Skip to content

Commit a20f5fe

Browse files
Default to disabling the libunwind frameheader cache.
Although it works fine with glibc, as currently implemented the frameheader cache is incompatible with certain platforms with slightly different locking semantics inside dl_iterate_phdr. Therefore only enable it when it is turned on explicitly with a configure-time option. Differential Revision: https://reviews.llvm.org/D86163
1 parent 9028c03 commit a20f5fe

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

libunwind/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ option(LIBUNWIND_WEAK_PTHREAD_LIB "Use weak references to refer to pthread funct
138138
option(LIBUNWIND_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
139139
option(LIBUNWIND_INCLUDE_DOCS "Build the libunwind documentation." ${LLVM_INCLUDE_DOCS})
140140
option(LIBUNWIND_IS_BAREMETAL "Build libunwind for baremetal targets." OFF)
141+
option(LIBUNWIND_USE_FRAME_HEADER_CACHE "Cache frame headers for unwinding. Requires locking dl_iterate_phdr." OFF)
141142

142143
set(LIBUNWIND_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
143144
"Define suffix of library directory name (32/64)")
@@ -368,6 +369,10 @@ if(LIBUNWIND_IS_BAREMETAL)
368369
add_compile_definitions(_LIBUNWIND_IS_BAREMETAL)
369370
endif()
370371

372+
if(LIBUNWIND_USE_FRAME_HEADER_CACHE)
373+
add_compile_definitions(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
374+
endif()
375+
371376
# This is the _ONLY_ place where add_definitions is called.
372377
if (MSVC)
373378
add_definitions(-D_CRT_SECURE_NO_WARNINGS)

libunwind/src/AddressSpace.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,12 @@ struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
411411
#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
412412
#endif
413413

414+
#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
414415
#include "FrameHeaderCache.hpp"
415416

416417
// There should be just one of these per process.
417418
static FrameHeaderCache ProcessFrameHeaderCache;
419+
#endif
418420

419421
static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,
420422
dl_iterate_cb_data *cbdata) {
@@ -435,8 +437,10 @@ int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t pinfo_size,
435437
auto cbdata = static_cast<dl_iterate_cb_data *>(data);
436438
if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr)
437439
return 0;
440+
#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
438441
if (ProcessFrameHeaderCache.find(pinfo, pinfo_size, data))
439442
return 1;
443+
#endif
440444

441445
Elf_Addr image_base = calculateImageBase(pinfo);
442446
bool found_obj = false;
@@ -464,7 +468,9 @@ int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t pinfo_size,
464468
found_obj = checkAddrInSegment(phdr, image_base, cbdata);
465469
}
466470
if (found_obj && found_hdr) {
471+
#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
467472
ProcessFrameHeaderCache.add(cbdata->sects);
473+
#endif
468474
return 1;
469475
}
470476
}

libunwind/test/frameheadercache_test.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// The frame header cache should work fine for other architectures,
77
// but the #ifdefs end up being even more complicated than this.
88

9-
#ifdef __x86_64__
9+
#if defined(__x86_64__) && defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
1010

1111
// This #if chain is ugly, but see the comments in AddressSpace.hpp for
1212
// the reasoning.

0 commit comments

Comments
 (0)