TCL stack trace not showing desired error line number - tcl

The -errorline element of the return options dictionary for the following TCL script is "2":
puts [info patchlevel]
try {
error "this is an error"
} trap {} {result ropts} {
puts $result
puts $ropts
}
How do I get the stacktrace to display the line number in the source file where the error was actually raised (ie. line 4 instead of 2) ?
Example screenshot:

Tcl often has that information available, but doesn't use it.
It has the information available because you have a chance to retrieve it with info frame and getbytecode (which is in the tcl::unsupported namespace, mostly because we reserve the right to change how the bytecodes themselves work at any time). I'm not quite sure if that would work in your specific case, but if you put your test code in a procedure then it definitely would. (There are complexities here with fragility that I don't fully understand.)
It doesn't use it because, for backward-compatibility with existing tooling, it uses the line numbers it was using prior to the creation of the machinery to support info frame. Those line numbers are relative to the local script fragment (which is whatever reports the line number in the error info trace first); in this case, that is the body of the try.
I don't like that it works like that at all. However, changing things is a bit tricky because we'd need to also figure out what else to report and what to do in the cases where the information genuinely isn't available (such as for automatically-generated code where things are assembled from many strings from many lines).

Related

How do i know when a function body ends in assembly

I want to know when a function body end in assemby, for example in c you have this brakets {} that tell you when the function body start and when it ends but how do i know this in assembly?
Is there a parser that can extract me all the functions from assembly and start line and endline of their body?
There's no foolproof way, and there might not even be a well-defined correct answer in hand-written asm.
Usually (e.g. in compiler-generated code) you know a function ends when you see the next global symbol, like objdump does to decide when to print a new "banner". But without all function-start symbols being visible, there's no unambigious way. That's why some object file formats have room for size metadata associated with a symbol. Like .size foo, . - foo in GAS syntax.
It's not as easy as looking for a ret; some functions end with a jmp tail-call to another function. And some call a noreturn function like abort or __stack_chk_fail (not tailcall because they want to push a return address for a backtrace.) Or just fall off into whatever's next because that path had undefined behaviour in the source so the compiler assumed it wasn't reachable and stopped generating instructions for it, e.g. a C++ non-void function where execution can/does fall off the end without a return.
In general, assembly can blur the lines of what a function is.
Asm has features you can use to implement the high-level concept of a function, but you're not restricted to that.
e.g. multiple asm functions could all return by jumping to a common block of code that pops some registers before a ret. Is that shared tail a separate function that's called with a tail-called with a special calling convention?
Compilers don't usually do that, but humans could.
As for function entry points, usually some other code somewhere in the program will contain a call to it. But not necessarily; it might only be reachable via a table of function pointers, and you don't know that a block of .rodata holds function pointers until you find some code loading from it and calling or jumping.
But that doesn't work if the lowest-address instruction of the function isn't its entry point. See Does a function with instructions before the entry-point label cause problems for anything (linking)? for an example
Compilers don't generate code like that, but humans can. (It's a handy trick sometimes for https://codegolf.stackexchange.com/ questions.)
Or in the general case, a function might have multiple entry points. Or you could describe that as multiple functions with overlapping implementations. Sometimes it's as simple as one tailcalling another by falling into it without needing a jmp, i.e. it starts a few instructions before another.
I wan't to know when a function body ends in assembly, [...]
There are mainly four ways that the execution of a stream of (userspace) instructions can "end":
An unconditional jump like jmp or a conditional one like Jcc (je,jnz,jg ...)
A ret instruction (meaning the end of a subroutine) which probably comes closest to the intent of your question (including the ExitProcess "ret" command)
The call of another "function"
An exception. Not a C style exception, but rather an exception like "Invalid instruction" or "Division by 0" which terminates the user space program
[...] for example in c you have this brakets {} that tell you when the function body start and when it ends but how do i know this in assembly?
Simple answer: you don't. On the machine level every address can (theoretically) be an entry point to a "function". So there is no unique entry point to a "function" other than defined - and you can define anything.
On a tangent, this relates to self-modifying code and viruses, but it must not. The exit/end is as described in the first part above.
Is there a parser that can extract me all the functions from assembly and
start line and endline of their body?
Disassemblers create some kind of "functions" with entry and exit points. But they are merely assumed. No way to know if that assumption is correct. This may cause problems.
The usual approach is using a disassembler and the work to recombinate the stream of instructions to different "functions" remains to the person that mandated this task (vulgo: you). Some tools exist that claim to simplify this, but I cannot judge their efficacy.
From the perspective of a high level language, there are decompilers that try to reverse the transformation from (for example) C to assembly/machine code that try to automatize that task and will work more or less or in some cases.

How do I debug lua functions called from conky?

