mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 10:52:13 +00:00
creport: Improve code region list (as N did in 6.1.0)
This commit is contained in:
parent
1aba87ef76
commit
36530a5501
4 changed files with 49 additions and 14 deletions
|
@ -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;
|
u64 code_base;
|
||||||
|
|
||||||
/* Guess that either PC or LR will point to a code region. This could be false. */
|
/* Try to add the thread's PC. */
|
||||||
if (!TryFindCodeRegion(debug_handle, pc, &code_base) && !TryFindCodeRegion(debug_handle, lr, &code_base)) {
|
if (TryFindCodeRegion(debug_handle, thread->GetPC(), &code_base)) {
|
||||||
return;
|
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) {
|
while (this->code_count < max_code_count) {
|
||||||
MemoryInfo mi;
|
MemoryInfo mi;
|
||||||
u32 pi;
|
u32 pi;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "creport_debug_types.hpp"
|
#include "creport_debug_types.hpp"
|
||||||
|
#include "creport_thread_info.hpp"
|
||||||
|
|
||||||
struct CodeInfo {
|
struct CodeInfo {
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
|
@ -29,18 +30,19 @@ struct CodeInfo {
|
||||||
|
|
||||||
class CodeList {
|
class CodeList {
|
||||||
private:
|
private:
|
||||||
static const size_t max_code_count = 0x10;
|
static const size_t max_code_count = 0x60;
|
||||||
u32 code_count = 0;
|
u32 code_count = 0;
|
||||||
CodeInfo code_infos[max_code_count];
|
CodeInfo code_infos[max_code_count];
|
||||||
|
|
||||||
/* For pretty-printing. */
|
/* For pretty-printing. */
|
||||||
char address_str_buf[0x280];
|
char address_str_buf[0x280];
|
||||||
public:
|
public:
|
||||||
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
void ReadCodeRegionsFromThreadInfo(Handle debug_handle, const ThreadInfo *thread);
|
||||||
const char *GetFormattedAddressString(u64 address);
|
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);
|
||||||
|
void AddCodeRegion(u64 debug_handle, u64 code_address);
|
||||||
void GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
|
void GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
|
||||||
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
|
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
|
||||||
this->has_extra_info = has_extra_info;
|
this->has_extra_info = has_extra_info;
|
||||||
if (OpenProcess(pid)) {
|
if (OpenProcess(pid)) {
|
||||||
ProcessExceptions();
|
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->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
|
||||||
this->crashed_thread_info.SetCodeList(&this->code_list);
|
this->crashed_thread_info.SetCodeList(&this->code_list);
|
||||||
this->thread_list.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();
|
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. */
|
/* Real creport builds the report here. We do it later. */
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
@ -258,7 +263,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.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));
|
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. */
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "creport_debug_types.hpp"
|
#include "creport_debug_types.hpp"
|
||||||
#include "creport_code_info.hpp"
|
|
||||||
|
class CodeList;
|
||||||
|
|
||||||
class ThreadInfo {
|
class ThreadInfo {
|
||||||
private:
|
private:
|
||||||
|
@ -31,9 +32,11 @@ class ThreadInfo {
|
||||||
u32 stack_trace_size = 0;
|
u32 stack_trace_size = 0;
|
||||||
CodeList *code_list;
|
CodeList *code_list;
|
||||||
public:
|
public:
|
||||||
u64 GetPC() { return context.pc.x; }
|
u64 GetPC() const { return context.pc.x; }
|
||||||
u64 GetLR() { return context.lr; }
|
u64 GetLR() const { return context.lr; }
|
||||||
u64 GetId() { return thread_id; }
|
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);
|
bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit);
|
||||||
void SaveToFile(FILE *f_report);
|
void SaveToFile(FILE *f_report);
|
||||||
|
@ -49,6 +52,9 @@ class ThreadList {
|
||||||
u32 thread_count = 0;
|
u32 thread_count = 0;
|
||||||
ThreadInfo thread_infos[max_thread_count];
|
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 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);
|
||||||
|
|
Loading…
Reference in a new issue