This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
LBPHacker's profile picture

Error Tracer

Started by LBPHacker, 31 August 2013 - 02:11 PM
LBPHacker #1
Posted 31 August 2013 - 04:11 PM
Hey everybody, LBPHacker here. Yesterday I started writing a program (called trace) - as you can guess, a program which you can use to trace errors. For those who are not familiar with error tracing (or just can understand what I mean by "error tracing" due to my poor English), let's just see an example:
local function a()
	x() -- attempt to call nil
end

local function b()
	a()
end


local function c()
	a()
end

local what = read()
(what == "b" and b or c)()
We'll get an error message, namely "program:2: attempt to call nil". The only problem is, we can't know for sure if a was called by b or c. Now this example isn't too complex, and with a little bit of thinking we could figure that out, but think about programs which have 200 or more lines with a ton of functions which cross-call each other - then the lack of knowing which of them called which is a pain when we're debugging the program. In any other programming language (and even in Lua) we call for help, and we get the "call stack", which tells us which function called which one and where did that exactly happen.

We don't have that in CC Lua. I'm not sure why (security leaks?). Anyways, this program is kind of capable of recording function calls (even local functions), and it really builds up a stack which then can be displayed using a for loop.

Spoiler

To make it work you have to type this into the shell:
trace <program> [arg1, ..., argN]

Keep in mind that this program is still work in progress, it sure does contain bugs I'm not aware of.

A bunch o' thanks goes to Engineer for being there on Skype and nudging me around so I was able to build up enough self-confidence to start writing this mess.

Every time I used this program it worked perfectly, though that doesn't mean more than five or six times (debugging doesn't count). Feel free to test it with the most complex programs you can think about. As things are now, trace can actually make a perfectly working program fail, since it basically rewrites the program in a way you wouldn't even think (yeah, it removes all local keywords), and supplies a virtual environment for every function declared in the program.

As closing words, pastebin get ZbcKjGDy trace

So that's it. Hope you like it. Suggestions are welcome.

Update log:
SpoilerUPDATE #3 (01.09.13)
  • Rethought the way trace detects external API calls - finally (term == term) evaluates true.
UPDATE #2 (01.09.13)
  • Fixed a bug with some error messages pointing to trace while it was working perfectly. Eg. this code:
    print(string.sub(false, 1, 2))
    Here string.sub raises a level two error which usually points to the program which called it. Under trace, calls to external functions happens elsewhere (actually in trace itself), not in the program. And so does the level two error point to trace. Now that I can detect that, I can redirect the error to the program.
UPDATE #1 (01.09.13)
  • Fixed a bug which caused values the program under observation set to false (or anything that'd evaluate false in an IF statement) end up being a table (namely the virtual _nil table in trace)
  • Added Options argument. You can use trace the way you always used it, but if you supply a sequece of characters beginning with a colon as the first argument, that argument is treated as the Options argument. The characters following the colon are the actual switches. Eg.
    trace :l myprogram 42
    That will set switch L, and trace will run myprogram and supplies a parameter, namely 42. The switches are not case-sensitive, :l is the same as :L. Available switches:
    • L: Log errors to trace.log
  • Note that multiple switches are set in the same parameter (the first beginning with a colon), so setting both switch L and switch S (which does nothing at the moment - it's just an example) would look like this:
    trace :ls myprogram 42
svdragster #2
Posted 01 September 2013 - 03:33 AM
Really nice job!
Can you also write the result into a file? I forget way too fast :P/>
LBPHacker #3
Posted 01 September 2013 - 03:58 AM
Really nice job!
Can you also write the result into a file? I forget way too fast :P/>
Sure I can. trace.log, for example. By the way, fixing bugs even now… But I'm progressing… Updated pastebin. Same ID, new code (and now bugs…)