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-traceback 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.24.11, 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;
  • a panic traceback is missing goroutine 1 [running]:;
  • 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.

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions