mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 03:00:14 +02:00
Log the faulting host thread, pc and backtrace of a native crash on Linux
A SIGSEGV on the Steam Frame logged only the guest state and 'Host stack trace unavailable on this platform'. With glibc the handler now names the faulting thread, its pc and lr, and a backtrace, each as module + offset for addr2line. The Dawn provider also says when a local package (--dawn-package) replaces the download instead of printing the URL it does not fetch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HBRGKTE1GnN2ah8gcZKr3
This commit is contained in:
2 files changed
+59
-1
No files matched your search
@@ -185,7 +185,11 @@ elseif (_aurora_dawn_provider STREQUAL "package")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
message(STATUS "aurora: Fetching prebuilt Dawn package from ${AURORA_DAWN_PACKAGE_URL}")
|
||||
if (FETCHCONTENT_SOURCE_DIR_DAWN_PREBUILT)
|
||||
message(STATUS "aurora: Using the local Dawn package ${FETCHCONTENT_SOURCE_DIR_DAWN_PREBUILT}")
|
||||
else ()
|
||||
message(STATUS "aurora: Fetching prebuilt Dawn package from ${AURORA_DAWN_PACKAGE_URL}")
|
||||
endif ()
|
||||
|
||||
set(_dawn_prebuilt_hash_argument "")
|
||||
if (AURORA_DAWN_PACKAGE_URL_HASH)
|
||||
|
||||
@@ -49,6 +49,14 @@
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#if defined(__GLIBC__)
|
||||
// The host side of a native crash on desktop Linux: the faulting thread, its pc and lr, and a
|
||||
// backtrace, each as module + offset for addr2line against the unstripped executable.
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
#include <pthread.h>
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "abi_bridge.h"
|
||||
@@ -766,6 +774,23 @@ void SetRuntimeExitCodeImpl(int code) {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
// One host code address as module + offset (what `addr2line -f -C -e <module> <offset>` takes),
|
||||
// with the nearest exported symbol when there is one.
|
||||
void LogHostAddress(const char* label, int index, const void* address) {
|
||||
Dl_info info{};
|
||||
if (address != nullptr && dladdr(address, &info) != 0 && info.dli_fname != nullptr) {
|
||||
const char* slash = std::strrchr(info.dli_fname, '/');
|
||||
const char* module = slash != nullptr ? slash + 1 : info.dli_fname;
|
||||
const auto offset = reinterpret_cast<uintptr_t>(address) - reinterpret_cast<uintptr_t>(info.dli_fbase);
|
||||
RT_LOGF(RT_TAG_RUNTIME, "%s%d %p %s+0x%zx%s%s\n", label, index, address, module, static_cast<size_t>(offset),
|
||||
info.dli_sname != nullptr ? " " : "", info.dli_sname != nullptr ? info.dli_sname : "");
|
||||
} else {
|
||||
RT_LOGF(RT_TAG_RUNTIME, "%s%d %p\n", label, index, address);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void DumpHostStackTrace() {
|
||||
#if defined(_WIN32)
|
||||
static std::atomic_flag s_inProgress = ATOMIC_FLAG_INIT;
|
||||
@@ -776,6 +801,19 @@ void DumpHostStackTrace() {
|
||||
std::fputs(trace.c_str(), stderr);
|
||||
std::fflush(stderr);
|
||||
s_inProgress.clear();
|
||||
#elif defined(__GLIBC__)
|
||||
static std::atomic_flag s_inProgress = ATOMIC_FLAG_INIT;
|
||||
if (s_inProgress.test_and_set()) {
|
||||
return;
|
||||
}
|
||||
std::array<void*, 64> frames{};
|
||||
const int count = backtrace(frames.data(), static_cast<int>(frames.size()));
|
||||
RT_LOGF(RT_TAG_RUNTIME, "Host stack trace (%d frames):\n", count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
LogHostAddress(" #", i, frames[static_cast<size_t>(i)]);
|
||||
}
|
||||
std::fflush(stderr);
|
||||
s_inProgress.clear();
|
||||
#else
|
||||
RT_LOGF(RT_TAG_RUNTIME, "Host stack trace unavailable on this platform\n");
|
||||
std::fflush(stderr);
|
||||
@@ -1231,6 +1269,22 @@ void PosixMemoryFaultHandler(int sig, siginfo_t* info, void* ucontextVoid) {
|
||||
popupDetails << ".\n\nThe process transcript and crash log contain the full CPU and stack "
|
||||
"diagnostics.";
|
||||
ShowRuntimeFatalPopup("a native crash occurred", popupDetails.str());
|
||||
#if defined(__GLIBC__)
|
||||
{
|
||||
char threadName[32] = "?";
|
||||
pthread_getname_np(pthread_self(), threadName, sizeof(threadName));
|
||||
RT_LOGF(RT_TAG_RUNTIME, "Faulting host thread: '%s' (tid %ld)\n", threadName, static_cast<long>(gettid()));
|
||||
if (ucontextVoid != nullptr) {
|
||||
const auto* uc = static_cast<const ucontext_t*>(ucontextVoid);
|
||||
#if defined(__aarch64__)
|
||||
LogHostAddress("Faulting pc #", 0, reinterpret_cast<const void*>(uc->uc_mcontext.pc));
|
||||
LogHostAddress("Faulting lr #", 0, reinterpret_cast<const void*>(uc->uc_mcontext.regs[30]));
|
||||
#elif defined(__x86_64__)
|
||||
LogHostAddress("Faulting pc #", 0, reinterpret_cast<const void*>(uc->uc_mcontext.gregs[REG_RIP]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DumpHostStackTrace();
|
||||
WriteFatalLogImpl(sig == SIGBUS ? "sigbus" : "sigsegv");
|
||||
|
||||
|
||||
Reference in new issue
Block a user