Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Stack Trace

Tango offers a built-in ability to get stacktraces and visualize them.

This is performed in the tango.core.stacktrace.* modules.

Support is still in evolution, in general you need to at least compile with debug info (-g) to have the function names. See the platform dependent hints for more info.

Traced Exception

Stack traces can be useful to know where the exception originated and its context. You can activate stack tracing simply with

import tango.core.stacktrace.TraceExceptions;

Then if you print the exception with something like this

e.writeOut((char[] s) { Stdout(s); });
Stdout.flush();

you will see the stacktrace.

Function name

To find the name of a function pointer you can use one of

char[] nameOfFunctionAt(void* addr, char[] buf);
char[] nameOfFunctionAt(void * addr);

for delegates you can extract the address with .funcptr

Demangling

tango.core.stacktrace.Demangler has a demangler that can be used to demangle D names.

demangler.demangle(myMangledString);

one can even allocate new demangler with different verbosity levels, or modify the verbosity of the default demangler

System Dependent Hints

Windows

You need to compile without optimizations and with -g to get the stack traces. A dbginfo.dll is needed, but that should be part of windows

Macintosh

Stacktracing works also without -g, but the names are then missing and one should recover them later.

The symbol names are returned, but line numbers are missing.

Tracing might have problems with nested functions (that lead to nested stackframes that interrupt the stacktracing procedure).

Linux

Stacktracing works also without -g, but symbol names are not resolved.

Tracing might have problems with nested functions (that lead to nested stackframes that interrupt the stacktracing procedure).

The function names and addresses can be recovered with the addr2line utility. At the moment there is no easy to use D program to parse a stacktrace, call addr2line and return demangled function names and file/number, a contribution would be appreciated.

Improving stacktracing

The main functions used to get a stack trace are

/// builds a backtrace of addresses, the addresses are addresses of the *next* instruction, 
/// *return* addresses, the most likely the calling instruction is the one before them
/// (stack top excluded)
extern(C) size_t rt_addrBacktrace(TraceContext* context, TraceContext *contextOut,
     size_t*traceBuf,size_t bufLength,int *flags);

and

/// tries to sybolize a frame information, this should try to build the best
/// backtrace information, if possible finding the calling context, thus 
/// if fInfo.exactAddress is false the address might be changed to the one preceding it
/// returns true if it managed to at least find the function name
extern(C) bool rt_symbolizeFrameInfo(ref Exception.FrameInfo fInfo,
     TraceContext* context,char[]buf);

both functions can be changed with

extern(C) void rt_setAddrBacktraceFnc(AddrBacktraceFunc f);

and

extern(C) void rt_setSymbolizeFrameInfoFnc(SymbolizeFrameInfoFnc f);

Finally the printing format of a frame function can be changed setting Exception.FrameInfo.defaultFramePrintingFunction.

Improvements are welcome.