mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 02:42:09 +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;
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
@ -49,6 +52,9 @@ class ThreadList {
|
|||
u32 thread_count = 0;
|
||||
ThreadInfo thread_infos[max_thread_count];
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue