From d65255acb8bc39a65b88048858a422538aa25937 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 25 Jun 2018 04:07:44 -0600 Subject: [PATCH] creport: Implement reading info about all threads. --- .../creport/source/creport_crash_report.cpp | 2 +- .../creport/source/creport_crash_report.hpp | 3 ++ .../creport/source/creport_thread_info.cpp | 48 +++++++++++++++++++ .../creport/source/creport_thread_info.hpp | 15 +++++- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 3bddef162..41cbf6564 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -12,7 +12,7 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) { ProcessExceptions(); if (kernelAbove500()) { /* TODO: Process Code Regions. */ - /* TODO: Process Threads. */ + thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit()); } if (IsApplication()) { diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index 99fd1acdf..812ec7568 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -37,6 +37,9 @@ class CrashReport { ExceptionInfo exception_info; ThreadInfo crashed_thread_info; + /* Extra Info. */ + ThreadList thread_list; + public: CrashReport() : debug_handle(INVALID_HANDLE), result((Result)CrashReportResult::IncompleteReport), process_info({}), dying_message_address(0), dying_message_size(0), dying_message{}, exception_info({}) { } diff --git a/stratosphere/creport/source/creport_thread_info.cpp b/stratosphere/creport/source/creport_thread_info.cpp index b429aa0d6..3ab24b23a 100644 --- a/stratosphere/creport/source/creport_thread_info.cpp +++ b/stratosphere/creport/source/creport_thread_info.cpp @@ -28,6 +28,9 @@ bool ThreadInfo::ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_ return true; } + /* Try to locate stack top/bottom. */ + TryGetStackInfo(debug_handle); + u64 cur_fp = this->context.fp; for (unsigned int i = 0; i < sizeof(this->stack_trace)/sizeof(u64); i++) { /* Validate the current frame. */ @@ -47,4 +50,49 @@ bool ThreadInfo::ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_ } return true; +} + +void ThreadInfo::TryGetStackInfo(Handle debug_handle) { + MemoryInfo mi; + u32 pi; + if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, this->context.sp))) { + return; + } + + /* Check if sp points into the stack. */ + if (mi.type == MemType_MappedMemory) { + this->stack_bottom = mi.addr; + this->stack_top = mi.addr + mi.size; + return; + } + + /* It's possible that sp is below the stack... */ + if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, mi.addr + mi.size))) { + return; + } + + if (mi.type == MemType_MappedMemory) { + this->stack_bottom = mi.addr; + this->stack_top = mi.addr + mi.size; + } +} + +void ThreadList::ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit) { + u32 thread_count; + u64 thread_ids[max_thread_count]; + + if (R_FAILED(svcGetThreadList(&thread_count, thread_ids, max_thread_count, debug_handle))) { + this->thread_count = 0; + return; + } + + if (thread_count > max_thread_count) { + thread_count = max_thread_count; + } + + for (unsigned int i = 0; i < thread_count; i++) { + if (this->thread_infos[this->thread_count].ReadFromProcess(debug_handle, thread_ids[this->thread_count], is_64_bit)) { + this->thread_count++; + } + } } \ No newline at end of file diff --git a/stratosphere/creport/source/creport_thread_info.hpp b/stratosphere/creport/source/creport_thread_info.hpp index b36f5cfb2..1c15c8642 100644 --- a/stratosphere/creport/source/creport_thread_info.hpp +++ b/stratosphere/creport/source/creport_thread_info.hpp @@ -42,4 +42,17 @@ class ThreadInfo { } bool ReadFromProcess(Handle debug_handle, u64 thread_id, bool is_64_bit); -}; \ No newline at end of file + private: + void TryGetStackInfo(Handle debug_handle); +}; + +class ThreadList { + private: + static const size_t max_thread_count = 0x60; + u32 thread_count; + ThreadInfo thread_infos[max_thread_count]; + public: + ThreadList() : thread_count(0), thread_infos({}) { } + + void ReadThreadsFromProcess(Handle debug_handle, bool is_64_bit); +};