mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-22 18:32:05 +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;
|
||||
if (OpenProcess(pid)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -67,13 +76,13 @@ void CrashReport::HandleAttachProcess(DebugEventInfo &d) {
|
|||
}
|
||||
|
||||
/* Cap userdata size. */
|
||||
if (userdata_size > 0x1000) {
|
||||
userdata_size = 0x1000;
|
||||
if (userdata_size > sizeof(this->dying_message)) {
|
||||
userdata_size = sizeof(this->dying_message);
|
||||
}
|
||||
|
||||
/* Assign. */
|
||||
this->userdata_5x_address = userdata_address;
|
||||
this->userdata_5x_size = userdata_size;
|
||||
this->dying_message_address = userdata_address;
|
||||
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());
|
||||
}
|
||||
|
||||
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) {
|
||||
MemoryInfo mi;
|
||||
u32 pi;
|
||||
|
|
|
@ -27,19 +27,22 @@ class CrashReport {
|
|||
|
||||
/* Attach Process Info. */
|
||||
AttachProcessInfo process_info;
|
||||
u64 userdata_5x_address;
|
||||
u64 userdata_5x_size;
|
||||
u64 dying_message_address;
|
||||
u64 dying_message_size;
|
||||
u8 dying_message[0x1000];
|
||||
|
||||
static_assert(sizeof(dying_message) == 0x1000, "Incorrect definition for dying message!");
|
||||
|
||||
/* Exception Info. */
|
||||
ExceptionInfo exception_info;
|
||||
ThreadInfo crashed_thread_info;
|
||||
|
||||
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 SaveReport();
|
||||
void ProcessExceptions();
|
||||
|
||||
bool IsAddressReadable(u64 address, u64 size, MemoryInfo *mi = NULL);
|
||||
|
||||
|
@ -78,6 +81,8 @@ class CrashReport {
|
|||
return this->exception_info.type == DebugExceptionType::UserBreak;
|
||||
}
|
||||
private:
|
||||
void ProcessExceptions();
|
||||
void ProcessDyingMessage();
|
||||
void HandleAttachProcess(DebugEventInfo &d);
|
||||
void HandleException(DebugEventInfo &d);
|
||||
};
|
Loading…
Reference in a new issue