strat: use m_ for member variables
This commit is contained in:
@@ -86,31 +86,31 @@ namespace ams::creport {
|
||||
|
||||
void CrashReport::Initialize() {
|
||||
/* Initialize the heap. */
|
||||
this->heap_handle = lmem::CreateExpHeap(this->heap_storage, sizeof(this->heap_storage), lmem::CreateOption_None);
|
||||
m_heap_handle = lmem::CreateExpHeap(m_heap_storage, sizeof(m_heap_storage), lmem::CreateOption_None);
|
||||
|
||||
/* Allocate members. */
|
||||
this->module_list = std::construct_at(static_cast<ModuleList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ModuleList))));
|
||||
this->thread_list = std::construct_at(static_cast<ThreadList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ThreadList))));
|
||||
this->dying_message = static_cast<u8 *>(lmem::AllocateFromExpHeap(this->heap_handle, DyingMessageSizeMax));
|
||||
if (this->dying_message != nullptr) {
|
||||
std::memset(this->dying_message, 0, DyingMessageSizeMax);
|
||||
m_module_list = std::construct_at(static_cast<ModuleList *>(lmem::AllocateFromExpHeap(m_heap_handle, sizeof(ModuleList))));
|
||||
m_thread_list = std::construct_at(static_cast<ThreadList *>(lmem::AllocateFromExpHeap(m_heap_handle, sizeof(ThreadList))));
|
||||
m_dying_message = static_cast<u8 *>(lmem::AllocateFromExpHeap(m_heap_handle, DyingMessageSizeMax));
|
||||
if (m_dying_message != nullptr) {
|
||||
std::memset(m_dying_message, 0, DyingMessageSizeMax);
|
||||
}
|
||||
}
|
||||
|
||||
void CrashReport::BuildReport(os::ProcessId process_id, bool has_extra_info) {
|
||||
this->has_extra_info = has_extra_info;
|
||||
m_has_extra_info = has_extra_info;
|
||||
|
||||
if (this->OpenProcess(process_id)) {
|
||||
ON_SCOPE_EXIT { this->Close(); };
|
||||
|
||||
/* Parse info from the crashed process. */
|
||||
this->ProcessExceptions();
|
||||
this->module_list->FindModulesFromThreadInfo(this->debug_handle, this->crashed_thread);
|
||||
this->thread_list->ReadFromProcess(this->debug_handle, this->thread_tls_map, this->Is64Bit());
|
||||
m_module_list->FindModulesFromThreadInfo(m_debug_handle, m_crashed_thread);
|
||||
m_thread_list->ReadFromProcess(m_debug_handle, m_thread_tls_map, this->Is64Bit());
|
||||
|
||||
/* Associate module list to threads. */
|
||||
this->crashed_thread.SetModuleList(this->module_list);
|
||||
this->thread_list->SetModuleList(this->module_list);
|
||||
m_crashed_thread.SetModuleList(m_module_list);
|
||||
m_thread_list->SetModuleList(m_module_list);
|
||||
|
||||
/* Process dying message for applications. */
|
||||
if (this->IsApplication()) {
|
||||
@@ -119,13 +119,13 @@ namespace ams::creport {
|
||||
|
||||
/* Nintendo's creport finds extra modules by looking at all threads if application, */
|
||||
/* but there's no reason for us not to always go looking. */
|
||||
for (size_t i = 0; i < this->thread_list->GetThreadCount(); i++) {
|
||||
this->module_list->FindModulesFromThreadInfo(this->debug_handle, this->thread_list->GetThreadInfo(i));
|
||||
for (size_t i = 0; i < m_thread_list->GetThreadCount(); i++) {
|
||||
m_module_list->FindModulesFromThreadInfo(m_debug_handle, m_thread_list->GetThreadInfo(i));
|
||||
}
|
||||
|
||||
/* Cache the module base address to send to fatal. */
|
||||
if (this->module_list->GetModuleCount()) {
|
||||
this->module_base_address = this->module_list->GetModuleStartAddress(0);
|
||||
if (m_module_list->GetModuleCount()) {
|
||||
m_module_base_address = m_module_list->GetModuleStartAddress(0);
|
||||
}
|
||||
|
||||
/* Nintendo's creport saves the report to erpt here, but we'll save to SD card later. */
|
||||
@@ -139,33 +139,33 @@ namespace ams::creport {
|
||||
|
||||
/* TODO: Support generating 32-bit fatal contexts? */
|
||||
out->architecture = fatal::CpuContext::Architecture_Aarch64;
|
||||
out->type = static_cast<u32>(this->exception_info.type);
|
||||
out->type = static_cast<u32>(m_exception_info.type);
|
||||
|
||||
for (size_t i = 0; i < fatal::aarch64::RegisterName_FP; i++) {
|
||||
out->aarch64_ctx.SetRegisterValue(static_cast<fatal::aarch64::RegisterName>(i), this->crashed_thread.GetGeneralPurposeRegister(i));
|
||||
out->aarch64_ctx.SetRegisterValue(static_cast<fatal::aarch64::RegisterName>(i), m_crashed_thread.GetGeneralPurposeRegister(i));
|
||||
}
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_FP, this->crashed_thread.GetFP());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_LR, this->crashed_thread.GetLR());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_SP, this->crashed_thread.GetSP());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_PC, this->crashed_thread.GetPC());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_FP, m_crashed_thread.GetFP());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_LR, m_crashed_thread.GetLR());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_SP, m_crashed_thread.GetSP());
|
||||
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_PC, m_crashed_thread.GetPC());
|
||||
|
||||
out->aarch64_ctx.stack_trace_size = this->crashed_thread.GetStackTraceSize();
|
||||
out->aarch64_ctx.stack_trace_size = m_crashed_thread.GetStackTraceSize();
|
||||
for (size_t i = 0; i < out->aarch64_ctx.stack_trace_size; i++) {
|
||||
out->aarch64_ctx.stack_trace[i] = this->crashed_thread.GetStackTrace(i);
|
||||
out->aarch64_ctx.stack_trace[i] = m_crashed_thread.GetStackTrace(i);
|
||||
}
|
||||
|
||||
if (this->module_base_address != 0) {
|
||||
out->aarch64_ctx.SetBaseAddress(this->module_base_address);
|
||||
if (m_module_base_address != 0) {
|
||||
out->aarch64_ctx.SetBaseAddress(m_module_base_address);
|
||||
}
|
||||
|
||||
/* For ams fatal, which doesn't use afsr0, pass program_id instead. */
|
||||
out->aarch64_ctx.SetProgramIdForAtmosphere(ncm::ProgramId{this->process_info.program_id});
|
||||
out->aarch64_ctx.SetProgramIdForAtmosphere(ncm::ProgramId{m_process_info.program_id});
|
||||
}
|
||||
|
||||
void CrashReport::ProcessExceptions() {
|
||||
/* Loop all debug events. */
|
||||
svc::DebugEventInfo d;
|
||||
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), this->debug_handle))) {
|
||||
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), m_debug_handle))) {
|
||||
switch (d.type) {
|
||||
case svc::DebugEvent_CreateProcess:
|
||||
this->HandleDebugEventInfoCreateProcess(d);
|
||||
@@ -183,11 +183,11 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Parse crashed thread info. */
|
||||
this->crashed_thread.ReadFromProcess(this->debug_handle, this->thread_tls_map, this->crashed_thread_id, this->Is64Bit());
|
||||
m_crashed_thread.ReadFromProcess(m_debug_handle, m_thread_tls_map, m_crashed_thread_id, this->Is64Bit());
|
||||
}
|
||||
|
||||
void CrashReport::HandleDebugEventInfoCreateProcess(const svc::DebugEventInfo &d) {
|
||||
this->process_info = d.info.create_process;
|
||||
m_process_info = d.info.create_process;
|
||||
|
||||
/* On 5.0.0+, we want to parse out a dying message from application crashes. */
|
||||
if (hos::GetVersion() < hos::Version_5_0_0 || !IsApplication()) {
|
||||
@@ -195,12 +195,12 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Parse out user data. */
|
||||
const u64 address = this->process_info.user_exception_context_address + DyingMessageAddressOffset;
|
||||
const u64 address = m_process_info.user_exception_context_address + DyingMessageAddressOffset;
|
||||
u64 userdata_address = 0;
|
||||
u64 userdata_size = 0;
|
||||
|
||||
/* Read userdata address. */
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_address)), this->debug_handle, address, sizeof(userdata_address)))) {
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_address)), m_debug_handle, address, sizeof(userdata_address)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,48 +210,48 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Read userdata size. */
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_size)), this->debug_handle, address + sizeof(userdata_address), sizeof(userdata_size)))) {
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_size)), m_debug_handle, address + sizeof(userdata_address), sizeof(userdata_size)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cap userdata size. */
|
||||
userdata_size = std::min(size_t(userdata_size), DyingMessageSizeMax);
|
||||
|
||||
this->dying_message_address = userdata_address;
|
||||
this->dying_message_size = userdata_size;
|
||||
m_dying_message_address = userdata_address;
|
||||
m_dying_message_size = userdata_size;
|
||||
}
|
||||
|
||||
void CrashReport::HandleDebugEventInfoCreateThread(const svc::DebugEventInfo &d) {
|
||||
/* Save info on the thread's TLS address for later. */
|
||||
this->thread_tls_map.SetThreadTls(d.info.create_thread.thread_id, d.info.create_thread.tls_address);
|
||||
m_thread_tls_map.SetThreadTls(d.info.create_thread.thread_id, d.info.create_thread.tls_address);
|
||||
}
|
||||
|
||||
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
|
||||
switch (d.info.exception.type) {
|
||||
case svc::DebugException_UndefinedInstruction:
|
||||
this->result = creport::ResultUndefinedInstruction();
|
||||
m_result = creport::ResultUndefinedInstruction();
|
||||
break;
|
||||
case svc::DebugException_InstructionAbort:
|
||||
this->result = creport::ResultInstructionAbort();
|
||||
m_result = creport::ResultInstructionAbort();
|
||||
break;
|
||||
case svc::DebugException_DataAbort:
|
||||
this->result = creport::ResultDataAbort();
|
||||
m_result = creport::ResultDataAbort();
|
||||
break;
|
||||
case svc::DebugException_AlignmentFault:
|
||||
this->result = creport::ResultAlignmentFault();
|
||||
m_result = creport::ResultAlignmentFault();
|
||||
break;
|
||||
case svc::DebugException_UserBreak:
|
||||
this->result = creport::ResultUserBreak();
|
||||
m_result = creport::ResultUserBreak();
|
||||
/* Try to parse out the user break result. */
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(this->result)), this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result));
|
||||
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(m_result)), m_debug_handle, d.info.exception.specific.user_break.address, sizeof(m_result));
|
||||
}
|
||||
break;
|
||||
case svc::DebugException_UndefinedSystemCall:
|
||||
this->result = creport::ResultUndefinedSystemCall();
|
||||
m_result = creport::ResultUndefinedSystemCall();
|
||||
break;
|
||||
case svc::DebugException_MemorySystemError:
|
||||
this->result = creport::ResultMemorySystemError();
|
||||
m_result = creport::ResultMemorySystemError();
|
||||
break;
|
||||
case svc::DebugException_DebuggerAttached:
|
||||
case svc::DebugException_BreakPoint:
|
||||
@@ -260,8 +260,8 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Save exception info. */
|
||||
this->exception_info = d.info.exception;
|
||||
this->crashed_thread_id = d.thread_id;
|
||||
m_exception_info = d.info.exception;
|
||||
m_crashed_thread_id = d.thread_id;
|
||||
}
|
||||
|
||||
void CrashReport::ProcessDyingMessage() {
|
||||
@@ -271,10 +271,10 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Validate address/size. */
|
||||
if (this->dying_message_address == 0 || this->dying_message_address & 0xFFF) {
|
||||
if (m_dying_message_address == 0 || m_dying_message_address & 0xFFF) {
|
||||
return;
|
||||
}
|
||||
if (this->dying_message_size > DyingMessageSizeMax) {
|
||||
if (m_dying_message_size > DyingMessageSizeMax) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -284,12 +284,12 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Verify that we have a dying message buffer. */
|
||||
if (this->dying_message == nullptr) {
|
||||
if (m_dying_message == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read the dying message. */
|
||||
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(this->dying_message), this->debug_handle, this->dying_message_address, this->dying_message_size);
|
||||
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(m_dying_message), m_debug_handle, m_dying_message_address, m_dying_message_size);
|
||||
}
|
||||
|
||||
void CrashReport::SaveReport(bool enable_screenshot) {
|
||||
@@ -307,7 +307,7 @@ namespace ams::creport {
|
||||
char file_path[fs::EntryNameLengthMax + 1];
|
||||
|
||||
/* Save crash report. */
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, this->process_info.program_id);
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, m_process_info.program_id);
|
||||
{
|
||||
ScopedFile file(file_path);
|
||||
if (file.IsOpen()) {
|
||||
@@ -316,25 +316,25 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Dump threads. */
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, this->process_info.program_id);
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, m_process_info.program_id);
|
||||
{
|
||||
ScopedFile file(file_path);
|
||||
if (file.IsOpen()) {
|
||||
this->thread_list->DumpBinary(file, this->crashed_thread.GetThreadId());
|
||||
m_thread_list->DumpBinary(file, m_crashed_thread.GetThreadId());
|
||||
}
|
||||
}
|
||||
|
||||
/* Finalize our heap. */
|
||||
std::destroy_at(this->module_list);
|
||||
std::destroy_at(this->thread_list);
|
||||
lmem::FreeToExpHeap(this->heap_handle, this->module_list);
|
||||
lmem::FreeToExpHeap(this->heap_handle, this->thread_list);
|
||||
if (this->dying_message != nullptr) {
|
||||
lmem::FreeToExpHeap(this->heap_handle, this->dying_message);
|
||||
std::destroy_at(m_module_list);
|
||||
std::destroy_at(m_thread_list);
|
||||
lmem::FreeToExpHeap(m_heap_handle, m_module_list);
|
||||
lmem::FreeToExpHeap(m_heap_handle, m_thread_list);
|
||||
if (m_dying_message != nullptr) {
|
||||
lmem::FreeToExpHeap(m_heap_handle, m_dying_message);
|
||||
}
|
||||
this->module_list = nullptr;
|
||||
this->thread_list = nullptr;
|
||||
this->dying_message = nullptr;
|
||||
m_module_list = nullptr;
|
||||
m_thread_list = nullptr;
|
||||
m_dying_message = nullptr;
|
||||
|
||||
/* Try to take a screenshot. */
|
||||
/* NOTE: Nintendo validates that enable_screenshot is true here, and validates that the application id is not in a blacklist. */
|
||||
@@ -345,11 +345,11 @@ namespace ams::creport {
|
||||
ON_SCOPE_EXIT { capsrv::FinalizeScreenShotControl(); };
|
||||
|
||||
u64 jpeg_size;
|
||||
if (R_SUCCEEDED(capsrv::CaptureJpegScreenshot(std::addressof(jpeg_size), this->heap_storage, sizeof(this->heap_storage), vi::LayerStack_ApplicationForDebug, TimeSpan::FromSeconds(10)))) {
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, this->process_info.program_id);
|
||||
if (R_SUCCEEDED(capsrv::CaptureJpegScreenshot(std::addressof(jpeg_size), m_heap_storage, sizeof(m_heap_storage), vi::LayerStack_ApplicationForDebug, TimeSpan::FromSeconds(10)))) {
|
||||
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, m_process_info.program_id);
|
||||
ScopedFile file(file_path);
|
||||
if (file.IsOpen()) {
|
||||
file.Write(this->heap_storage, jpeg_size);
|
||||
file.Write(m_heap_storage, jpeg_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,42 +360,42 @@ namespace ams::creport {
|
||||
void CrashReport::SaveToFile(ScopedFile &file) {
|
||||
file.WriteFormat("Atmosphère Crash Report (v1.6):\n");
|
||||
|
||||
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->result.GetValue(), this->result.GetModule(), this->result.GetDescription());
|
||||
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", m_result.GetValue(), m_result.GetModule(), m_result.GetDescription());
|
||||
|
||||
/* Process Info. */
|
||||
char name_buf[0x10] = {};
|
||||
static_assert(sizeof(name_buf) >= sizeof(this->process_info.name), "buffer overflow!");
|
||||
std::memcpy(name_buf, this->process_info.name, sizeof(this->process_info.name));
|
||||
static_assert(sizeof(name_buf) >= sizeof(m_process_info.name), "buffer overflow!");
|
||||
std::memcpy(name_buf, m_process_info.name, sizeof(m_process_info.name));
|
||||
file.WriteFormat("Process Info:\n");
|
||||
file.WriteFormat(" Process Name: %s\n", name_buf);
|
||||
file.WriteFormat(" Program ID: %016lx\n", this->process_info.program_id);
|
||||
file.WriteFormat(" Process ID: %016lx\n", this->process_info.process_id);
|
||||
file.WriteFormat(" Process Flags: %08x\n", this->process_info.flags);
|
||||
file.WriteFormat(" Program ID: %016lx\n", m_process_info.program_id);
|
||||
file.WriteFormat(" Process ID: %016lx\n", m_process_info.process_id);
|
||||
file.WriteFormat(" Process Flags: %08x\n", m_process_info.flags);
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
file.WriteFormat(" User Exception Address: %s\n", this->module_list->GetFormattedAddressString(this->process_info.user_exception_context_address));
|
||||
file.WriteFormat(" User Exception Address: %s\n", m_module_list->GetFormattedAddressString(m_process_info.user_exception_context_address));
|
||||
}
|
||||
|
||||
/* Exception Info. */
|
||||
file.WriteFormat("Exception Info:\n");
|
||||
file.WriteFormat(" Type: %s\n", GetDebugExceptionString(this->exception_info.type));
|
||||
file.WriteFormat(" Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.address));
|
||||
switch (this->exception_info.type) {
|
||||
file.WriteFormat(" Type: %s\n", GetDebugExceptionString(m_exception_info.type));
|
||||
file.WriteFormat(" Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.address));
|
||||
switch (m_exception_info.type) {
|
||||
case svc::DebugException_UndefinedInstruction:
|
||||
file.WriteFormat(" Opcode: %08x\n", this->exception_info.specific.undefined_instruction.insn);
|
||||
file.WriteFormat(" Opcode: %08x\n", m_exception_info.specific.undefined_instruction.insn);
|
||||
break;
|
||||
case svc::DebugException_DataAbort:
|
||||
case svc::DebugException_AlignmentFault:
|
||||
if (this->exception_info.specific.raw != this->exception_info.address) {
|
||||
file.WriteFormat(" Fault Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.specific.raw));
|
||||
if (m_exception_info.specific.raw != m_exception_info.address) {
|
||||
file.WriteFormat(" Fault Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.specific.raw));
|
||||
}
|
||||
break;
|
||||
case svc::DebugException_UndefinedSystemCall:
|
||||
file.WriteFormat(" Svc Id: 0x%02x\n", this->exception_info.specific.undefined_system_call.id);
|
||||
file.WriteFormat(" Svc Id: 0x%02x\n", m_exception_info.specific.undefined_system_call.id);
|
||||
break;
|
||||
case svc::DebugException_UserBreak:
|
||||
file.WriteFormat(" Break Reason: 0x%x\n", this->exception_info.specific.user_break.break_reason);
|
||||
file.WriteFormat(" Break Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.specific.user_break.address));
|
||||
file.WriteFormat(" Break Size: 0x%lx\n", this->exception_info.specific.user_break.size);
|
||||
file.WriteFormat(" Break Reason: 0x%x\n", m_exception_info.specific.user_break.break_reason);
|
||||
file.WriteFormat(" Break Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.specific.user_break.address));
|
||||
file.WriteFormat(" Break Size: 0x%lx\n", m_exception_info.specific.user_break.size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -403,23 +403,23 @@ namespace ams::creport {
|
||||
|
||||
/* Crashed Thread Info. */
|
||||
file.WriteFormat("Crashed Thread Info:\n");
|
||||
this->crashed_thread.SaveToFile(file);
|
||||
m_crashed_thread.SaveToFile(file);
|
||||
|
||||
/* Dying Message. */
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0 && this->dying_message_size != 0) {
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0 && m_dying_message_size != 0) {
|
||||
file.WriteFormat("Dying Message Info:\n");
|
||||
file.WriteFormat(" Address: 0x%s\n", this->module_list->GetFormattedAddressString(this->dying_message_address));
|
||||
file.WriteFormat(" Size: 0x%016lx\n", this->dying_message_size);
|
||||
file.DumpMemory( " Dying Message: ", this->dying_message, this->dying_message_size);
|
||||
file.WriteFormat(" Address: 0x%s\n", m_module_list->GetFormattedAddressString(m_dying_message_address));
|
||||
file.WriteFormat(" Size: 0x%016lx\n", m_dying_message_size);
|
||||
file.DumpMemory( " Dying Message: ", m_dying_message, m_dying_message_size);
|
||||
}
|
||||
|
||||
/* Module Info. */
|
||||
file.WriteFormat("Module Info:\n");
|
||||
this->module_list->SaveToFile(file);
|
||||
m_module_list->SaveToFile(file);
|
||||
|
||||
/* Thread Info. */
|
||||
file.WriteFormat("Thread Report:\n");
|
||||
this->thread_list->SaveToFile(file);
|
||||
m_thread_list->SaveToFile(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user