mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
creport: Pretty-print addresses whenever possible.
This commit is contained in:
parent
5993614c2e
commit
a811b447ce
6 changed files with 38 additions and 12 deletions
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue