AArch64 DWARF unwind + macOS os_signpost integration#176
Open
angerman wants to merge 2 commits intostable-ghc-9.14from
Open
AArch64 DWARF unwind + macOS os_signpost integration#176angerman wants to merge 2 commits intostable-ghc-9.14from
angerman wants to merge 2 commits intostable-ghc-9.14from
Conversation
The AArch64 native code generator was silently discarding CmmUnwind nodes (`return nilOL`), making DWARF-based profiling and debugging impossible on Apple Silicon and ARM64 Linux. This commit adds full DWARF unwind support, mirroring the existing X86 implementation: - Add UNWIND pseudo-instruction to AArch64.Instr - Convert CmmUnwind nodes to UNWIND instructions in CodeGen - Emit UNWIND after DELTA via addSpUnwindings for SP tracking - Wire extractUnwindPoints into the AArch64 NcgImpl record - Pretty-print UNWIND as a label + comment in Ppr With this change, `ghc -g` on AArch64 produces .debug_frame entries, enabling `lldb` backtraces, `dwarfdump --debug-frame`, and sampler- based profilers (Instruments, Samply) to unwind through Haskell code.
GHC-compiled programs are invisible to Apple Instruments because the
RTS emits no os_signpost events. This makes it hard to correlate GC
pauses and thread scheduling with system-level activity on macOS.
Add a new Signpost.c/Signpost.h module that bridges RTS events to the
os_signpost API, using OS_LOG_CATEGORY_POINTS_OF_INTEREST so events
appear in Instruments by default without a custom .instrpkg:
- GC intervals: begin/end pairs tracked per-capability with unique
signpost IDs, emitting generation, bytes copied, and slop
- Thread lifecycle: create/run/stop as point events with cap and tid
- User events: traceEvent#/traceMarker# forwarded as signposts
All functions gate on os_signpost_enabled() so the overhead when
Instruments is not attached is near zero (a single branch on the
log handle's signpost-enabled flag).
On non-Darwin platforms, all functions compile to empty macros.
Integration points:
- Stats.c: GC begin/end with full statistics
- Trace.h/Trace.c: thread and user event forwarding
- RtsStartup.c: init after initScheduler, free before endTracing
b203c9e to
eeb6c01
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent, complementary features that make GHC-compiled Haskell code visible to standard profiling tools on macOS:
Part 1: AArch64 DWARF Unwind Support (GHC #19913)
The AArch64 NCG was silently discarding
CmmUnwindnodes (return nilOL), producing no DWARF unwind information. This madelldb bt, Instruments, and Samply unable to unwind through Haskell frames on Apple Silicon.UNWINDpseudo-instruction to AArch64Instrdata type (mirrors X86)CmmUnwind→UNWINDconversion instmtToInstrsaddSpUnwindingsto emitUNWINDafterDELTA(tracks SP changes)extractUnwindPointsand wire intoNcgImpl(wasconst [])Part 2: macOS os_signpost Integration
The RTS had no
os_signpostsupport, making GC pauses, thread events, and user events invisible in Apple Instruments.rts/Signpost.{h,c}with os_signpost API wrapperstraceEvent#/traceMarker#)os_signpost_enabled()gate)Files Changed
Compiler (AArch64 DWARF):
compiler/GHC/CmmToAsm/AArch64/Instr.hs— UNWIND constructor + pattern matchescompiler/GHC/CmmToAsm/AArch64/CodeGen.hs— CmmUnwind handler, addSpUnwindings, extractUnwindPointscompiler/GHC/CmmToAsm/AArch64/Ppr.hs— UNWIND pretty-printingcompiler/GHC/CmmToAsm/AArch64.hs— Wire extractUnwindPoints into NcgImplRTS (os_signpost):
rts/Signpost.h— Header with Darwin functions / non-Darwin empty macrosrts/Signpost.c— os_signpost implementationrts/RtsStartup.c— initSignposts/freeSignposts lifecyclerts/Stats.c— GC begin/end signpost callsrts/Trace.h— Thread event signpost callsrts/Trace.c— User event signpost callsrts/rts.cabal— Add Signpost.c to buildTest plan
-gand verifydwarfdump --debug-frameshows FDE entrieslldband verifybtshows Haskell framestraceEvent/traceMarkerevents appear as signpost events