Просмотр исходного кода

svcBreak now dumps information from the debug buffer passed (#1646)

* svcBreak now dumps information from the debug buffer passed

info1 and info2 seem to somtimes hold an address to a buffer, this is usually 4 bytes or the size of the int and contains an error code. There's other circumstances where it can be something different so we hexdump these to examine them at a later date.

* Addressed comments
David 7 лет назад
Родитель
Сommit
581406af18
1 измененных файлов с 28 добавлено и 0 удалено
  1. 28 0
      src/core/hle/kernel/svc.cpp

+ 28 - 0
src/core/hle/kernel/svc.cpp

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