Expand description
§CallTrace - High-Performance Function Call Tracing Library
CallTrace is a Rust library that provides comprehensive function call tracing capabilities
using GCC’s -finstrument-functions feature. It captures function calls, arguments, return values,
and call relationships across multiple threads with minimal performance overhead.
§Features
- Zero-overhead when disabled: Atomic fast-path checking
- Thread-safe: Full support for multi-threaded applications
- Argument capture: DWARF-based type-aware argument extraction
- Return value tracing: RAX/XMM0 register capture
- Crash analysis: Comprehensive crash reporting with stack traces
- JSON output: Structured, hierarchical call tree export
- Symbol resolution: Function name resolution with C++ demangling
- Memory safe: 100% Rust implementation with zero memory leaks
§Quick Start
§1. Compile your C/C++ program with instrumentation
gcc -rdynamic -finstrument-functions -g your_program.c -o your_programRequired flags:
-rdynamic: Export symbols for dladdr() resolution-finstrument-functions: Enable GCC instrumentation hooks-g: Provide DWARF debug information for argument capture
§2. Run with CallTrace
# Basic tracing
CALLTRACE_OUTPUT=trace.json LD_PRELOAD=./libcalltrace.so ./your_program
# With argument capture (higher overhead)
CALLTRACE_CAPTURE_ARGS=1 CALLTRACE_OUTPUT=trace.json LD_PRELOAD=./libcalltrace.so ./your_program
# With debug output
CALLTRACE_DEBUG=1 CALLTRACE_OUTPUT=trace.json LD_PRELOAD=./libcalltrace.so ./your_program§3. Analyze the results
The generated JSON file contains a hierarchical view of all function calls:
{
"metadata": {
"version": "1.0.0",
"timestamp": "2024-01-15T10:30:00Z",
"total_calls": 1250,
"threads": 4
},
"call_trees": {
"12345": {
"thread_id": 12345,
"calls": [
{
"function": "main",
"address": "0x401020",
"start_time": "10:30:00.123456",
"end_time": "10:30:00.987654",
"arguments": [...],
"children": [...]
}
]
}
}
}§Environment Variables
| Variable | Default | Description |
|---|---|---|
CALLTRACE_OUTPUT | {executable}.json | Output file path |
CALLTRACE_CAPTURE_ARGS | false | Enable argument capture |
CALLTRACE_MAX_DEPTH | 100 | Maximum call depth |
CALLTRACE_DEBUG | false | Enable debug output |
CALLTRACE_PRETTY_JSON | true | Pretty-print JSON |
§Performance
CallTrace is designed for production use with minimal overhead:
- Function calls: ~50-100ns overhead per call (argument capture disabled)
- Memory usage: ~2MB for 10,000 function calls
- Thread safety: Zero data races, lock-free where possible
- Atomic fast-path: <5ns when tracing is disabled
§Architecture
CallTrace uses a modular architecture:
cyg_profile: GCC instrumentation hooks entry pointscall_tree: Thread-safe call tree managementdwarf_analyzer: DWARF debug information parsingregister_reader: x86_64 register and argument capturejson_output: Structured JSON serializationcrash_handler: Signal handling and crash analysisbuild_validator: Compilation requirement validation
§Safety and Reliability
- Memory safe: No manual memory management, RAII throughout
- Thread safe: DashMap and
Arc<RwLock<T>>for concurrent access - Signal safe: Proper signal handler chaining and restoration
- Crash resilient: Comprehensive crash analysis and recovery
- Production tested: Extensive integration and stress testing
§Platform Support
- Architecture: x86_64
- Operating System: Linux (with glibc)
- Compiler: GCC with
-finstrument-functionssupport - Rust: 2021 edition, stable channel
§Example Integration
// your_program.c
#include <stdio.h>
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
int main() {
printf("fib(8) = %d\n", fibonacci(8));
return 0;
}Compile and trace:
gcc -rdynamic -finstrument-functions -g your_program.c -o your_program
CALLTRACE_OUTPUT=fib_trace.json LD_PRELOAD=./libcalltrace.so ./your_programThis will generate a complete call tree showing the recursive fibonacci calls, timing information, and call relationships.
§C API Functions
The library exports C-compatible functions for manual control:
calltrace_init(): Initialize tracing (called automatically)calltrace_cleanup(): Cleanup and write output (called automatically)
§Internal Implementation Notes
For developers contributing to CallTrace:
- Uses
ctor/dtorattributes for automatic initialization - Thread-local storage for performance counters and buffers
- LRU caching for DWARF function information
- String interning for common type/function names
- Atomic operations for statistics and fast-path checks
Re-exports§
pub use cyg_profile::__cyg_profile_func_enter;pub use cyg_profile::__cyg_profile_func_exit;
Modules§
- build_
validator - Build Validation Module
- call_
tree - Thread-Safe Call Tree Management
- crash_
handler - Crash Handler Module
- cyg_
profile - GCC Instrumentation Profile Hooks
- dwarf_
analyzer - DWARF Debug Information Analysis
- error
- Error handling for CallTrace library
- json_
output - JSON Output Generation
- register_
reader - x86_64 Register Reading for Function Argument Capture
Structs§
- Call
Trace Config - CallTrace runtime configuration
Functions§
- calltrace_
cleanup - Cleanup the CallTrace library and write final output
- calltrace_
init - Initialize the CallTrace library