Skip to content
mhahnFr edited this page Feb 20, 2024 · 25 revisions

Here you can find all information about the CallstackLibrary as well as the documentation of the source code.

The features

This library can translate backtraces obtained by the function backtrace into a human-readable format. It will use the debug symbols of the application, in case they are not available, the information obtained by the dynamic linker is used.
Additional C++ functionality and optimizations can be enabled while compiling the library.

There is also a wrapper class for simplified usage of this library in C++ code.

Additionally, there is an exception class capable of printing its construction stacktrace.

How to use

Example:

#include <stdio.h> // For printf(...)

#include <callstack.h>

int main() {
    struct callstack* callstack = callstack_new();
    struct callstack_frame* frames = callstack_toArray(callstack);
    
    printf("The current callstack:\n");
    for (size_t i = 0; i < callstack_getFrameCount(callstack); ++i) {
        printf("In: (%s) %s (%s:%ld)\n", callstack_frame_getShortestName(&frames[i]), 
                                         frames[i].function,
                                         callstack_getShortestSourceFileName(&frames[i]),
                                         frames[i].sourceLine);
    }
    
    callstack_delete(callstack);
}

C++ support

With the C++ wrapper class the lifecycle management of callstack objects is simplified.
To use it, you need to do nothing - it is automatically included if you compile your code with a C++ compiler.

The move semantic is also supported by the wrapper if compiled using a compiler supporting C++11.

In order to get demangled C++ function names, the library needs to be compiled with the C++ exclusive functions enabled, see below.

Example:

#include <iostream>

#include <callstack.h>

int main() {
    lcs::callstack callstack;
    callstack_frame* frames = callstack_toArray(callstack);
    
    std::cout << "The current callstack:" << std::endl;
    for (size_t i = 0; i < callstack_getFrameCount(callstack); ++i) {
        std::cout << "In: (" << callstack_frame_getShortestName(&frames[i])
                  << ") "    << frames[i].function
                  << " ("    << callstack_frame_getShortestSourceFileName(&frames[i])
                  << ":"     << frames[i].sourceLine
                  << ")"     << std::endl;
    }
}

Enabling additional C++ exclusive functions

The C++ name demangler and a few other optional functions are disabled by default. To enable them while compiling the library, pass CXX_FUNCTIONS=true to make:

make CXX_FUNCTIONS=true

The C++ optimizations can be enabled by passing CXX_OPTIMIZED=true the same way:

make CXX_OPTIMIZED=true

The two flags can be combined:

make CXX_FUNCTIONS=true CXX_OPTIMIZED=true

When linking statically against the CallstackLibrary with C++ functions and / or optimizations enabled the application additionally needs to be linked against the C++ standard library of your compiler (this is usually already the case when linking C++ code).

Clone this wiki locally