From a811b447ce84e09d951766829cc64a339df6f6c7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 27 Jul 2018 20:34:09 -0700 Subject: [PATCH] creport: Pretty-print addresses whenever possible. --- stratosphere/creport/source/creport_code_info.cpp | 13 +++++++++++++ stratosphere/creport/source/creport_code_info.hpp | 4 ++++ .../creport/source/creport_crash_report.cpp | 11 ++++++----- .../creport/source/creport_crash_report.hpp | 2 +- stratosphere/creport/source/creport_thread_info.cpp | 12 ++++++------ stratosphere/creport/source/creport_thread_info.hpp | 8 ++++++++ 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/stratosphere/creport/source/creport_code_info.cpp b/stratosphere/creport/source/creport_code_info.cpp index ba7ceb12c..c57a44df1 100644 --- a/stratosphere/creport/source/creport_code_info.cpp +++ b/stratosphere/creport/source/creport_code_info.cpp @@ -125,4 +125,17 @@ void CodeList::GetCodeInfoBuildId(u64 debug_handle, u64 rodata_addr, u8 *build_i memcpy(build_id, last_pages + ofs + 4, 0x20); } } +} + + +const char *CodeList::GetFormattedAddressString(u64 address) { + memset(this->address_str_buf, 0, sizeof(this->address_str_buf)); + for (unsigned int i = 0; i < this->code_count; i++) { + if (this->code_infos[i].start_address <= address && address < this->code_infos[i].end_address) { + snprintf(this->address_str_buf, sizeof(this->address_str_buf) - 1, "%016lx (%s + 0x%lx)", address, this->code_infos[i].name, address - this->code_infos[i].start_address); + return this->address_str_buf; + } + } + snprintf(this->address_str_buf, sizeof(this->address_str_buf) - 1, "%016lx", address); + return this->address_str_buf; } \ No newline at end of file diff --git a/stratosphere/creport/source/creport_code_info.hpp b/stratosphere/creport/source/creport_code_info.hpp index f10834f3d..18aa17b23 100644 --- a/stratosphere/creport/source/creport_code_info.hpp +++ b/stratosphere/creport/source/creport_code_info.hpp @@ -16,8 +16,12 @@ class CodeList { static const size_t max_code_count = 0x10; u32 code_count = 0; CodeInfo code_infos[max_code_count]; + + /* For pretty-printing. */ + char address_str_buf[0x280]; public: void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr); + const char *GetFormattedAddressString(u64 address); void SaveToFile(FILE *f_report); private: bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address); diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 34873bc48..cf396ecc5 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -15,6 +15,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) { this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR()); this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit()); } + this->thread_list.SetCodeList(&this->code_list); if (IsApplication()) { ProcessDyingMessage(); @@ -242,7 +243,7 @@ void CrashReport::SaveReport() { void CrashReport::SaveToFile(FILE *f_report) { char buf[0x10] = {0}; - fprintf(f_report, "Atmosphère Crash Report (v1.0):\n"); + fprintf(f_report, "Atmosphère Crash Report (v1.1):\n"); fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result)); /* Process Info. */ @@ -253,12 +254,12 @@ void CrashReport::SaveToFile(FILE *f_report) { fprintf(f_report, " Process ID: %016lx\n", this->process_info.process_id); fprintf(f_report, " Process Flags: %08x\n", this->process_info.flags); if (kernelAbove500()) { - fprintf(f_report, " User Exception Address: %016lx\n", this->process_info.user_exception_context_address); + fprintf(f_report, " User Exception Address: %s\n", this->code_list.GetFormattedAddressString(this->process_info.user_exception_context_address)); } fprintf(f_report, "Exception Info:\n"); fprintf(f_report, " Type: %s\n", GetDebugExceptionTypeStr(this->exception_info.type)); - fprintf(f_report, " Address: %016lx\n", this->exception_info.address); + fprintf(f_report, " Address: %s\n", this->code_list.GetFormattedAddressString(this->exception_info.address)); switch (this->exception_info.type) { case DebugExceptionType::UndefinedInstruction: fprintf(f_report, " Opcode: %08x\n", this->exception_info.specific.undefined_instruction.insn); @@ -266,7 +267,7 @@ void CrashReport::SaveToFile(FILE *f_report) { case DebugExceptionType::DataAbort: case DebugExceptionType::AlignmentFault: if (this->exception_info.specific.raw != this->exception_info.address) { - fprintf(f_report, " Fault Address: %016lx\n", this->exception_info.specific.raw); + fprintf(f_report, " Fault Address: %s\n", this->code_list.GetFormattedAddressString(this->exception_info.specific.raw)); } break; case DebugExceptionType::BadSvc: @@ -282,7 +283,7 @@ void CrashReport::SaveToFile(FILE *f_report) { if (kernelAbove500()) { if (this->dying_message_size) { fprintf(f_report, "Dying Message Info:\n"); - fprintf(f_report, " Address: 0x%016lx\n", this->dying_message_address); + fprintf(f_report, " Address: 0x%s\n", this->code_list.GetFormattedAddressString(this->dying_message_address)); fprintf(f_report, " Size: 0x%016lx\n", this->dying_message_size); CrashReport::Memdump(f_report, " Dying Message: ", this->dying_message, this->dying_message_size); } diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index d93ba0bcc..76b371cdb 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -43,7 +43,7 @@ class CrashReport { CodeList code_list; ThreadList thread_list; - public: + public: void BuildReport(u64 pid, bool has_extra_info); void SaveReport(); diff --git a/stratosphere/creport/source/creport_thread_info.cpp b/stratosphere/creport/source/creport_thread_info.cpp index f881e1700..f310f8f14 100644 --- a/stratosphere/creport/source/creport_thread_info.cpp +++ b/stratosphere/creport/source/creport_thread_info.cpp @@ -12,16 +12,16 @@ void ThreadInfo::SaveToFile(FILE *f_report) { fprintf(f_report, " Registers:\n"); { for (unsigned int i = 0; i <= 28; i++) { - fprintf(f_report, " X[%02u]: %016lx\n", i, this->context.x[i]); + fprintf(f_report, " X[%02u]: %s\n", i, this->code_list->GetFormattedAddressString(this->context.x[i])); } - fprintf(f_report, " FP: %016lx\n", this->context.fp); - fprintf(f_report, " LR: %016lx\n", this->context.lr); - fprintf(f_report, " SP: %016lx\n", this->context.sp); - fprintf(f_report, " PC: %016lx\n", this->context.pc); + fprintf(f_report, " FP: %s\n", this->code_list->GetFormattedAddressString(this->context.fp)); + fprintf(f_report, " LR: %s\n", this->code_list->GetFormattedAddressString(this->context.lr)); + fprintf(f_report, " SP: %s\n", this->code_list->GetFormattedAddressString(this->context.sp)); + fprintf(f_report, " PC: %s\n", this->code_list->GetFormattedAddressString(this->context.pc)); } fprintf(f_report, " Stack Trace:\n"); for (unsigned int i = 0; i < this->stack_trace_size; i++) { - fprintf(f_report, " ReturnAddress[%02u]: %016lx\n", i, this->stack_trace[i]); + fprintf(f_report, " ReturnAddress[%02u]: %s\n", i, this->code_list->GetFormattedAddressString(this->stack_trace[i])); } } diff --git a/stratosphere/creport/source/creport_thread_info.hpp b/stratosphere/creport/source/creport_thread_info.hpp index 6af698d4b..af49bb779 100644 --- a/stratosphere/creport/source/creport_thread_info.hpp +++ b/stratosphere/creport/source/creport_thread_info.hpp @@ -3,6 +3,7 @@ #include #include "creport_debug_types.hpp" +#include "creport_code_info.hpp" struct FpuReg { u64 _[2]; /* TODO: uint128? */ @@ -37,6 +38,7 @@ class ThreadInfo { u64 stack_bottom = 0; u64 stack_trace[0x20]{}; u32 stack_trace_size = 0; + CodeList *code_list; public: u64 GetPC() { return context.pc; } u64 GetLR() { return context.lr; } @@ -45,6 +47,7 @@ class ThreadInfo { bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit); void SaveToFile(FILE *f_report); void DumpBinary(FILE *f_bin); + void SetCodeList(CodeList *cl) { this->code_list = cl; } private: void TryGetStackInfo(Handle debug_handle); }; @@ -58,4 +61,9 @@ class ThreadList { void SaveToFile(FILE *f_report); void DumpBinary(FILE *f_bin, u64 crashed_id); void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit); + void SetCodeList(CodeList *cl) { + for (u32 i = 0; i < thread_count; i++) { + thread_infos[i].SetCodeList(cl); + } + } };