leanprover / leanprover/lean4

Feature request: emit #line directives in generated C code for source-level debugging

Open
#12,921 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P-medium
Dominant language
Lean
Stars
9.2k
Forks
990
Avg merge
1d 17h
Merged PRs (30d)
175

Description

Summary

The Lean 4 C code generator (EmitC.lean) produces C code without #line preprocessor directives. This means DWARF debug info in compiled binaries references the generated .c files rather than the original .lean source files, making source-level debugging impossible.

Current behavior

When compiling a Lean program with debug flags (moreLeancArgs := #["-g"]), the resulting binary's DWARF .debug_line section maps to the intermediate Main.c file (e.g., .lake/build/ir/Main.c), not the .lean source.

The generated C files contain no #line directives:

// Lean compiler output
// Module: Main
// Imports: public import Init
#include <lean/lean.h>
// ... pure C code with no source location markers ...

Requested behavior

Add #line directives to the generated C code that map back to the corresponding .lean source positions:

#line 6 "Main.lean"
LEAN_EXPORT lean_object* l_calculateSum(lean_object* x_1, lean_object* x_2) {
    // ...
}

This is a standard C preprocessor feature (C11 §6.10.4) supported by all C compilers. Many language implementations that compile through C use this technique (e.g., Cython, GHC's -via-C backend).

Motivation

We're building CodeTracer, a time-travel debugger that supports multiple languages through RR + LLDB. Lean programs can be recorded and replayed, but without source mapping in the DWARF info, we cannot:

  • Set breakpoints on .lean source lines
  • Show the current position in .lean source during stepping
  • Extract flow/omniscience data mapped to Lean source locations

This single change would unblock source-level debugging for Lean in any debugger (LLDB, GDB, CodeTracer, etc.).

Implementation notes

The change would be in src/Lean/Compiler/IR/EmitC.lean. The compiler IR already tracks declaration names — the missing piece is threading source position (Syntax.Pos or Position) information through the IR pipeline and emitting #line directives at function boundaries (and ideally at statement granularity).

A minimal version could emit #line only at function definition boundaries, which would at least enable function-level breakpoints.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/Lean/Compiler/IR/EmitC.lean and inspect how declaration names are emitted and where source positions are available in the IR pipeline. Trace the path from source positions to generated function definitions, then verify that compiled debug output maps function boundaries back to the corresponding .lean files and lines.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.