creport: Improve code region list (as N did in 6.1.0)

This commit is contained in:
Michael Scire 2018-11-11 19:52:19 -08:00
parent 1aba87ef76
commit 36530a5501
4 changed files with 49 additions and 14 deletions

View file

@ -32,15 +32,37 @@ void CodeList::SaveToFile(FILE *f_report) {
}
}
void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
void CodeList::ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread) {
u64 code_base;
/* Guess that either PC or LR will point to a code region. This could be false. */
if (!TryFindCodeRegion(debug_handle, pc, &code_base) && !TryFindCodeRegion(debug_handle, lr, &code_base)) {
return;
/* Try to add the thread's PC. */
if (TryFindCodeRegion(debug_handle, thread->GetPC(), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
u64 cur_ptr = code_base;
/* Try to add the thread's LR. */
if (TryFindCodeRegion(debug_handle, thread->GetLR(), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
/* Try to add all the addresses in the thread's stacktrace. */
for (u32 i = 0; i < thread->GetStackTraceSize(); i++) {
if (TryFindCodeRegion(debug_handle, thread->GetStackTrace(i), &code_base)) {
AddCodeRegion(debug_handle, code_base);
}
}
}
void CodeList::AddCodeRegion(u64 debug_handle, u64 code_address) {
/* Check whether we already have this code region. */
for (size_t i = 0; i < this->code_count; i++) {
if (this->code_infos[i].start_address <= code_address && code_address < this->code_infos[i].end_address) {
return;
}
}
/* Add all contiguous code regions. */
u64 cur_ptr = code_address;
while (this->code_count < max_code_count) {
MemoryInfo mi;
u32 pi;

View file

@ -19,6 +19,7 @@
#include <cstdio>
#include "creport_debug_types.hpp"
#include "creport_thread_info.hpp"
struct CodeInfo {
char name[0x20];
@ -29,18 +30,19 @@ struct CodeInfo {
class CodeList {
private:
static const size_t max_code_count = 0x10;
static const size_t max_code_count = 0x60;
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);
void ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread);
const char *GetFormattedAddressString(u64 address);
void SaveToFile(FILE *f_report);
private:
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
void AddCodeRegion(u64 debug_handle, u64 code_address);
void GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
};

View file

@ -27,7 +27,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
this->has_extra_info = has_extra_info;
if (OpenProcess(pid)) {
ProcessExceptions();
this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR());
this->code_list.ReadCodeRegionsFromThreadInfo(this->debug_handle, &this->crashed_thread_info);
this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
this->crashed_thread_info.SetCodeList(&this->code_list);
this->thread_list.SetCodeList(&this->code_list);
@ -36,6 +36,11 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
ProcessDyingMessage();
}
/* Real creport only does this if application, but there's no reason not to do it all the time. */
for (u32 i = 0; i < this->thread_list.GetThreadCount(); i++) {
this->code_list.ReadCodeRegionsFromThreadInfo(this->debug_handle, this->thread_list.GetThreadInfo(i));
}
/* Real creport builds the report here. We do it later. */
Close();
@ -258,7 +263,7 @@ void CrashReport::SaveReport() {
void CrashReport::SaveToFile(FILE *f_report) {
char buf[0x10] = {0};
fprintf(f_report, "Atmosphère Crash Report (v1.1):\n");
fprintf(f_report, "Atmosphère Crash Report (v1.2):\n");
fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->result, R_MODULE(this->result), R_DESCRIPTION(this->result));
/* Process Info. */

View file

@ -19,7 +19,8 @@
#include <cstdio>
#include "creport_debug_types.hpp"
#include "creport_code_info.hpp"
class CodeList;
class ThreadInfo {
private:
@ -31,9 +32,11 @@ class ThreadInfo {
u32 stack_trace_size = 0;
CodeList *code_list;
public:
u64 GetPC() { return context.pc.x; }
u64 GetLR() { return context.lr; }
u64 GetId() { return thread_id; }
u64 GetPC() const { return context.pc.x; }
u64 GetLR() const { return context.lr; }
u64 GetId() const { return thread_id; }
u32 GetStackTraceSize() const { return stack_trace_size; }
u64 GetStackTrace(u32 i) const { return stack_trace[i]; }
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
void SaveToFile(FILE *f_report);
@ -48,7 +51,10 @@ class ThreadList {
static const size_t max_thread_count = 0x60;
u32 thread_count = 0;
ThreadInfo thread_infos[max_thread_count];
public:
public:
u32 GetThreadCount() const { return thread_count; }
const ThreadInfo *GetThreadInfo(u32 i) const { return &thread_infos[i]; }
void SaveToFile(FILE *f_report);
void DumpBinary(FILE *f_bin, u64 crashed_id);
void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit);