Skip to main content
The Function Trace Generator agent creates detailed function-level execution traces for C/C++ programs using compiler instrumentation. These traces are essential for crash analysis and understanding program behavior.

Purpose

Generate function-level execution traces that show:
  • Function entry and exit events
  • Call stack depth
  • Execution timeline
  • Thread-level information

Invocation

Invoked by the crash-analysis-agent as part of the crash analysis workflow. Receives:
  • Code repository path
  • Working directory path
  • Crashing example program and build instructions
Creates: traces/ subdirectory in working directory

Workflow

1

Build Instrumentation Library

2

Rebuild Target with Instrumentation

Add instrumentation flags to the build:
  • Add -finstrument-functions -g to CFLAGS
  • Add -L<path-to-libtrace> -ltrace -ldl -lpthread to LDFLAGS
Autotools:
CMake:
Makefile:
3

Run Crashing Program

4

Convert to Perfetto Format (Optional)

5

Move Trace Files

Copy all trace files to the traces/ subdirectory in working directory

Instrumentation Details

The -finstrument-functions flag causes the compiler to insert calls to:
These are implemented by libtrace.so to log:
  • Function address
  • Timestamp (nanosecond precision)
  • Thread ID
  • Entry/exit event type

Trace File Format

Raw trace files (trace_<tid>.log) contain:
  • [N]: Event sequence number
  • [timestamp]: Nanoseconds since start
  • Dots: Call depth visualization
  • [ENTRY/EXIT]: Event type
  • Function name: Resolved from debug symbols

Perfetto Format

The Perfetto JSON format enables visualization at ui.perfetto.dev:

Validation

After generating traces, validate: Example validation:

Usage in Crash Analysis

The crash-analyzer-agent uses function traces to:
  1. Verify execution path: Confirm hypothesized functions were actually called
  2. Track control flow: Follow execution from entry to crash
  3. Identify missing functions: Detect functions that should have been called but weren’t
  4. Correlate with coverage: Cross-reference with gcov data

Performance Impact

Function instrumentation adds significant overhead:
  • 10-100x slowdown typical
  • Large trace files (MB-GB for complex programs)
  • Memory overhead for buffering
Recommendations:
  • Use only for crash reproduction, not production
  • Limit trace duration to necessary execution
  • Consider filtering high-frequency functions if needed

Troubleshooting

  • Check LD_LIBRARY_PATH includes libtrace.so directory
  • Verify program actually executed (didn’t fail immediately)
  • Check write permissions in current directory
  • Program may have crashed before trace buffer flushed
  • Increase buffer size in trace_instrument.c
  • Add explicit flush before crash-prone code
  • Missing debug symbols (-g flag)
  • Stripped binary
  • Use addr2line or nm to resolve manually
  • Filter out high-frequency functions
  • Limit tracing to specific code sections
  • Use sampling instead of full instrumentation

Output Structure

Crash Analysis

Main crash analysis orchestrator

Coverage Analyzer

Complementary coverage data generation