|
|
@@ -395,16 +395,42 @@ struct BreakReason {
|
|
|
/// Break program execution
|
|
|
static void Break(u32 reason, u64 info1, u64 info2) {
|
|
|
BreakReason break_reason{reason};
|
|
|
+ bool has_dumped_buffer{};
|
|
|
|
|
|
+ const auto handle_debug_buffer = [&](VAddr addr, u64 sz) {
|
|
|
+ if (sz == 0 || addr == 0 || has_dumped_buffer) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // This typically is an error code so we're going to assume this is the case
|
|
|
+ if (sz == sizeof(u32)) {
|
|
|
+ LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr));
|
|
|
+ } else {
|
|
|
+ // We don't know what's in here so we'll hexdump it
|
|
|
+ std::vector<u8> debug_buffer(sz);
|
|
|
+ Memory::ReadBlock(addr, debug_buffer.data(), sz);
|
|
|
+ std::string hexdump;
|
|
|
+ for (std::size_t i = 0; i < debug_buffer.size(); i++) {
|
|
|
+ hexdump += fmt::format("{:02X} ", debug_buffer[i]);
|
|
|
+ if (i != 0 && i % 16 == 0) {
|
|
|
+ hexdump += '\n';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ LOG_CRITICAL(Debug_Emulated, "debug_buffer=\n{}", hexdump);
|
|
|
+ }
|
|
|
+ has_dumped_buffer = true;
|
|
|
+ };
|
|
|
switch (break_reason.break_type) {
|
|
|
case BreakType::Panic:
|
|
|
LOG_CRITICAL(Debug_Emulated, "Signalling debugger, PANIC! info1=0x{:016X}, info2=0x{:016X}",
|
|
|
info1, info2);
|
|
|
+ handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
case BreakType::AssertionFailed:
|
|
|
LOG_CRITICAL(Debug_Emulated,
|
|
|
"Signalling debugger, Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
|
|
|
info1, info2);
|
|
|
+ handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
case BreakType::PreNROLoad:
|
|
|
LOG_WARNING(
|
|
|
@@ -433,6 +459,7 @@ static void Break(u32 reason, u64 info1, u64 info2) {
|
|
|
Debug_Emulated,
|
|
|
"Signalling debugger, Unknown break reason {}, info1=0x{:016X}, info2=0x{:016X}",
|
|
|
static_cast<u32>(break_reason.break_type.Value()), info1, info2);
|
|
|
+ handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -441,6 +468,7 @@ static void Break(u32 reason, u64 info1, u64 info2) {
|
|
|
Debug_Emulated,
|
|
|
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
|
|
|
reason, info1, info2);
|
|
|
+ handle_debug_buffer(info1, info2);
|
|
|
ASSERT(false);
|
|
|
|
|
|
Core::CurrentProcess()->PrepareForTermination();
|