creport: Pretty-print addresses whenever possible.

This commit is contained in:
Michael Scire 2018-07-27 20:34:09 -07:00
parent 5993614c2e
commit a811b447ce
6 changed files with 38 additions and 12 deletions

View file

@ -126,3 +126,16 @@ void CodeList::GetCodeInfoBuildId(u64 debug_handle, u64 rodata_addr, u8 *build_i
} }
} }
} }
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;
}

View file

@ -16,8 +16,12 @@ class CodeList {
static const size_t max_code_count = 0x10; static const size_t max_code_count = 0x10;
u32 code_count = 0; u32 code_count = 0;
CodeInfo code_infos[max_code_count]; CodeInfo code_infos[max_code_count];
/* For pretty-printing. */
char address_str_buf[0x280];
public: public:
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr); void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
const char *GetFormattedAddressString(u64 address);
void SaveToFile(FILE *f_report); void SaveToFile(FILE *f_report);
private: private:
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address); bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);

View file

@ -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->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.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
} }
this->thread_list.SetCodeList(&this->code_list);
if (IsApplication()) { if (IsApplication()) {
ProcessDyingMessage(); ProcessDyingMessage();
@ -242,7 +243,7 @@ void CrashReport::SaveReport() {
void CrashReport::SaveToFile(FILE *f_report) { void CrashReport::SaveToFile(FILE *f_report) {
char buf[0x10] = {0}; 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)); fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result));
/* Process Info. */ /* 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 ID: %016lx\n", this->process_info.process_id);
fprintf(f_report, " Process Flags: %08x\n", this->process_info.flags); fprintf(f_report, " Process Flags: %08x\n", this->process_info.flags);
if (kernelAbove500()) { 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, "Exception Info:\n");
fprintf(f_report, " Type: %s\n", GetDebugExceptionTypeStr(this->exception_info.type)); 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) { switch (this->exception_info.type) {
case DebugExceptionType::UndefinedInstruction: case DebugExceptionType::UndefinedInstruction:
fprintf(f_report, " Opcode: %08x\n", this->exception_info.specific.undefined_instruction.insn); 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::DataAbort:
case DebugExceptionType::AlignmentFault: case DebugExceptionType::AlignmentFault:
if (this->exception_info.specific.raw != this->exception_info.address) { 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; break;
case DebugExceptionType::BadSvc: case DebugExceptionType::BadSvc:
@ -282,7 +283,7 @@ void CrashReport::SaveToFile(FILE *f_report) {
if (kernelAbove500()) { if (kernelAbove500()) {
if (this->dying_message_size) { if (this->dying_message_size) {
fprintf(f_report, "Dying Message Info:\n"); 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); fprintf(f_report, " Size: 0x%016lx\n", this->dying_message_size);
CrashReport::Memdump(f_report, " Dying Message: ", this->dying_message, this->dying_message_size); CrashReport::Memdump(f_report, " Dying Message: ", this->dying_message, this->dying_message_size);
} }

View file

@ -12,16 +12,16 @@ void ThreadInfo::SaveToFile(FILE *f_report) {
fprintf(f_report, " Registers:\n"); fprintf(f_report, " Registers:\n");
{ {
for (unsigned int i = 0; i <= 28; i++) { 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, " FP: %s\n", this->code_list->GetFormattedAddressString(this->context.fp));
fprintf(f_report, " LR: %016lx\n", this->context.lr); fprintf(f_report, " LR: %s\n", this->code_list->GetFormattedAddressString(this->context.lr));
fprintf(f_report, " SP: %016lx\n", this->context.sp); fprintf(f_report, " SP: %s\n", this->code_list->GetFormattedAddressString(this->context.sp));
fprintf(f_report, " PC: %016lx\n", this->context.pc); fprintf(f_report, " PC: %s\n", this->code_list->GetFormattedAddressString(this->context.pc));
} }
fprintf(f_report, " Stack Trace:\n"); fprintf(f_report, " Stack Trace:\n");
for (unsigned int i = 0; i < this->stack_trace_size; i++) { 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]));
} }
} }

View file

@ -3,6 +3,7 @@
#include <cstdio> #include <cstdio>
#include "creport_debug_types.hpp" #include "creport_debug_types.hpp"
#include "creport_code_info.hpp"
struct FpuReg { struct FpuReg {
u64 _[2]; /* TODO: uint128? */ u64 _[2]; /* TODO: uint128? */
@ -37,6 +38,7 @@ class ThreadInfo {
u64 stack_bottom = 0; u64 stack_bottom = 0;
u64 stack_trace[0x20]{}; u64 stack_trace[0x20]{};
u32 stack_trace_size = 0; u32 stack_trace_size = 0;
CodeList *code_list;
public: public:
u64 GetPC() { return context.pc; } u64 GetPC() { return context.pc; }
u64 GetLR() { return context.lr; } u64 GetLR() { return context.lr; }
@ -45,6 +47,7 @@ class ThreadInfo {
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit); bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
void SaveToFile(FILE *f_report); void SaveToFile(FILE *f_report);
void DumpBinary(FILE *f_bin); void DumpBinary(FILE *f_bin);
void SetCodeList(CodeList *cl) { this->code_list = cl; }
private: private:
void TryGetStackInfo(Handle debug_handle); void TryGetStackInfo(Handle debug_handle);
}; };
@ -58,4 +61,9 @@ class ThreadList {
void SaveToFile(FILE *f_report); void SaveToFile(FILE *f_report);
void DumpBinary(FILE *f_bin, u64 crashed_id); void DumpBinary(FILE *f_bin, u64 crashed_id);
void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit); 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);
}
}
}; };