mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-10-12 02:09:17 +00:00
fix emulator crash on crashed game window closure
This commit is contained in:
@@ -2247,12 +2247,12 @@ bool handle_access_violation(u32 addr, bool is_writing, bool is_exec, ucontext_t
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
// Keep retrying until the page is mapped: the thread must be able to resume so it can observe cpu_flag::exit and terminate cleanly.
|
||||
// Reporting the violation as unhandled here would escalate a guest crash into an unhandled host exception.
|
||||
while (!hack_alloc())
|
||||
{
|
||||
thread_ctrl::wait_for(1000);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2301,10 +2301,11 @@ static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
|
||||
is_exec = true;
|
||||
addr = static_cast<u32>(exec64);
|
||||
}
|
||||
else if (const usz exec64 = (ptr - vm::g_exec_addr - vm::g_exec_addr_seg_offset); exec64 <= u32{umax})
|
||||
else if (const usz seg_off = (ptr - vm::g_exec_addr - vm::g_exec_addr_seg_offset); seg_off <= u32{umax} / 2)
|
||||
{
|
||||
// Segment map holds one u16 per 4 bytes of guest code: ptr = g_exec_addr + g_exec_addr_seg_offset + (addr >> 1)
|
||||
is_exec = true;
|
||||
addr = static_cast<u32>(exec64);
|
||||
addr = static_cast<u32>(seg_off * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2549,7 +2550,8 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
|
||||
#endif
|
||||
|
||||
const u64 exec64 = (reinterpret_cast<u64>(info->si_addr) - reinterpret_cast<u64>(vm::g_exec_addr)) / 2;
|
||||
const u64 exec64_2 = (reinterpret_cast<u64>(info->si_addr) - reinterpret_cast<u64>(vm::g_exec_addr)) - vm::g_exec_addr_seg_offset;
|
||||
// Segment map holds one u16 per 4 bytes of guest code: si_addr = g_exec_addr + g_exec_addr_seg_offset + (addr >> 1)
|
||||
const u64 seg_off = (reinterpret_cast<u64>(info->si_addr) - reinterpret_cast<u64>(vm::g_exec_addr)) - vm::g_exec_addr_seg_offset;
|
||||
const auto cause = is_executing ? "executing" : is_writing ? "writing" : "reading";
|
||||
|
||||
if (auto [addr, ok] = vm::try_get_addr(info->si_addr); ok && !is_executing)
|
||||
@@ -2568,9 +2570,9 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (exec64_2 < 0x100000000ull && !is_executing)
|
||||
else if (seg_off < 0x80000000ull && !is_executing)
|
||||
{
|
||||
if (thread_ctrl::get_current() && handle_access_violation(static_cast<u32>(exec64_2), is_writing, true, context))
|
||||
if (thread_ctrl::get_current() && handle_access_violation(static_cast<u32>(seg_off * 2), is_writing, true, context))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user