mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
Improve fatal error report
This commit is contained in:
parent
7be259217a
commit
9245308ff2
1 changed files with 56 additions and 9 deletions
|
@ -6,7 +6,8 @@
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <Windows.h>
|
||||||
|
#include <Psapi.h>
|
||||||
#else
|
#else
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define _XOPEN_SOURCE
|
#define _XOPEN_SOURCE
|
||||||
|
@ -20,11 +21,7 @@
|
||||||
static void report_fatal_error(const std::string& msg)
|
static void report_fatal_error(const std::string& msg)
|
||||||
{
|
{
|
||||||
std::string _msg = msg + "\n"
|
std::string _msg = msg + "\n"
|
||||||
"HOW TO REPORT ERRORS:\n"
|
"HOW TO REPORT ERRORS: Check the FAQ, README, other sources.\n"
|
||||||
"1) Check the FAQ, readme, other sources. Please ensure that your hardware and software configuration is compliant.\n"
|
|
||||||
"2) You must provide FULL information: how to reproduce the error (your actions), RPCS3.log file, other *.log files whenever requested.\n"
|
|
||||||
"3) Please ensure that your software (game) is 'Playable' or close. Please note that 'Non-playable' games will be ignored.\n"
|
|
||||||
"4) If the software (game) is not 'Playable', please ensure that this error is unexpected, i.e. it didn't happen before or similar.\n"
|
|
||||||
"Please, don't send incorrect reports. Thanks for understanding.\n";
|
"Please, don't send incorrect reports. Thanks for understanding.\n";
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -1675,7 +1672,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += fmt::format("Access violation %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
|
msg += fmt::format("Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1687,8 +1684,58 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<HMODULE> modules;
|
||||||
|
for (DWORD size = 256; modules.size() < size; size /= sizeof(HMODULE))
|
||||||
|
{
|
||||||
|
modules.resize(size);
|
||||||
|
if (!EnumProcessModules(GetCurrentProcess(), modules.data(), size * sizeof(HMODULE), &size))
|
||||||
|
{
|
||||||
|
modules.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip);
|
msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip);
|
||||||
msg += fmt::format("Image base: %p.\n", GetModuleHandle(NULL));
|
|
||||||
|
DWORD64 unwind_base;
|
||||||
|
if (const auto rtf = RtlLookupFunctionEntry(pExp->ContextRecord->Rip, &unwind_base, nullptr))
|
||||||
|
{
|
||||||
|
// Get function address
|
||||||
|
const DWORD64 func_addr = rtf->BeginAddress + unwind_base;
|
||||||
|
msg += fmt::format("Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress);
|
||||||
|
|
||||||
|
// Access UNWIND_INFO structure
|
||||||
|
//const auto uw = (u8*)(unwind_base + rtf->UnwindData);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HMODULE module : modules)
|
||||||
|
{
|
||||||
|
MODULEINFO info;
|
||||||
|
if (GetModuleInformation(GetCurrentProcess(), module, &info, sizeof(info)))
|
||||||
|
{
|
||||||
|
const DWORD64 base = (DWORD64)info.lpBaseOfDll;
|
||||||
|
|
||||||
|
if (pExp->ContextRecord->Rip >= base && pExp->ContextRecord->Rip < base + info.SizeOfImage)
|
||||||
|
{
|
||||||
|
std::string module_name;
|
||||||
|
for (DWORD size = 256; module_name.size() < size;)
|
||||||
|
{
|
||||||
|
module_name.resize(size);
|
||||||
|
size = GetModuleBaseNameA(GetCurrentProcess(), module, &module_name.front(), size);
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
module_name.resize(1, '\0');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += fmt::format("Module name: '%s'.\n", module_name);
|
||||||
|
msg += fmt::format("Module base: %p.\n", info.lpBaseOfDll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
||||||
|
|
||||||
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
|
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||||
{
|
{
|
||||||
|
@ -1755,7 +1802,7 @@ static void signal_handler(int sig, siginfo_t* info, void* uct)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO (debugger interaction)
|
// TODO (debugger interaction)
|
||||||
report_fatal_error(fmt::format("Access violation %s location %p at %p.", cause, info->si_addr, RIP(context)));
|
report_fatal_error(fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context)));
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue