Log last function on debug pause or exception, dump cpu_thread state on access violation

This commit is contained in:
Eladash 2019-07-09 20:44:07 +03:00 committed by Ivan
parent d7a2d42d8f
commit 537d3f2548
7 changed files with 37 additions and 18 deletions

View File

@ -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())

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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;\

View File

@ -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;
}
});

View File

@ -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

View File

@ -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;
}
}
}