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

Stack trace for CC

Started by LBPHacker, 10 September 2015 - 04:32 PM
LBPHacker #1
Posted 10 September 2015 - 06:32 PM
Hey everyone, LBPHacker here (after a long break).

This is an idea that came up a few years ago when I realised we can't use the debug API in ComputerCraft (I was planning to use it for stack traces, something that's very useful when you're working on big projects). Fortunately that's not the case with xpcall, the heart of this utility program. It does what its name suggests; does a stack trace.

> trace -h
Usage: trace [switches...] <program> [args...]
Switches:
  -h         show this message
  -l<FILE>   log trace to <FILE> (append mode)
  -f         show full trace (including bios.lua)
  -m<MAX>    set max trace depth to <MAX>
                (there's no maximum by default)
  -b         break trace into separate lines
> cat deadbeef
local function b()
    c() -- which is nil
end

local function a()
    b()
end

a()
> trace deadbeef
deadbeef:2: attempt to call nil
  stack trace: deadbeef:2 deadbeef:6 deadbeef:9

pastebin get zZkvWW4c trace

(Wow, this turned out to be an awfully short post)
Edited on 10 September 2015 - 04:42 PM
Wojbie #2
Posted 10 September 2015 - 08:33 PM
This is awfully short post for what is probably smallest useful debugging tool on this forums!!
I am soo gonna test this one when i am debugging my old code.
Thanks for this great contribution to betterment of CC! :D/>
ElvishJerricco #3
Posted 11 September 2015 - 07:26 AM
Hm. Didn't realize we had access to xpcall. I just always assumed it was disabled. Glad I'm wrong. Wonderful utility!
Creator #4
Posted 07 November 2015 - 10:29 PM
Have searched it all over the internet without getting a satisfying answer. Pcall vs Xpcall ?
Bomb Bloke #5
Posted 07 November 2015 - 10:42 PM
Best I can make out:

local ok, result = pcall( func, arg1, arg2, etc )
if not ok then handleError(result) end

… is about the same as:

xpcall( function() func( arg1, arg2, etc ) end, handleError )

… the difference being that when xpcall resolves, you're still at the function stack position where the error occurred (whereas by the time pcall has returned, you've returned to the position where the original call was made and so it's too late to tell where the error might've happened). Normally you'd use the debug library to get trace information at that point.
Creator #6
Posted 07 November 2015 - 10:57 PM
I see, thanks.
ElvishJerricco #7
Posted 08 November 2015 - 11:40 AM
The application being that when xpcall calls your handler, you can use antics with the error function and error levels to generate a stack trace. As Bomb Bloke said, you usually have the debug library to do this cleanly, but we don't have that so we have to cheat.