mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Add more information for segfault reports (#7538)
This commit is contained in:
parent
171e6c6e54
commit
6bb083a77c
@ -8,6 +8,7 @@
|
|||||||
#include "sysinfo.h"
|
#include "sysinfo.h"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
@ -43,6 +44,7 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
LOG_CHANNEL(sig_log);
|
LOG_CHANNEL(sig_log);
|
||||||
|
LOG_CHANNEL(sys_log, "SYS");
|
||||||
LOG_CHANNEL(vm_log, "VM");
|
LOG_CHANNEL(vm_log, "VM");
|
||||||
|
|
||||||
thread_local u64 g_tls_fault_all = 0;
|
thread_local u64 g_tls_fault_all = 0;
|
||||||
@ -50,6 +52,14 @@ thread_local u64 g_tls_fault_rsx = 0;
|
|||||||
thread_local u64 g_tls_fault_spu = 0;
|
thread_local u64 g_tls_fault_spu = 0;
|
||||||
extern thread_local std::string(*g_tls_log_prefix)();
|
extern thread_local std::string(*g_tls_log_prefix)();
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << get_object(arg);
|
||||||
|
out += ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
[[noreturn]] void catch_all_exceptions()
|
[[noreturn]] void catch_all_exceptions()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -1526,18 +1536,32 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
|||||||
{
|
{
|
||||||
const auto cause = pExp->ExceptionRecord->ExceptionInformation[0] != 0 ? "writing" : "reading";
|
const auto cause = pExp->ExceptionRecord->ExceptionInformation[0] != 0 ? "writing" : "reading";
|
||||||
|
|
||||||
msg += fmt::format("Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
|
fmt::append(msg, "Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msg += fmt::format("Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress);
|
fmt::append(msg, "Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress);
|
||||||
|
|
||||||
for (DWORD i = 0; i < pExp->ExceptionRecord->NumberParameters; i++)
|
for (DWORD i = 0; i < pExp->ExceptionRecord->NumberParameters; i++)
|
||||||
{
|
{
|
||||||
msg += fmt::format("ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]);
|
fmt::append(msg, "ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thread_ctrl::get_current())
|
||||||
|
{
|
||||||
|
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
|
||||||
|
|
||||||
|
if (const auto cpu = get_current_cpu_thread())
|
||||||
|
{
|
||||||
|
sys_log.notice("\n%s", cpu->dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Report full thread name if not an emu thread
|
||||||
|
|
||||||
|
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
|
||||||
|
|
||||||
std::vector<HMODULE> modules;
|
std::vector<HMODULE> modules;
|
||||||
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
|
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
|
||||||
{
|
{
|
||||||
@ -1549,14 +1573,14 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip);
|
fmt::append(msg, "Instruction address: %p.\n", pExp->ContextRecord->Rip);
|
||||||
|
|
||||||
DWORD64 unwind_base;
|
DWORD64 unwind_base;
|
||||||
if (const auto rtf = RtlLookupFunctionEntry(pExp->ContextRecord->Rip, &unwind_base, nullptr))
|
if (const auto rtf = RtlLookupFunctionEntry(pExp->ContextRecord->Rip, &unwind_base, nullptr))
|
||||||
{
|
{
|
||||||
// Get function address
|
// Get function address
|
||||||
const DWORD64 func_addr = rtf->BeginAddress + unwind_base;
|
const DWORD64 func_addr = rtf->BeginAddress + unwind_base;
|
||||||
msg += fmt::format("Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress);
|
fmt::append(msg, "Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress);
|
||||||
|
|
||||||
// Access UNWIND_INFO structure
|
// Access UNWIND_INFO structure
|
||||||
//const auto uw = (u8*)(unwind_base + rtf->UnwindData);
|
//const auto uw = (u8*)(unwind_base + rtf->UnwindData);
|
||||||
@ -1583,17 +1607,18 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += fmt::format("Module name: '%s'.\n", module_name);
|
fmt::append(msg, "Module name: '%s'.\n", module_name);
|
||||||
msg += fmt::format("Module base: %p.\n", info.lpBaseOfDll);
|
fmt::append(msg, "Module base: %p.\n", info.lpBaseOfDll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
fmt::append(msg, "RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
||||||
|
|
||||||
// TODO: print registers and the callstack
|
// TODO: print registers and the callstack
|
||||||
|
|
||||||
// Report fatal error
|
// Report fatal error
|
||||||
|
sys_log.fatal("\n%s", msg);
|
||||||
report_fatal_error(msg);
|
report_fatal_error(msg);
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
@ -1652,8 +1677,25 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto cpu = get_current_cpu_thread())
|
||||||
|
{
|
||||||
|
sys_log.notice("\n%s", cpu->dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string msg = fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context));
|
||||||
|
|
||||||
|
if (thread_ctrl::get_current())
|
||||||
|
{
|
||||||
|
fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Report full thread name if not an emu thread
|
||||||
|
|
||||||
|
fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
|
||||||
|
|
||||||
// TODO (debugger interaction)
|
// TODO (debugger interaction)
|
||||||
report_fatal_error(fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context)));
|
sys_log.fatal("\n%s", msg);
|
||||||
|
report_fatal_error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool s_exception_handler_set = []() -> bool
|
const bool s_exception_handler_set = []() -> bool
|
||||||
|
Loading…
Reference in New Issue
Block a user