mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-18 17:00:30 -04:00
chore: print stack trace when abort() is called on Windows
This is just a quick hack, the use of `cpptrace` should be more general and platform-independent.
This commit is contained in:
parent
1324c90faf
commit
2fcbee2a0b
@ -202,6 +202,10 @@ if(WITH_LIBDWARFS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
find_package(cpptrace REQUIRED CONFIG)
|
||||
endif()
|
||||
|
||||
pkg_check_modules(LIBCRYPTO REQUIRED IMPORTED_TARGET libcrypto>=${LIBCRYPTO_REQUIRED_VERSION})
|
||||
pkg_check_modules(LIBARCHIVE REQUIRED IMPORTED_TARGET libarchive>=${LIBARCHIVE_REQUIRED_VERSION})
|
||||
pkg_check_modules(XXHASH REQUIRED IMPORTED_TARGET libxxhash>=${XXHASH_REQUIRED_VERSION})
|
||||
@ -653,6 +657,7 @@ foreach(tgt ${LIBDWARFS_TARGETS} ${LIBDWARFS_OBJECT_TARGETS} dwarfs_test_helpers
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${tgt} PRIVATE ntdll.lib dbghelp.lib)
|
||||
target_link_libraries(${tgt} PRIVATE cpptrace::cpptrace)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
@ -33,6 +33,9 @@ int safe_main(std::function<int(void)> fn) {
|
||||
try {
|
||||
install_signal_handlers();
|
||||
setup_default_locale();
|
||||
#ifdef _WIN32
|
||||
::_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||
#endif
|
||||
|
||||
return fn();
|
||||
} catch (...) {
|
||||
|
69
src/util.cpp
69
src/util.cpp
@ -45,9 +45,15 @@
|
||||
|
||||
#include <dwarfs/config.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cpptrace/cpptrace.hpp>
|
||||
#include <signal.h>
|
||||
#include <tlhelp32.h>
|
||||
#else
|
||||
#ifdef DWARFS_STACKTRACE_ENABLED
|
||||
#include <folly/debugging/symbolizer/SignalHandler.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <dwarfs/conv.h>
|
||||
#include <dwarfs/error.h>
|
||||
@ -393,10 +399,73 @@ int get_current_umask() {
|
||||
return mask;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<HANDLE> suspend_other_threads() {
|
||||
std::vector<HANDLE> handles;
|
||||
DWORD currend_tid = ::GetCurrentThreadId();
|
||||
DWORD current_pid = ::GetCurrentProcessId();
|
||||
|
||||
HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (snapshot == INVALID_HANDLE_VALUE) {
|
||||
return handles;
|
||||
}
|
||||
|
||||
THREADENTRY32 te;
|
||||
te.dwSize = sizeof(THREADENTRY32);
|
||||
|
||||
if (::Thread32First(snapshot, &te)) {
|
||||
do {
|
||||
if (te.th32OwnerProcessID == current_pid &&
|
||||
te.th32ThreadID != currend_tid) {
|
||||
HANDLE th =
|
||||
::OpenThread(THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION,
|
||||
FALSE, te.th32ThreadID);
|
||||
if (th) {
|
||||
if (::SuspendThread(th) != static_cast<DWORD>(-1)) {
|
||||
handles.push_back(th);
|
||||
} else {
|
||||
::CloseHandle(th);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (::Thread32Next(snapshot, &te));
|
||||
}
|
||||
|
||||
::CloseHandle(snapshot);
|
||||
|
||||
return handles;
|
||||
}
|
||||
|
||||
void resume_suspended_threads(const std::vector<HANDLE>& handles) {
|
||||
for (auto th : handles) {
|
||||
::ResumeThread(th);
|
||||
::CloseHandle(th);
|
||||
}
|
||||
}
|
||||
|
||||
void abort_handler(int signal) {
|
||||
auto suspended = suspend_other_threads();
|
||||
std::cerr << "Caught signal " << signal << "\n";
|
||||
cpptrace::generate_trace().print();
|
||||
resume_suspended_threads(suspended);
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
void install_signal_handlers() {
|
||||
#ifdef _WIN32
|
||||
::signal(SIGABRT, abort_handler);
|
||||
#else
|
||||
#ifdef DWARFS_STACKTRACE_ENABLED
|
||||
folly::symbolizer::installFatalSignalHandler();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace dwarfs
|
||||
|
@ -15,6 +15,7 @@
|
||||
"boost-uuid",
|
||||
"boost-variant",
|
||||
"brotli",
|
||||
"cpptrace",
|
||||
"date",
|
||||
"double-conversion",
|
||||
"fmt",
|
||||
|
Loading…
x
Reference in New Issue
Block a user