Stack traces, backtraces, call stacks explained in JavaScript, Python, PHP

People are rarely happy to see a stack trace. A stack trace often appears when software encounters an exception, an unexpected error which can't be handled gracefully and therefore most stop execution of the program. What the stack trace shows is what was happening in the moments leading up to the bug. The stack is called a stack because each item (each function call) is stacked on top of the previous one in a special part of computer memory called the stack. Most computers and programming languages work with a stack. In programs written in programming languages without side effects, a feature of functional programming, it's possible to know exactly what was going on in the program just by looking at the stack trace of function calls with arguments.

JavaScript

Developers have good debugging support for JavaScript built in to browsers like Chrome (DevTools) or Firefox (Firebug). It's not unusual to open the DevTools pane on a website and see some uncaught Javascript exception error messages. Simply clicking them will show you the call stack. You can also open the 'Sources' tab of DevTools, select a .js file, and select any line making it easy to see the call stack (same as a stack trace but always available and inspectable whereas a stack "trace" implies we're debugging an exception) at that breakpoint in your JS code. When execution reaches that point you can not only see the call stack but also the value of all variables currently in scope.

Or you can print the call stack at any time by using the JS Console api: console.trace();

Trace
    at bar (repl:1:46)
    at repl:1:86
    at Array.map (native)
    at repl:1:75
    at REPLServer.defaultEval (repl.js:252:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:417:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)

Python

In Python, any unhandled exception will print a "stack traceback", another term for a stack trace. If you want to print one manually (without raising an exception which would also thereby stopping execution of your program) you can use the traceback module e.g. traceback.print_stack(). To get a traceback object (when not currently handling an exception in which case you can use sys.last_traceback) use tb = traceback.extract_stack().

PHP

In PHP we can get the current call stack as a "backtrace" array by calling debug_backtrace() in our code. The array is of numerically indexd call frame associative arrays, each call frame including line number and filename, function name, and passed in arguments. We can print it out using var_dump(debug_backtrace()) or also simply debug_print_backtrace as of PHP 5.

Bash script

So it turns out Bash does have a builtin "stack trace". It's called caller and it takes an integer argument of the frame number (caller 0 prints the immediate scope's caller, caller 1 calls this caller's caller, and so on).

Got a stack trace dump, now what?

So what can you do with a stack trace? Unless you are running inside a code debugger and have a breakpoint set, the appearance of a stack trace probably means your program is finished and all you can do is look at the debugging output to figure out what went wrong. If you aren't the developer, then you should show it to the developer who should be able to understand it and fix the bug (eventually).

If you are responsible for debugging the error, then you can look at the state of variables at every level of the call stack. Most likely, a variable was set to a wrong value at some point.

Add new comment