I'm trying to add some lua functionality to my existing conky setup so that repetitive "code" in my conky text can be cleaned up. For example, I have information for each mounted FS, each core, etc. where each row displayed in my panel differs ONLY by one parameter.
My first skeletal, attempt at using lua functions for this seems to run but displays nothing in my panel. I've only found very simple examples to base this on, so I may have made a simple error, but I don't even know how to diagnose it. My code here is modeled after what I HAVE been able to find regarding writing functions, such as this How to implement a basic Lua function in Conky? , but that's about all the depth I've found on the topic except for drawing and cairo examples.
Here's the code added to my conky config, as well as the contents of my functions.lua file
conky.config = {
...
lua_load = '/home/conky-manager/MyConky/functions.lua',
};
conky.text = [[
...
${voffset 5}${lua conky_test 'test'}
...
]]
file - functions.lua
function conky_test(parm1)
return 'result text'
end
What I would expect is to see is "result text" displayed in my panel at the location where that function call appears, but nothing shows.
Is there a log created by conky as it runs, or a way to provide some debug output? Even if I'd made a simple error here, I'd still like to have the ability to diagnose things as my code gets more complex.
Success!
After cobbling info from several articles together, I figured out my basic flaws -
1. Missing a 'conky_main' function,
2. Missing a 'lua_draw_hook_post' to invoke it, and
3. Realizing that if I invoke conky from a terminal, print statements in lua would appear there.
So, for anyone who sees this question and has the same issues, here's the corrected code.
conky.config = {
...
lua_load = '/home/conky-manager/MyConky/functions.lua',
lua_draw_hook_post = "main",
};
conky.text = [[
...
${lua conky_test 'test'}
...
]]
and the proper basics in my functions.lua file
function conky_test(parm1)
return 'result text'
end
function conky_main()
if conky_window == nil then
return
end
end
A few notes:
I still haven't determined if using 'lua_draw_hook_pre' instead of 'lua_draw_hook_post' makes any difference, but it doesn't seem to in this example.
Also, some examples showed actually calling this 'test' function instead of writing a 'main', but the 'main' seemed to have value in checking to see if conky_window existed.
Some examples seemed to state that naming functions with the prefix 'conky_' was required, but then showed examples of calling those functions without the prefix, so I assume the prefix is inferred during the call.
a major note: you should run conky from the directory containing the lua scripts.

How do I use a function from one lisp file to solve for something in another lisp file?

