mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
Log last function on debug pause or exception, dump cpu_thread state on access violation
This commit is contained in:
parent
d7a2d42d8f
commit
537d3f2548
@ -1410,6 +1410,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
if (cpu->id_type() != 1)
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
|
||||
// TODO:
|
||||
@ -1446,6 +1447,12 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
}
|
||||
|
||||
Emu.Pause();
|
||||
|
||||
if (cpu)
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
|
||||
}
|
||||
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
|
||||
while (Emu.IsPaused())
|
||||
|
@ -153,9 +153,9 @@ void cpu_thread::operator()()
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Emu.Pause();
|
||||
LOG_FATAL(GENERAL, "%s thrown: %s", typeid(e).name(), e.what());
|
||||
LOG_NOTICE(GENERAL, "\n%s", dump());
|
||||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -62,13 +62,13 @@ public:
|
||||
}
|
||||
|
||||
// Test stopped state
|
||||
bool is_stopped()
|
||||
bool is_stopped() const
|
||||
{
|
||||
return !!(state & (cpu_flag::stop + cpu_flag::exit + cpu_flag::jit_return + cpu_flag::dbg_global_stop));
|
||||
}
|
||||
|
||||
// Test paused state
|
||||
bool is_paused()
|
||||
bool is_paused() const
|
||||
{
|
||||
return !!(state & (cpu_flag::suspend + cpu_flag::dbg_global_pause + cpu_flag::dbg_pause));
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ using ppu_function_t = bool(*)(ppu_thread&);
|
||||
|
||||
// BIND_FUNC macro "converts" any appropriate HLE function to ppu_function_t, binding it to PPU thread context.
|
||||
#define BIND_FUNC(func, ...) (static_cast<ppu_function_t>([](ppu_thread& ppu) -> bool {\
|
||||
const auto old_f = ppu.last_function;\
|
||||
ppu.last_function = #func;\
|
||||
const auto old_f = ppu.current_function;\
|
||||
if (!old_f) ppu.last_function = #func;\
|
||||
ppu.current_function = #func;\
|
||||
ppu_func_detail::do_call(ppu, func);\
|
||||
ppu.last_function = old_f;\
|
||||
ppu.current_function = old_f;\
|
||||
ppu.cia += 4;\
|
||||
__VA_ARGS__;\
|
||||
return false;\
|
||||
|
@ -448,14 +448,24 @@ std::string ppu_thread::dump() const
|
||||
fmt::append(ret, "Joiner: %s\n", join_status(joiner.load()));
|
||||
fmt::append(ret, "Commands: %u\n", cmd_queue.size());
|
||||
|
||||
const auto _func = last_function;
|
||||
const char* _func = current_function;
|
||||
|
||||
if (_func)
|
||||
{
|
||||
ret += "Last function: ";
|
||||
ret += "Current function: ";
|
||||
ret += _func;
|
||||
ret += '\n';
|
||||
}
|
||||
else if (is_paused())
|
||||
{
|
||||
if (const auto last_func = last_function)
|
||||
{
|
||||
_func = last_func;
|
||||
ret += "Last function: ";
|
||||
ret += _func;
|
||||
ret += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto _time = start_time)
|
||||
{
|
||||
@ -814,13 +824,13 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||
const auto old_cia = cia;
|
||||
const auto old_rtoc = gpr[2];
|
||||
const auto old_lr = lr;
|
||||
const auto old_func = last_function;
|
||||
const auto old_func = current_function;
|
||||
const auto old_fmt = g_tls_log_prefix;
|
||||
|
||||
cia = addr;
|
||||
gpr[2] = rtoc;
|
||||
lr = ppu_function_manager::addr + 8; // HLE stop address
|
||||
last_function = nullptr;
|
||||
current_function = nullptr;
|
||||
|
||||
g_tls_log_prefix = []
|
||||
{
|
||||
@ -832,19 +842,19 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||
{
|
||||
if (std::uncaught_exceptions())
|
||||
{
|
||||
if (last_function)
|
||||
if (current_function)
|
||||
{
|
||||
if (start_time)
|
||||
{
|
||||
LOG_WARNING(PPU, "'%s' aborted (%fs)", last_function, (get_system_time() - start_time) / 1000000.);
|
||||
LOG_WARNING(PPU, "'%s' aborted (%fs)", current_function, (get_system_time() - start_time) / 1000000.);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING(PPU, "'%s' aborted", last_function);
|
||||
LOG_WARNING(PPU, "'%s' aborted", current_function);
|
||||
}
|
||||
}
|
||||
|
||||
last_function = old_func;
|
||||
current_function = old_func;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -852,7 +862,7 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||
cia = old_cia;
|
||||
gpr[2] = old_rtoc;
|
||||
lr = old_lr;
|
||||
last_function = old_func;
|
||||
current_function = old_func;
|
||||
g_tls_log_prefix = old_fmt;
|
||||
}
|
||||
});
|
||||
|
@ -180,7 +180,8 @@ public:
|
||||
cmd64 cmd_get(u32 index) { return cmd_queue[cmd_queue.peek() + index].load(); }
|
||||
|
||||
u64 start_time{0}; // Sleep start timepoint
|
||||
const char* last_function{}; // Last function name for diagnosis, optimized for speed.
|
||||
const char* current_function{}; // Current function name for diagnosis, optimized for speed.
|
||||
const char* last_function{}; // Sticky copy of current_function, is not cleared on function return
|
||||
|
||||
lf_value<std::string> ppu_name; // Thread name
|
||||
|
||||
|
@ -1744,9 +1744,9 @@ s32 error_code::error_report(const fmt_type_info* sup, u64 arg, const fmt_type_i
|
||||
{
|
||||
auto& ppu = static_cast<ppu_thread&>(*thread);
|
||||
|
||||
if (ppu.last_function)
|
||||
if (ppu.current_function)
|
||||
{
|
||||
func = ppu.last_function;
|
||||
func = ppu.current_function;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user