Skip to content

pclntab: preserve precise statement PCs with Darwin DWARF #2115

Description

@cpunion

Summary

Enabling LLGo's existing DWARF path for a native Darwin executable makes several end-user runtime.Caller, runtime.CallersFrames, logging, and panic-frame checks lose Go-compatible statement locations. The same probes pass when built with -ldflags=-w.

This was exposed while validating the default-DWARF policy for #2112. The failure belongs to pclntab/PC-line generation and reconstruction; DWARF is the configuration trigger, not the runtime lookup source. It should be fixed separately rather than folded into the initial pclntab packaging change.

Reproduction

Host: Darwin/arm64, Go 1.26.5, LLVM 19.

go test ./test/go -run 'TestCallerAcceptanceLogging|TestCallerAcceptancePanicTraceback|TestCallerAcceptanceIntrospection|TestRuntimeLineInfoAndStack|TestRuntimeStatementLineInfo' -count=1 -v

All five failures are repeatable with DWARF enabled by default. Representative differences:

  • log reports main.go:23, while the Go-compatible call site is line 26;
  • panic user frames retain Go-style formatting but can carry earlier/imprecise source lines;
  • a goroutine caller reports line 68 instead of 69;
  • CallersFrames attributes checkFrames to line 46 instead of the call at line 48;
  • statement-line lookup reports line 37 instead of 39.

Building the probes with -ldflags=-w retains the existing precise pclntab behavior.

Root-cause analysis

runtime.Caller, runtime.CallersFrames, and runtime.FuncForPC do not read DWARF at runtime. They resolve PCs through LLGo's funcinfo/pclntab and PC-line tables, so the wrong line cannot come from a DWARF line-table lookup.

The relevant build-policy branch is shouldEnablePCLNSites: for Darwin embedded builds it disables compiler-emitted PC anchor sites when emitDebugInfo=true, because those inline anchors currently disturb LLDB lexical scopes. With the anchors absent, embedded-table reconstruction lacks the final statement PCs needed for exact call-site attribution. Passing -ldflags=-w makes emitDebugInfo=false, re-enables the sites, and restores all five precise-line tests.

This makes the causal chain:

Darwin + embedded pclntab + DWARF enabled
  -> compiler PC sites disabled for LLDB compatibility
  -> reconstructed pclntab loses some statement PCs
  -> Caller/CallersFrames/FuncForPC report an earlier line or incomplete stack

The primary fix therefore belongs in the pclntab/PC-line integration: preserve or reconstruct precise statement PCs while keeping DWARF enabled. It is not a fix to make the runtime parse DWARF.

A separate raw-address panic fallback found while reducing a combined logging/panic probe is tracked by #2149 and fixed by draft PR #2151. Its cause is a returned C helper frame in the physical FP walker, not missing PCLN sites; that failure is explicitly outside this issue.

Required outcome

The fix needs to reconcile both requirements:

  • preserve precise Go-compatible PCLN/statement locations in default DWARF builds;
  • keep the existing LLDB suite passing without corrupting lexical scopes.

Large DI or PCLN reconstruction changes are intentionally out of scope for the initial -pclntab implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggo-compatCompatibility with Go commands, flags, and toolchain behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions