mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
creport: Implement reading a dying message
This commit is contained in:
parent
e6b7793916
commit
5268a9f9f3
2 changed files with 49 additions and 9 deletions
|
@ -10,8 +10,17 @@ 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();
|
||||||
|
if (kernelAbove500()) {
|
||||||
|
/* TODO: Process Code Regions. */
|
||||||
|
/* TODO: Process Threads. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsApplication()) {
|
||||||
|
ProcessDyingMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real creport builds the report here. We do it later. */
|
||||||
|
|
||||||
/* TODO: More stuff here (sub_7100002260)... */
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,13 +76,13 @@ void CrashReport::HandleAttachProcess(DebugEventInfo &d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cap userdata size. */
|
/* Cap userdata size. */
|
||||||
if (userdata_size > 0x1000) {
|
if (userdata_size > sizeof(this->dying_message)) {
|
||||||
userdata_size = 0x1000;
|
userdata_size = sizeof(this->dying_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign. */
|
/* Assign. */
|
||||||
this->userdata_5x_address = userdata_address;
|
this->dying_message_address = userdata_address;
|
||||||
this->userdata_5x_size = userdata_size;
|
this->dying_message_size = userdata_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +126,32 @@ void CrashReport::HandleException(DebugEventInfo &d) {
|
||||||
this->crashed_thread_info.ReadFromProcess(this->debug_handle, d.thread_id, Is64Bit());
|
this->crashed_thread_info.ReadFromProcess(this->debug_handle, d.thread_id, Is64Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashReport::ProcessDyingMessage() {
|
||||||
|
/* Dying message is only stored starting in 5.0.0. */
|
||||||
|
if (!kernelAbove500()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate the message address/size. */
|
||||||
|
if (this->dying_message_address == 0 || this->dying_message_address & 0xFFF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->dying_message_size > sizeof(this->dying_message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate that the report isn't garbage. */
|
||||||
|
if (!IsOpen() || !WasSuccessful()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsAddressReadable(this->dying_message_address, this->dying_message_size)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
svcReadDebugProcessMemory(this->dying_message, this->debug_handle, this->dying_message_address, this->dying_message_size);
|
||||||
|
}
|
||||||
|
|
||||||
bool CrashReport::IsAddressReadable(u64 address, u64 size, MemoryInfo *o_mi) {
|
bool CrashReport::IsAddressReadable(u64 address, u64 size, MemoryInfo *o_mi) {
|
||||||
MemoryInfo mi;
|
MemoryInfo mi;
|
||||||
u32 pi;
|
u32 pi;
|
||||||
|
|
|
@ -27,19 +27,22 @@ class CrashReport {
|
||||||
|
|
||||||
/* Attach Process Info. */
|
/* Attach Process Info. */
|
||||||
AttachProcessInfo process_info;
|
AttachProcessInfo process_info;
|
||||||
u64 userdata_5x_address;
|
u64 dying_message_address;
|
||||||
u64 userdata_5x_size;
|
u64 dying_message_size;
|
||||||
|
u8 dying_message[0x1000];
|
||||||
|
|
||||||
|
static_assert(sizeof(dying_message) == 0x1000, "Incorrect definition for dying message!");
|
||||||
|
|
||||||
/* Exception Info. */
|
/* Exception Info. */
|
||||||
ExceptionInfo exception_info;
|
ExceptionInfo exception_info;
|
||||||
ThreadInfo crashed_thread_info;
|
ThreadInfo crashed_thread_info;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CrashReport() : debug_handle(INVALID_HANDLE), result((Result)CrashReportResult::IncompleteReport), process_info({}), exception_info({}) { }
|
CrashReport() : debug_handle(INVALID_HANDLE), result((Result)CrashReportResult::IncompleteReport), process_info({}), dying_message_address(0),
|
||||||
|
dying_message_size(0), dying_message{}, exception_info({}) { }
|
||||||
|
|
||||||
void BuildReport(u64 pid, bool has_extra_info);
|
void BuildReport(u64 pid, bool has_extra_info);
|
||||||
void SaveReport();
|
void SaveReport();
|
||||||
void ProcessExceptions();
|
|
||||||
|
|
||||||
bool IsAddressReadable(u64 address, u64 size, MemoryInfo *mi = NULL);
|
bool IsAddressReadable(u64 address, u64 size, MemoryInfo *mi = NULL);
|
||||||
|
|
||||||
|
@ -78,6 +81,8 @@ class CrashReport {
|
||||||
return this->exception_info.type == DebugExceptionType::UserBreak;
|
return this->exception_info.type == DebugExceptionType::UserBreak;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
void ProcessExceptions();
|
||||||
|
void ProcessDyingMessage();
|
||||||
void HandleAttachProcess(DebugEventInfo &d);
|
void HandleAttachProcess(DebugEventInfo &d);
|
||||||
void HandleException(DebugEventInfo &d);
|
void HandleException(DebugEventInfo &d);
|
||||||
};
|
};
|
Loading…
Reference in a new issue