mirror of https://github.com/AxioDL/logvisor.git
Use libbacktrace for Linux/macOS
This commit is contained in:
parent
81fb4e4c2d
commit
22e14d760a
|
@ -1,3 +1,6 @@
|
||||||
[submodule "fmt"]
|
[submodule "fmt"]
|
||||||
path = fmt
|
path = fmt
|
||||||
url = https://github.com/fmtlib/fmt
|
url = https://github.com/fmtlib/fmt
|
||||||
|
[submodule "libbacktrace"]
|
||||||
|
path = libbacktrace
|
||||||
|
url = https://github.com/status-im/libbacktrace.git
|
||||||
|
|
|
@ -15,13 +15,38 @@ add_library(logvisor
|
||||||
lib/logvisor.cpp
|
lib/logvisor.cpp
|
||||||
include/logvisor/logvisor.hpp)
|
include/logvisor/logvisor.hpp)
|
||||||
|
|
||||||
|
if(APPLE OR UNIX)
|
||||||
|
include(ExternalProject)
|
||||||
|
find_package(Git REQUIRED)
|
||||||
|
find_program(MAKE_EXE NAMES gmake make)
|
||||||
|
ExternalProject_Add(
|
||||||
|
project_libbacktrace
|
||||||
|
PREFIX ${PROJECT_BINARY_DIR}/libbacktrace
|
||||||
|
GIT_REPOSITORY https://github.com/status-im/libbacktrace.git
|
||||||
|
GIT_TAG 2e878a38dd7144c84b665019b1085ea38ebe56d1
|
||||||
|
CONFIGURE_COMMAND ${PROJECT_BINARY_DIR}/libbacktrace/src/project_libbacktrace/configure --enable-host-shared --prefix=${PROJECT_BINARY_DIR}/libbacktrace/install --enable-shared=no --enable-static=yes
|
||||||
|
BUILD_COMMAND ${MAKE_EXE}
|
||||||
|
INSTALL_COMMAND ${MAKE_EXE} install
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
)
|
||||||
|
add_library(libbacktrace STATIC IMPORTED GLOBAL)
|
||||||
|
set_target_properties(libbacktrace PROPERTIES IMPORTED_LOCATION "${PROJECT_BINARY_DIR}/libbacktrace/install/lib/libbacktrace.a")
|
||||||
|
set_target_properties(libbacktrace PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_BINARY_DIR}/libbacktrace/install/include")
|
||||||
|
# Hack for INTERFACE_INCLUDE_DIRECTORIES propagation
|
||||||
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/15052
|
||||||
|
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/libbacktrace/install/include")
|
||||||
|
add_dependencies(libbacktrace project_libbacktrace)
|
||||||
|
set(BACKTRACE_LIBS libbacktrace)
|
||||||
|
else()
|
||||||
|
set(BACKTRACE_LIBS "")
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(logvisor PUBLIC fmt)
|
target_link_libraries(logvisor PUBLIC fmt)
|
||||||
if(NX)
|
if(NX)
|
||||||
target_link_libraries(logvisor PUBLIC debug nxd optimized nx)
|
target_link_libraries(logvisor PUBLIC debug nxd optimized nx)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(logvisor PUBLIC ${CMAKE_DL_LIBS})
|
target_link_libraries(logvisor PRIVATE ${CMAKE_DL_LIBS} ${BACKTRACE_LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(logvisor PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
target_include_directories(logvisor PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||||
|
|
||||||
install(DIRECTORY include/logvisor DESTINATION include)
|
install(DIRECTORY include/logvisor DESTINATION include)
|
||||||
|
|
|
@ -178,57 +178,26 @@ void KillProcessTree() {
|
||||||
|
|
||||||
void KillProcessTree() {}
|
void KillProcessTree() {}
|
||||||
|
|
||||||
#include <execinfo.h>
|
#include <backtrace.h>
|
||||||
[[noreturn]] void logvisorAbort() {
|
|
||||||
void* array[128];
|
|
||||||
size_t size = backtrace(array, 128);
|
|
||||||
|
|
||||||
constexpr size_t exeBufSize = 1024 + 1;
|
void backtrace_error(void* data, const char* msg, int errnum) {
|
||||||
char exeNameBuffer[exeBufSize] = {};
|
std::fprintf(stderr, "Error retrieving stack trace: %d %s\n", errnum, msg);
|
||||||
|
|
||||||
#if __linux__
|
|
||||||
readlink("/proc/self/exe", exeNameBuffer, exeBufSize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __APPLE__
|
|
||||||
std::string cmdLineStr = fmt::format(FMT_STRING("atos -p {}"), getpid());
|
|
||||||
#else
|
|
||||||
std::string cmdLineStr = fmt::format(FMT_STRING("2>/dev/null addr2line -C -f -e \"{}\""), exeNameBuffer);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
#if __linux__
|
|
||||||
Dl_info dlip;
|
|
||||||
if (dladdr(array[i], &dlip))
|
|
||||||
cmdLineStr += fmt::format(FMT_STRING(" 0x{:016X}"), (uintptr_t)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
|
||||||
else
|
|
||||||
cmdLineStr += fmt::format(FMT_STRING(" 0x{:016X}"), (uintptr_t)array[i]);
|
|
||||||
#else
|
|
||||||
cmdLineStr += fmt::format(FMT_STRING(" 0x{:016X}"), (uintptr_t)array[i]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fp = popen(cmdLineStr.c_str(), "r");
|
int backtrace_callback(void* data, uintptr_t pc, const char* filename, int lineno, const char* function) {
|
||||||
if (fp) {
|
int status = -255;
|
||||||
char readBuf[256];
|
char* demangledName = abi::__cxa_demangle(function, nullptr, nullptr, &status);
|
||||||
size_t readSz;
|
std::fprintf(stderr, "0x%lX %s\n\t%s:%d\n", pc, status == 0 ? demangledName : function, filename, lineno);
|
||||||
while ((readSz = fread(readBuf, 1, 256, fp)))
|
if (demangledName != nullptr) {
|
||||||
std::fwrite(readBuf, 1, readSz, stderr);
|
|
||||||
pclose(fp);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
std::fputs("- ", stderr);
|
|
||||||
Dl_info dlip;
|
|
||||||
if (dladdr(array[i], &dlip)) {
|
|
||||||
int status;
|
|
||||||
char* demangledName = abi::__cxa_demangle(dlip.dli_sname, nullptr, nullptr, &status);
|
|
||||||
std::fprintf(stderr, "%p(%s+%p)\n", dlip.dli_saddr, demangledName ? demangledName : dlip.dli_sname,
|
|
||||||
(void*)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
|
||||||
std::free(demangledName);
|
std::free(demangledName);
|
||||||
} else {
|
|
||||||
std::fprintf(stderr, "%p\n", array[i]);
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[noreturn]] void logvisorAbort() {
|
||||||
|
backtrace_state* state = backtrace_create_state(nullptr, 0, backtrace_error, nullptr);
|
||||||
|
if (state != nullptr) {
|
||||||
|
backtrace_full(state, 0, backtrace_callback, backtrace_error, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fflush(stderr);
|
std::fflush(stderr);
|
||||||
|
|
Loading…
Reference in New Issue