libdragon
Files | Data Structures | Functions
Backtrace (call stack) support

Implementation of functions to walk the stack and dump a backtrace. More...

Files

file  backtrace.c
 Backtrace (call stack) support.
 
file  backtrace.h
 Backtrace (call stack) support.
 

Data Structures

struct  backtrace_frame_t
 A stack frame, part of a backtrace. More...
 

Functions

void backtrace_frame_print (backtrace_frame_t *frame, FILE *out)
 Print a single frame of a backtrace. More...
 
void backtrace_frame_print_compact (backtrace_frame_t *frame, FILE *out, int width)
 Print a single frame of a backtrace, in a compact format. More...
 
int backtrace (void **buffer, int size)
 Walk the stack and return the current call stack. More...
 
char ** backtrace_symbols (void **buffer, int size)
 Translate the buffer returned by backtrace into a list of strings. More...
 
bool backtrace_symbols_cb (void **buffer, int size, uint32_t flags, void(*cb)(void *, backtrace_frame_t *), void *cb_arg)
 Symbolize the buffer returned by backtrace, calling a callback for each frame. More...
 

Detailed Description

Implementation of functions to walk the stack and dump a backtrace.

This module implements two POSIX/GNU standard functions to help walking the stack and providing the current execution context: backtrace() and backtrace_symbols().

The functions have an API fully compatible with the standard ones. The implementation is however optimized for the MIPS/N64 case, and with standard compilation settings. See the documentation in backtrace.c for implementation details.

You can call the functions to inspect the current call stack. For a higher level function that just prints the current call stack on the debug channels, see debug_backtrace.


Data Structure Documentation

◆ backtrace_frame_t

struct backtrace_frame_t

A stack frame, part of a backtrace.

Data Fields
uint32_t addr PC address of the frame (MIPS virtual address)
const char * func Name of the function (this should always be present)
uint32_t func_offset Byte offset of the address within the function.
const char * source_file Name of the source file (if known, or "???" otherwise)
int source_line Line number in the source file (if known, or 0 otherwise)
bool is_inline True if this frame refers to an inlined function.

Function Documentation

◆ backtrace_frame_print()

void backtrace_frame_print ( backtrace_frame_t frame,
FILE *  out 
)

Print a single frame of a backtrace.

Print all the information about a single frame of a backtrace, with the following format:

<func>+<offset> (<source_file>:<source_line>) [<address>]

for instance:

debug_assert_func_f+0x9c (/home/user/src/libdragon/src/debug.c:537) [0x80010c5c]
void debug_assert_func_f(const char *file, int line, const char *func, const char *failedexpr, const char *msg,...)
Underlying implementation function for assert() and assertf.
Definition: debug.c:614
Parameters
outFile to print to
frameFrame to print

◆ backtrace_frame_print_compact()

void backtrace_frame_print_compact ( backtrace_frame_t frame,
FILE *  out,
int  width 
)

Print a single frame of a backtrace, in a compact format.

Print a frame of a backtrace in a compact format, with a limited width in number of characters. This is the format:

<func> (<source_file>:<source_line>)

but the source file will be truncated to fit the width, showing only its final part. For instance, if the width is 40 characters, the following frame:

debug_assert_func_f+0x9c (/home/user/src/libdragon/src/debug.c:537) [0x80010c5c]

will be printed as:

debug_assert_func_f (.../src/debug.c:537)
Parameters
outFile to print to
frameFrame to print
widthWidth in characters to fit the frame information to

◆ backtrace()

int backtrace ( void **  buffer,
int  size 
)

Walk the stack and return the current call stack.

This function will analyze the current execution context, walking the stack and returning informations on the active call frames.

This function adheres to POSIX specification. It does not allocate memory so it is safe to be called even in the context of low memory conditions or possibly corrupted heap.

If called within an interrupt or exception handler, the function is able to correctly walk backward the interrupt handler and show the context even before the exception was triggered.

Parameters
bufferEmpty array of pointers. This will be populated with pointers to the return addresses for each call frame.
sizeSize of the buffer, that is, maximum number of call frames that will be walked by the function.
Returns
Number of call frames walked (at most, size).

◆ backtrace_symbols()

char ** backtrace_symbols ( void **  buffer,
int  size 
)

Translate the buffer returned by backtrace into a list of strings.

This function symbolizes the buffer returned by backtrace, translating return addresses into function names and source code locations.

The user-readable strings are allocated on the heap and must be freed by the caller (via a single free() call). There is no need to free each of the returned strings: a single free() call is enough, as they are allocated in a single contiguous block.

This function adheres to POSIX specification.

This function also handles inlined functions. In general, inlined function do not have a real stack frame because they are expanded in place; so for instance a single stack frame (as returned by backtrace) can correspond to multiple symbolized stack frames, one per each inlined function. Since the POSIX API requires this function to return an array of the same size of the input array, all inlined functions are collapsed into a single string, separated by newlines.

Parameters
bufferArray of return addresses, populated by backtrace
sizeSize of the provided buffer, in number of pointers.
Returns
Array of strings, one for each call frame. The array must be freed by the caller with a single free() call.
See also
backtrace_symbols_cb

◆ backtrace_symbols_cb()

bool backtrace_symbols_cb ( void **  buffer,
int  size,
uint32_t  flags,
void(*)(void *, backtrace_frame_t *)  cb,
void *  cb_arg 
)

Symbolize the buffer returned by backtrace, calling a callback for each frame.

This function is similar to backtrace_symbols, but instead of formatting strings into a heap-allocated buffer, it invokes a callback for each symbolized stack frame. This allows to skip the memory allocation if not required, and also allows for custom processing / formatting of the backtrace by the caller.

The callback will receive an opaque argument (cb_arg) and a pointer to a stack frame descriptor (backtrace_frame_t). The descriptor and all its contents (including strings) is valid only for the duration of the call, so the callback must (deep-)copy any data it needs to keep.

The callback implementation might find useful to call backtrace_frame_print or backtrace_frame_print_compact to print the frame information.

Parameters
bufferArray of return addresses, populated by backtrace
sizeSize of the provided buffer, in number of pointers.
flagsFlags to control the symbolization process. Use 0.
cbCallback function to invoke for each symbolized frame
cb_argOpaque argument to pass to the callback function
Returns
True if the symbolization was successful, false otherwise. Notice that the function returns true even if some frames were not symbolized; false is only used when the function had to abort before even calling the callback once (eg: no symbol table was found).
See also
backtrace_symbols