A modern, BSD-licensed clone of the backtrace facility found in GNU libc. This library is primarily intended for porting Linux code to BSD platforms and other systems that don't have built-in backtrace support.
- Full GNU libc compatibility: Drop-in replacement for GNU libc's backtrace API
- Modern C11 implementation: Enhanced security and memory safety features
- Cross-platform support: Linux, BSD, macOS, and other POSIX systems
- Performance optimized: Fast backtrace capture with minimal overhead
- Comprehensive testing: Extensive test suite with performance benchmarks
- Easy integration: pkg-config support and build system integration
- Python-generated code: Configurable stack depth with code generation
- Production ready: Memory safe with proper error handling
# Install from AUR
yay -S libexecinfo
# Or using paru
paru -S libexecinfo
# Clone repository
git clone https://github.com/fam007e/libexecinfo.git
cd libexecinfo
# Generate source files (configurable stack depth)
python gen.py --max-depth 128 --output stacktraverse.c
# Build
make all
# Test
make test
# Install
sudo make install PREFIX=/usr
- C Compiler: GCC 7+ or Clang 6+
- Python: 3.6+ (for code generation)
- Make: GNU Make
- Development tools: Standard POSIX utilities
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
void print_backtrace() {
void *buffer[64];
char **strings;
int size, i;
size = backtrace(buffer, 64);
strings = backtrace_symbols(buffer, size);
printf("Backtrace (%d frames):\n", size);
for (i = 0; i < size; i++) {
printf(" [%d] %s\n", i, strings[i]);
}
free(strings);
}
void function_c() { print_backtrace(); }
void function_b() { function_c(); }
void function_a() { function_b(); }
int main() {
function_a();
return 0;
}
# Basic compilation
gcc -o myprogram myprogram.c -lexecinfo
# With symbol information (recommended)
gcc -Wl,--export-dynamic -o myprogram myprogram.c -lexecinfo
# Using pkg-config
gcc -o myprogram myprogram.c $(pkg-config --cflags --libs libexecinfo)
#include <execinfo.h>
#include <unistd.h>
#include <signal.h>
// Signal handler for crash reports
void crash_handler(int sig) {
void *buffer[128];
int size;
size = backtrace(buffer, 128);
// Write directly to stderr (safe in signal handlers)
write(STDERR_FILENO, "Crashed! Backtrace:\n", 20);
backtrace_symbols_fd(buffer, size, STDERR_FILENO);
exit(1);
}
int main() {
signal(SIGSEGV, crash_handler);
signal(SIGABRT, crash_handler);
// Your program code here
return 0;
}
find_package(PkgConfig REQUIRED)
pkg_check_modules(EXECINFO REQUIRED libexecinfo)
add_executable(myapp main.c)
target_link_libraries(myapp ${EXECINFO_LIBRARIES})
target_include_directories(myapp PRIVATE ${EXECINFO_INCLUDE_DIRS})
execinfo_dep = dependency('libexecinfo')
executable('myapp', 'main.c', dependencies: execinfo_dep)
PKG_CHECK_MODULES([EXECINFO], [libexecinfo])
AC_SUBST([EXECINFO_CFLAGS])
AC_SUBST([EXECINFO_LIBS])
The library includes a comprehensive test suite:
# Run all tests
make test
# Run specific test categories
./test
# Performance testing
make test DEBUG=0 # Optimized build for benchmarks
Test coverage includes:
- Basic functionality verification
- Edge cases and error conditions
- Memory safety validation
- Performance benchmarks
- Cross-platform compatibility
# Debug build with sanitizers
make DEBUG=1 clean all
# Release build with optimizations
make DEBUG=0 clean all
# Custom stack depth (default: 128)
python gen.py --max-depth 256 --output stacktraverse.c
make clean all
CC
- C compiler (default: cc)CFLAGS
- Additional compiler flagsPREFIX
- Installation prefix (default: /usr/local)DEBUG
- Enable debug build (0/1)PYTHON
- Python interpreter (default: python3)
Capture return addresses from the current call stack.
Parameters:
buffer
- Array to store return addressessize
- Maximum number of addresses to capture
Returns: Number of addresses actually captured
Convert return addresses to symbolic information.
Parameters:
buffer
- Array of return addresses frombacktrace()
size
- Number of addresses in buffer
Returns: Array of strings with symbol information (must be freed)
Write symbolic backtrace directly to file descriptor.
Parameters:
buffer
- Array of return addresses frombacktrace()
size
- Number of addresses in bufferfd
- File descriptor to write to
EXECINFO_MAX_FRAMES
- Maximum supported stack depth (128)PRINT_BACKTRACE()
- Convenience macro to print backtrace to stderrEXECINFO_VERSION_*
- Version information macros
# Compile with export-dynamic flag
gcc -Wl,--export-dynamic -o myprogram myprogram.c -lexecinfo
# Make sure development packages are installed
sudo pacman -S base-devel
# Check pkg-config setup
pkg-config --exists libexecinfo && echo "OK" || echo "Missing"
# Enable debug build
make DEBUG=1 clean all
./test
backtrace()
is relatively fast (~1-10μs per call)backtrace_symbols()
is slower due to symbol resolution (~1-100ms)- Use
backtrace_symbols_fd()
in signal handlers (no memory allocation) - Consider caching results for frequently called code paths
Contributions are welcome! Please see our Contributing Guidelines for details.
git clone https://github.com/fam007e/libexecinfo.git
cd libexecinfo
# Set up development environment
make clean
python gen.py --max-depth 128 --output stacktraverse.c
make DEBUG=1 all test
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Make your changes with tests
- Ensure all tests pass (
make test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the BSD 2-Clause License - see the LICENSE file for details.
- Maxim Sobolev - Original author of libexecinfo
- GNU libc maintainers - For the original backtrace API design
- Arch Linux community - For packaging support and feedback
- GitHub Issues: https://github.com/fam007e/libexecinfo/issues
- Email: faisalmoshiur@gmail.com
- AUR Package: libexecinfo
- GNU libc backtrace - Original implementation
- libunwind - Alternative stack unwinding library
- backward-cpp - C++ backtrace library
Made with ❤️ for the open source community