I'm new to lisp and my professor gave some .lisp files to play around with.
http://pastebin.com/eDPUmTa1 (search functions)
http://pastebin.com/xuxgeeaM (water jug problem saved as waterjug.lisp)
The problem is I don't know how to implement running functions from one file to solve problems from another. The most I've done is compiled functions from one file and played around with it in the terminal. I'm not sure how to load 2 files in this IDE as well as how I should run the function. I'm trying, for example, to run the breadth-first-search function to solve the problem to no avail.
I'm currently using emacs as the text editor SBCL as the common lisp implementation along with quicklisp and slime.
Assuming each file is in its own buffer, say f1.lisp and f2.lisp, then you only have to call slime-compile-and-load-file when you are in each buffer. This is bound by default to C-c C-k. You have to compile the first file first, because it contains definitions for the second one.
But, your second file (f2.lisp) has two problems: search for (break and (bread and remove those strings. Check if the forms around them have their parenthesis well balanced.
Take care of warning messages and errors while compiling your file.
Then, if you want to evaluate something directly from the buffer, put your cursor (the point) after the form you want to evaluate, and type C-x C-e (imagine the cursor is represented by % below):
(dump-5 (start-state *water-jug*))%
This will print the result in the minibuffer, in your case something like #<JUG-STATE {1004B61A63}>, which represents an instance of the JUG-STATE class. Keep a window open to the REPL buffer in case the functions write something to standard output (this is the case with the (describe ...) expression below).
If instead you do C-c I, this will ask you which expression you want to inspect, already filled with the form before the point. When you press enter, the inspector buffer will show up:
#<JUG-STATE {1004BD8F53}>
--------------------
Class: #<STANDARD-CLASS COMMON-LISP-USER::JUG-STATE>
--------------------
Group slots by inheritance [ ]
Sort slots alphabetically [X]
All Slots:
[ ] FIVE = 0
[ ] TWO = 2
[set value] [make unbound]
Read http://www.cliki.net/slime-howto.

Understanding the use of Tcl namespace variable

I have a namespace variable which is defined as below:
namespace eval ::SMB::{
variable SmbInfo
------
------
proc ::SMB::SmbCreate {name dutport} {
variable SmbInfo
global DutPorts DutPort_2 DutPorts_3 smb
------
------
if{"" != [info command SMB::$name]} {
return -code error "command name \"$name\" already exists"
}
set SmbInfo($name -DutPort) $dutport
I am new to Tcl and trying to understand the above piece of code. Few questions, please correct me if I am wrong at any point:
The variable SmbInfo defined on top in namespace is getting overridden by the one declared in the procedure SmbCreate. I am unable to figure out what is the objective of the line:
set SmbInfo($name -DutPort) $dutport
I can see that 'DutPorts' is defined as global but I could not find 'DutPort'. I have not executed the code yet. Could it be an error?
Is ($name - DutPort) creating an array index for the variable SmbInfo and the value of $dutport is being set to that particular array variable?
I have similar code structures in the file like below
set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)]
Where BuildMac1 is a procedure. A bit explanation of the above code might also make the thing clear.
If anything I missed to post in the question, kindly point me, I will edit my question.
Thanks in advance.
The second declaration doesn't override, it's the same variable in both cases.
The command is a syntax error because of the space after $name. The intent seems to be to assign the value of $dutport to the member of SmbInfo that has the name "$name -DutPort" (where $name is replaced by the variable value).
A similar assignment, but here the value comes from the result of the command.
There are a few syntax errors in the code, too many or too few spaces here and there. It seems unlikely this code has ever been executed.
The purpose of the smb::SmbCreate command would seem to be to 1) create a new command in the SMB namespace named by the first parameter (unless such a command already exists) and 2) store metadata in the SmbInfo namespace variable, indexed by a) the name parameter and b) a keyword such as -DutPort or -SmbSetDmac.
Code like this essentially implements an ad-hoc object-oriented interface. If the whitespace issues are resolved, it should work fine.
You have many syntactic problems that are going to cause you much grief. Tcl cares very much about its syntax level, which includes exactly where the spaces and newlines are, and whether there are {braces} and [brackets] as expected. You must get these things right.
Looking at the specific code you're having problems with, this line:
set SmbInfo($name -DutPort) $dutport
would appear to be highly unlikely, as it is passing three arguments to the set command when that only takes one or two. I'd guess that you've got a command that you're calling to obtain a key for an array, and that the code therefore ought to be this:
set SmbInfo([$name -DutPort]) $dutport
See those [brackets]? They matter here, as they say “run my contents as a little subscript and use the result”. With that sorted out, there's also the question of whether $name -DutPort works at all, but you'll just have to be guided by the error messages there. Tcl usually gives very good error messages, though sometimes you have to think about why the code got in the state where it is giving that message in order to figure out what the actual problem is. You know, usual debugging…
I would expect similar problems with:
set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)]
and would guess that it is actually supposed to be:
set SmbInfo([$name -SmbSetDmac]) [BuildMac1 $SmbInfo([$from_name -DutPort])]
Note again that I have modified the spaces to follow the existing pattern (which I'm guessing is a property access; it looks like it's OTcl or XOTcl) and added brackets.
Finally, this line:
if{"" != [info command SMB::$name]} {
is also syntactically wrong, and should instead be:
if {"" != [info command SMB::$name]} {
That extra space matters, because it separates the word that is the command name (if) from the word that is the condition expression. The remainder of the line is probably correct (the SMB::$name might be suspicious, except you're using it in info command, but then you probably only need info command $name as it already knows about what namespace you're working in and you're using the unqualified name elsewhere).

Catch Mathematica warnings/errors without displaying them

I have a problem involving NDSolve in Mathematica, which I run multiple times with different values of the parameters. For some of these values, the solution results in singularities and NDSolve warns with NDSolve::ndsz or other related warnings.
I would simply like to catch these warnings, suppress their display, and just keep track of the fact that a problem occurred for these particular values of the parameters. I thought of the following options (neither of which really do the trick):
I know I can determine whether a command has resulted in a warning or error by using Check. However, that will still display the warning. If I turn it off with Off the Check fails to report the warning too.
It is possible to stop NDSolve using the EventLocator method, so I could check for very large values of the function or its derivatives and stop evaluation in that case. However, in practice, this still produces warnings from time to time, presumably because the step size can sometimes be so large that the NDSolve warning triggers before my Event has taken place.
Any other suggestions?
If you wrap the Check with Quiet then I believe that everything should work as you want. For example, you can suppress the specific message Power::indet
In[1]:= Quiet[Check[0^0,err,Power::indet],Power::indet]
Out[1]= err
but other messages are still displayed
In[2]:= Quiet[Check[Sin[x,y],err,Power::indet],Power::indet]
During evaluation of In[2]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
Out[2]= Sin[x,y]
Using Quiet and Check together works:
Quiet[Check[Table[1/Sin[x], {x, 0, \[Pi], \[Pi]}], $Failed]]
Perhaps you wish to redirect messages? This is copied almost verbatim from that page.
stream = OpenWrite["msgtemp.txt"];
$Messages = {stream};
1/0
FilePrint["msgtemp.txt"]