Skip to content

Commit eb2f198

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] facebook@a66dd13 [2] facebook@c11ad4e [3] https://github.com/facebook/hhvm/commits/master/hphp/runtime/vm/debug/debug.cpp
1 parent a9af9fc commit eb2f198

8 files changed

Lines changed: 16 additions & 504 deletions

File tree

CMake/HPHPFindLibs.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ if (APPLE)
271271
find_library(KERBEROS_LIB NAMES gssapi_krb5)
272272
endif()
273273

274+
if (LINUX)
275+
find_package(LibUnwind REQUIRED)
276+
endif()
277+
274278
# This is required by Homebrew's libc. See
275279
# https://github.com/facebook/hhvm/pull/5728#issuecomment-124290712
276280
# for more info.
@@ -419,6 +423,10 @@ macro(hphp_link target)
419423
target_link_libraries(${target} ${VISIBILITY} afdt)
420424
target_link_libraries(${target} ${VISIBILITY} mbfl)
421425

426+
if (LINUX)
427+
target_link_libraries(${target} ${VISIBILITY} ${LIBUNWIND_LIBRARIES})
428+
endif()
429+
422430
if (EDITLINE_LIBRARIES)
423431
target_link_libraries(${target} ${VISIBILITY} ${EDITLINE_LIBRARIES})
424432
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)