magic-trace Debug Info and Symbol Table Requirements: A Complete Guide

magic-trace requires an unstripped ELF symbol table (.symtab or .dynsym) and DWARF debug sections (.debug_line and .debug_info) to resolve function names and source locations; without these, traces display raw addresses as [unknown] and line-level selection fails.

Understanding the magic-trace debug info and symbol table requirements is essential for effective tracing with the janestreet/magic-trace tool. This OCaml-based utility analyzes ELF binaries to map sampled addresses back to human-readable function names and exact source file locations. The implementation relies on specific sections within the binary to perform this resolution.

Symbol Table Requirements (.symtab and .dynsym)

magic-trace requires access to a symbol table to translate memory addresses into function names. The tool reads either a regular symbol table (.symtab) or a dynamic symbol table (.dynsym) for dynamically linked programs.

In src/elf.ml, the function Elf.all_symbols queries Owee_elf.Symbol_table to collect the complete list of symbols from the binary. This implementation allows magic-trace to map instruction pointers to their corresponding function names during trace analysis.

If the binary is fully stripped—meaning it lacks both .symtab and .dynsym sections—magic-trace can still record trace events, but it cannot resolve addresses to function names. In this scenario, all symbols appear as [unknown] in the output, making interpretation significantly more difficult.

DWARF Debug Information Requirements

To map addresses to specific source files and line numbers, magic-trace requires DWARF debug information, specifically the .debug_line and .debug_info sections. These sections contain the mapping between machine code addresses and their original source locations.

The code responsible for line-level selections resides in src/symbol_selection.ml. When you request line-specific tracing using the symbol:?... syntax, the select_within_file function calls Elf.all_file_selections to retrieve available line information. If the ELF binary lacks the required DWARF sections, Elf.all_file_selections returns an empty list, causing select_within_file to abort with the error message "No lines found, possibly because of missing debug info" (see lines 48-49 of src/symbol_selection.ml).

Without DWARF line information, magic-trace cannot display source files or line numbers in its output, limiting the tool's effectiveness for source-level debugging.

While not strictly required for basic operation, two additional ELF sections enhance magic-trace functionality:

  • DWARF frame information (.debug_frame): Supports accurate stack unwinding and call-stack reconstruction during tracing.
  • Build ID (.note.gnu.build-id): Enables perf-based symbol resolution, which helps when working with external symbol maps or separate debug files.

Both sections are typically generated automatically when compiling with standard debug flags.

How to Compile Binaries for magic-trace

To satisfy the magic-trace debug info and symbol table requirements, compile your program with debug symbols enabled and avoid stripping the binary.

For OCaml programs, use the -g flag with ocamlopt:

(* hello.ml *)
let () = Printf.printf "Hello, magic-trace!\n"
ocamlopt -g hello.ml -o hello

This command preserves both the symbol table and DWARF debug sections. Run magic-trace with the -debug flag to verify symbol resolution:

magic-trace -debug hello

When properly compiled, the output will display resolved function names (e.g., hello) along with source file and line number information for each sampled instruction.

Never run strip on binaries intended for tracing. Stripping removes the .symtab section and debug sections entirely:

strip hello
magic-trace -debug hello  # Symbols appear as [unknown]

What Happens When Information Is Missing

The following table summarizes the impact of missing debug data:

Missing Component Visual Indicator Functional Impact
Symbol table (.symtab/.dynsym) Function names display as [unknown] Raw address traces only; no function resolution
DWARF line info (.debug_line) No source file/line numbers shown select_within_file fails with "No lines found, possibly because of missing debug info"
DWARF frame info (.debug_frame) Incomplete call stacks Limited stack unwinding capability

Summary

  • ** magic-trace requires unstripped ELF binaries** containing either .symtab (static) or .dynsym (dynamic) symbol tables to resolve function names.
  • DWARF sections (.debug_line and .debug_info) are mandatory for source-level resolution and line selection via symbol_selection.ml.
  • Compile with -g and avoid strip to ensure all required sections remain in the binary.
  • Optional .debug_frame and .note.gnu.build-id sections improve stack unwinding and external symbol resolution.

Frequently Asked Questions

Can magic-trace work on stripped binaries?

Yes, magic-trace can trace stripped binaries, but the output is severely limited. Without the symbol table (.symtab or .dynsym), the tool cannot map addresses to function names, displaying [unknown] instead. Without DWARF debug sections, no source file or line number information is available. As implemented in src/elf.ml, the Elf.all_symbols function returns an empty result for stripped binaries, forcing raw address mode.

Which compiler flags generate the required debug info for magic-trace?

Use the -g flag when compiling with OCaml (ocamlopt -g) or equivalent debug flags in other languages (e.g., -g for GCC/Clang). This flag instructs the compiler to generate the symbol table and DWARF sections (.debug_line, .debug_info). Additionally, ensure you do not run strip or link with -s, as these remove the debug sections that magic-trace depends on for symbol resolution in src/symbol_selection.ml.

Why does line-level selection fail with "No lines found" error?

This error occurs when the binary lacks DWARF line information (.debug_line). In src/symbol_selection.ml, the select_within_file function calls Elf.all_file_selections, which returns an empty list if the ELF file does not contain the required debug sections. The function then constructs the error string at lines 48-49: "No lines found, possibly because of missing debug info". Recompile with -g and verify the binary is not stripped to resolve this issue.

Is DWARF frame information (.debug_frame) mandatory for magic-trace?

No, .debug_frame is optional but strongly recommended. magic-trace can perform basic tracing without it, but missing frame information may limit call-stack reconstruction during trace analysis. The section aids in stack unwinding when the tool needs to reconstruct the sequence of function calls. Most compilers include this automatically when using -g, so no additional flags are typically required.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →