diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -138,6 +138,7 @@ option(LIBUNWIND_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) option(LIBUNWIND_INCLUDE_DOCS "Build the libunwind documentation." ${LLVM_INCLUDE_DOCS}) option(LIBUNWIND_IS_BAREMETAL "Build libunwind for baremetal targets." OFF) +option(LIBUNWIND_USE_FRAMEHEADER_CACHE "Cache frame headers for unwinding. Requires locking dl_iterate_phdr." OFF) set(LIBUNWIND_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") @@ -368,6 +369,10 @@ add_compile_definitions(_LIBUNWIND_IS_BAREMETAL) endif() +if(LIBUNWIND_USE_FRAMEHEADER_CACHE) + add_compile_definitions(_LIBUNWIND_USE_FRAMEHEADER_CACHE) +endif() + # This is the _ONLY_ place where add_definitions is called. if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp --- a/libunwind/src/AddressSpace.hpp +++ b/libunwind/src/AddressSpace.hpp @@ -411,10 +411,13 @@ #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." #endif +#if defined(_LIBUNWIND_USE_FRAMEHEADER_CACHE) #include "FrameHeaderCache.hpp" // There should be just one of these per process. static FrameHeaderCache ProcessFrameHeaderCache; +#endif + static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base, dl_iterate_cb_data *cbdata) { @@ -435,8 +438,10 @@ auto cbdata = static_cast(data); if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr) return 0; +#if defined(_LIBUNWIND_USE_FRAMEHEADER_CACHE) if (ProcessFrameHeaderCache.find(pinfo, pinfo_size, data)) return 1; +#endif Elf_Addr image_base = calculateImageBase(pinfo); bool found_obj = false; @@ -464,7 +469,9 @@ found_obj = checkAddrInSegment(phdr, image_base, cbdata); } if (found_obj && found_hdr) { +#if defined(_LIBUNWIND_USE_FRAMEHEADER_CACHE) ProcessFrameHeaderCache.add(cbdata->sects); +#endif return 1; } } diff --git a/libunwind/test/frameheadercache_test.pass.cpp b/libunwind/test/frameheadercache_test.pass.cpp --- a/libunwind/test/frameheadercache_test.pass.cpp +++ b/libunwind/test/frameheadercache_test.pass.cpp @@ -6,7 +6,7 @@ // The frame header cache should work fine for other architectures, // but the #ifdefs end up being even more complicated than this. -#ifdef __x86_64__ +#if defined(__x86_64__) && defined(_LIBUNWIND_USE_FRAMEHEADER_CACHE) // This #if chain is ugly, but see the comments in AddressSpace.hpp for // the reasoning.