Skip to content

Conversation

@vchigrin
Copy link
Contributor

Some stack may have frames with missing FDE records, for example, when they implemented in assembly and author did not provide frame information manually.
In that case any attempt to unwind such stack will result in potentially long linear .eh_frame section scan.
This patch adds assumption that if .eh_frame_hdr section is present and not empty, then any frame must be present in it and we can skip long linear scan of .eh_frame section.

@vchigrin vchigrin requested a review from a team as a code owner November 13, 2025 09:12
@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-libunwind

Author: Vyacheslav Chigrin (vchigrin)

Changes

Some stack may have frames with missing FDE records, for example, when they implemented in assembly and author did not provide frame information manually.
In that case any attempt to unwind such stack will result in potentially long linear .eh_frame section scan.
This patch adds assumption that if .eh_frame_hdr section is present and not empty, then any frame must be present in it and we can skip long linear scan of .eh_frame section.


Full diff: https://github.com/llvm/llvm-project/pull/167849.diff

1 Files Affected:

  • (modified) libunwind/src/UnwindCursor.hpp (+20-3)
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index d7348254af07b..42c3cf9084219 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -1787,9 +1787,26 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(
   }
   if (!foundFDE) {
     // Still not found, do full scan of __eh_frame section.
-    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
-                                      sects.dwarf_section_length, 0,
-                                      &fdeInfo, &cieInfo);
+    // But only if __eh_frame_hdr is absent or empty.
+    // We assume that both sections have the same data, and don't want to waste
+    // time for long scan for absent addresses.
+    bool hasEHHeaderData = false;
+#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
+    if ((sects.dwarf_index_section != 0)) {
+      typename EHHeaderParser<A>::EHHeaderInfo hdrInfo;
+      const pint_t ehHdrStart = sects.dwarf_index_section;
+      const pint_t ehHdrEnd = ehHdrStart + sects.dwarf_index_section_length;
+      if (EHHeaderParser<A>::decodeEHHdr(_addressSpace, ehHdrStart, ehHdrEnd,
+                                         hdrInfo)) {
+        hasEHHeaderData = (hdrInfo.fde_count != 0);
+      }
+    }
+#endif
+    if (!hasEHHeaderData) {
+      foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
+                                        sects.dwarf_section_length, 0, &fdeInfo,
+                                        &cieInfo);
+    }
   }
   if (foundFDE) {
     if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {

@github-actions
Copy link

github-actions bot commented Nov 13, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@vchigrin
Copy link
Contributor Author

As far as I can understand, GCC unwinding approach is similar. Check code here
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/unwind-dw2-fde-dip.c;h=57d0c8812b13a2bfa8ff9b5e031347ad9afd7032;hb=refs/heads/releases/gcc-14#l506
seems, if their code finds suitable .eh_frame_hdr data, it uses it. And if entry not found in the table, it simply returns NULL, falling back to linear search in .eh_frame only if .eh_frame_hdr has no suitable encoding or alignment.

@vchigrin
Copy link
Contributor Author

@kovdan01 , @atrosinenko - saw you in reviewers of one recent PR-s, touching this file. Could you either review, or redirect to appropriate reviewers for this change? Thank you in advance!

@vchigrin
Copy link
Contributor Author

On my testing program it changed timings of construction of boost::stacktrace::stacktrace object from
4519407ns to 81666ns - that is, about 50x improvement. Of course this is depends on the many factors: how many frames has tested binary, did examined stack include frames with missed FDEs, etc.

@kovdan01 kovdan01 requested a review from ldionne November 14, 2025 13:51
@kovdan01
Copy link
Contributor

@kovdan01 , @atrosinenko - saw you in reviewers of one recent PR-s, touching this file. Could you either review, or redirect to appropriate reviewers for this change? Thank you in advance!

@ldionne Could you please take a look at the changes and/or assign appropriate reviewers? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants