Skip to content

Commit 6063823

Browse files
committed
Enable stack trace symbolization for OSS builds
Historically, HHVM statically linked the system libbfd to power stack trace symbolization in its crash reports and in perf map files. This was disabled for OSS in D2137703[1] because of the wildly differing libbfd ABI across target systems. D3742004[2] and D3855027[3] then brought in folly::Symbolizer for both use cases, but this remained gated behind a Meta-only define. folly::Symbolizer has been stable in upstream folly for a while now, so let's enable it unconditionally and deshim the experimental/ header. This also allows removing the dead libbfd integration. For this to work, the folly build must be built with and able to find libunwind, which isn't a given when building against libc++ and LLVM libunwind on Ubuntu as it installs includes into a subdirectory, so provide an additional hint for this case. This allows us to finally have a proper stacktrace rather than raw memory addresses in crash reports, such as: ``` Core dumped: Segmentation fault Stack trace in /tmp/stacktrace.902095.log Host: hhvm-jammy-vm ProcessID: 902095 ThreadID: 281473658339392 ThreadPID: 902095 Name: /usr/local/bin/hhvm CmdLine: hhvm ../hhvm/hphp/test/quick/dv.php Type: Segmentation fault Runtime: hhvm Version: heads/7.70.0-slack-0-g7be53eff8d22faa0383a128696fae83b224aedd5 DebuggerCount: 0 Arguments: ../hhvm/hphp/test/quick/dv.php ThreadType: CLI -------------------------------Treadmill Information---------------------------- Now: 235093382994348 OldestStartTime: 235093373066177 InflightRequestsSize: 1 Active Requests: 281473658339392 1 235093373066177 (age 9ms) (timeout 0s) CLISession OLDEST ------------------------------------------------------------------------------ CPP Stacktrace: # 0 HPHP::jit::FixupMap::processFixupForVMFrame(HPHP::jit::VMFrame) # 1 HPHP::jit::FixupMap::fixupWork(HPHP::ActRec*, bool) # 2 HPHP::jit::detail::syncVMRegsWork(bool) # 3 HPHP::createBacktrace(HPHP::BacktraceArgs const&) # 4 HPHP::f_debug_backtrace(long, long) # 5 HPHP::throwable_init(HPHP::ObjectData*) # 6 HPHP::ObjectData* HPHP::ObjectData::newInstance<false>(HPHP::Class*) # 7 HPHP::SystemLib::AllocRuntimeExceptionObject(HPHP::Variant const&) # 8 HPHP::SystemLib::throwRuntimeExceptionObject(HPHP::Variant const&) # 9 HPHP::throwMissingArgument(HPHP::Func const*, int) PHP Stacktrace: #0 main() called at [/home/mszabo/hhvm/hphp/test/quick/dv.php:28] #1 main_entry() ``` [1] a66dd13 [2] c11ad4e [3] 0e082c4
1 parent dd50fcc commit 6063823

File tree

8 files changed

+13
-504
lines changed

8 files changed

+13
-504
lines changed

CMake/HPHPFindLibs.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ endif()
273273

274274
if (LINUX)
275275
find_package(Bpf REQUIRED)
276+
find_package(LibUnwind REQUIRED)
276277
endif()
277278

278279
# This is required by Homebrew's libc. See
@@ -427,6 +428,10 @@ macro(hphp_link target)
427428
target_link_libraries(${target} ${VISIBILITY} afdt)
428429
target_link_libraries(${target} ${VISIBILITY} mbfl)
429430

431+
if (LINUX)
432+
target_link_libraries(${target} ${VISIBILITY} ${LIBUNWIND_LIBRARIES})
433+
endif()
434+
430435
if (EDITLINE_LIBRARIES)
431436
target_link_libraries(${target} ${VISIBILITY} ${EDITLINE_LIBRARIES})
432437
elseif (READLINE_LIBRARY)

build/fbcode_builder/CMake/FindLibUnwind.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h)
15+
# When using prepackaged LLVM libunwind on Ubuntu, its includes are installed in a subdirectory.
16+
find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h PATH_SUFFIXES libunwind)
1617
mark_as_advanced(LIBUNWIND_INCLUDE_DIR)
1718

1819
find_library(LIBUNWIND_LIBRARY NAMES unwind)

hphp/runtime/vm/debug/debug.cpp

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,7 @@
2525
#include <stdio.h>
2626
#include <string.h>
2727

28-
#if defined USE_FOLLY_SYMBOLIZER
29-
30-
#include <folly/experimental/symbolizer/Symbolizer.h>
31-
32-
#elif defined HAVE_LIBBFD
33-
34-
#include <bfd.h>
35-
36-
#endif
28+
#include <folly/debugging/symbolizer/Symbolizer.h>
3729

3830
#include <folly/portability/Unistd.h>
3931
#include <folly/Demangle.h>
@@ -115,8 +107,6 @@ void DebugInfo::generatePidMapOverlay() {
115107
};
116108
std::vector<SymInfo> sorted;
117109

118-
#if defined USE_FOLLY_SYMBOLIZER
119-
120110
auto self = current_executable_path();
121111
using folly::symbolizer::ElfFile;
122112
ElfFile file;
@@ -141,51 +131,6 @@ void DebugInfo::generatePidMapOverlay() {
141131
return false;
142132
});
143133

144-
#elif defined HAVE_LIBBFD
145-
146-
auto self = current_executable_path();
147-
bfd* abfd = bfd_openr(self.c_str(), nullptr);
148-
#ifdef BFD_DECOMPRESS
149-
abfd->flags |= BFD_DECOMPRESS;
150-
#endif
151-
SCOPE_EXIT { bfd_close(abfd); };
152-
char **match = nullptr;
153-
if (bfd_check_format(abfd, bfd_archive) ||
154-
!bfd_check_format_matches(abfd, bfd_object, &match)) {
155-
return;
156-
}
157-
158-
long storage_needed = bfd_get_symtab_upper_bound (abfd);
159-
160-
if (storage_needed <= 0) return;
161-
162-
auto symbol_table = (asymbol**)malloc(storage_needed);
163-
164-
SCOPE_EXIT { free(symbol_table); free(match); };
165-
166-
long number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
167-
168-
for (long i = 0; i < number_of_symbols; i++) {
169-
auto sym = symbol_table[i];
170-
if (sym->flags &
171-
(BSF_INDIRECT |
172-
BSF_SECTION_SYM |
173-
BSF_FILE |
174-
BSF_DEBUGGING_RELOC |
175-
BSF_OBJECT)) {
176-
continue;
177-
}
178-
auto sec = sym->section;
179-
if (!(sec->flags & (SEC_ALLOC|SEC_LOAD|SEC_CODE))) continue;
180-
auto addr = sec->vma + sym->value;
181-
if (addr < uintptr_t(pidMapOverlayStart) ||
182-
addr >= uintptr_t(pidMapOverlayEnd)) {
183-
continue;
184-
}
185-
sorted.push_back(SymInfo{sym->name, addr, 0});
186-
}
187-
#endif // HAVE_LIBBFD
188-
189134
std::sort(
190135
sorted.begin(), sorted.end(),
191136
[](const SymInfo& a, const SymInfo& b) {

hphp/util/portability.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,6 @@
189189

190190
//////////////////////////////////////////////////////////////////////
191191

192-
#ifdef HHVM_FACEBOOK
193-
#define USE_FOLLY_SYMBOLIZER 1
194-
// Linking in libbfd is a gigantic PITA, but if folly symbolizer doesn't
195-
// work on your platform, you'll need to figure it out.
196-
#define HAVE_LIBBFD 1
197-
#endif
198-
199192
#ifndef PACKAGE
200193
// The value doesn't matter, but it must be defined before you include
201194
// bfd.h

0 commit comments

Comments
 (0)