llvm / llvm/llvm-project

-femit-dwarf-unwind=always does not work on macOS arm64/aarch64

Open
#179,694 2 comments 0 reactions 0 assignees View on GitHub
debuginfo llvm:mc
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The flag `-femit-dwarf-unwind=always` is documented as always emitting DWARF unwinding tables. This doesn't work in practice for Darwin aarch64 targets, and it behaves more like `-femit-dwarf-unwind=no-compact-unwind`.

This is an issue if the linker then gets the `-no_compact_unwind` flag as there will then be no unwind information at all. At which point exceptions stop working.

(The reason for that linker flag is interoperability with object files produced by gcc, which has issues with compact unwind generation)

The bug is in `MCDwarfFrameEmitter::Emit()` AFAICT. It aborts to early if `SupportsCompactUnwindWithoutEHFrame()` is set, never considering `-femit-dwarf-unwind`.

Suggested fix:

```diff
diff -up cendio-build-llvm-native-macarm-20.1.8/llvm/lib/MC/MCDwarf.cpp.dwarf cendio-build-llvm-native-macarm-20.1.8/llvm/lib/MC/MCDwarf.cpp
--- cendio-build-llvm-native-macarm-20.1.8/llvm/lib/MC/MCDwarf.cpp.dwarf 2026-02-04 16:10:53.226216444 +0100
+++ cendio-build-llvm-native-macarm-20.1.8/llvm/lib/MC/MCDwarf.cpp 2026-02-04 16:11:27.899072994 +0100
@@ -1905,11 +1905,13 @@ void MCDwarfFrameEmitter::Emit(MCObjectS
}
}

+ bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
+
// Compact unwind information can be emitted in the eh_frame section or the
// debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
// doesn't need an eh_frame section and the emission location is the eh_frame
// section.
- if (!NeedsEHFrameSection && IsEH) return;
+ if (!NeedsEHFrameSection && IsEH && CanOmitDwarf) return;

MCSection &Section =
IsEH ? *const_cast(MOFI)->getEHFrameSection()
@@ -1919,7 +1921,6 @@ void MCDwarfFrameEmitter::Emit(MCObjectS
MCSymbol *SectionStart = Context.createTempSymbol();
Streamer.emitLabel(SectionStart);

- bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
// Sort the FDEs by their corresponding CIE before we emit them.
// This isn't technically necessary according to the DWARF standard,
// but the Android libunwindstack rejects eh_frame sections where
```

Contributor guide

Open the contributing guide

Research direction

Start in llvm/lib/MC/MCDwarf.cpp at MCDwarfFrameEmitter::Emit(), then reproduce the behavior for Darwin aarch64 with -femit-dwarf-unwind=always and -no_compact_unwind. Compare the early-return logic with the suggested change; done means DWARF unwind information remains available so exceptions continue to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, macos
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.