summaryrefslogtreecommitdiffstats
path: root/src/core/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/debugger')
-rw-r--r--src/core/debugger/debugger.cpp24
-rw-r--r--src/core/debugger/gdbstub.cpp69
2 files changed, 56 insertions, 37 deletions
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index a1589fecb..0e270eb50 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -258,20 +258,20 @@ private:
Kernel::KScopedSchedulerLock sl{system.Kernel()};
// Put all threads to sleep on next scheduler round.
- for (auto* thread : ThreadList()) {
- thread->RequestSuspend(Kernel::SuspendType::Debug);
+ for (auto& thread : ThreadList()) {
+ thread.RequestSuspend(Kernel::SuspendType::Debug);
}
}
void ResumeEmulation(Kernel::KThread* except = nullptr) {
// Wake up all threads.
- for (auto* thread : ThreadList()) {
- if (thread == except) {
+ for (auto& thread : ThreadList()) {
+ if (std::addressof(thread) == except) {
continue;
}
- thread->SetStepState(Kernel::StepState::NotStepping);
- thread->Resume(Kernel::SuspendType::Debug);
+ thread.SetStepState(Kernel::StepState::NotStepping);
+ thread.Resume(Kernel::SuspendType::Debug);
}
}
@@ -283,13 +283,17 @@ private:
}
void UpdateActiveThread() {
- const auto& threads{ThreadList()};
- if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) {
- state->active_thread = threads.front();
+ auto& threads{ThreadList()};
+ for (auto& thread : threads) {
+ if (std::addressof(thread) == state->active_thread) {
+ // Thread is still alive, no need to update.
+ return;
+ }
}
+ state->active_thread = std::addressof(threads.front());
}
- const std::list<Kernel::KThread*>& ThreadList() {
+ Kernel::KProcess::ThreadList& ThreadList() {
return system.ApplicationProcess()->GetThreadList();
}
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index e55831f27..6f5f5156b 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <atomic>
+#include <codecvt>
+#include <locale>
#include <numeric>
#include <optional>
#include <thread>
@@ -12,6 +14,7 @@
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/settings.h"
+#include "common/string_util.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/debugger/gdbstub.h"
@@ -68,10 +71,16 @@ static std::string EscapeGDB(std::string_view data) {
}
static std::string EscapeXML(std::string_view data) {
+ std::u32string converted = U"[Encoding error]";
+ try {
+ converted = Common::UTF8ToUTF32(data);
+ } catch (std::range_error&) {
+ }
+
std::string escaped;
escaped.reserve(data.size());
- for (char c : data) {
+ for (char32_t c : converted) {
switch (c) {
case '&':
escaped += "&amp;";
@@ -86,7 +95,11 @@ static std::string EscapeXML(std::string_view data) {
escaped += "&gt;";
break;
default:
- escaped += c;
+ if (c > 0x7f) {
+ escaped += fmt::format("&#{};", static_cast<u32>(c));
+ } else {
+ escaped += static_cast<char>(c);
+ }
break;
}
}
@@ -96,7 +109,7 @@ static std::string EscapeXML(std::string_view data) {
GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_)
: DebuggerFrontend(backend_), system{system_} {
- if (system.ApplicationProcess()->Is64BitProcess()) {
+ if (system.ApplicationProcess()->Is64Bit()) {
arch = std::make_unique<GDBStubA64>();
} else {
arch = std::make_unique<GDBStubA32>();
@@ -433,10 +446,10 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
// See osdbg_thread_local_region.os.horizon.hpp and osdbg_thread_type.os.horizon.hpp
static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory,
- const Kernel::KThread* thread) {
+ const Kernel::KThread& thread) {
// Read thread type from TLS
- const VAddr tls_thread_type{memory.Read32(thread->GetTlsAddress() + 0x1fc)};
- const VAddr argument_thread_type{thread->GetArgument()};
+ const VAddr tls_thread_type{memory.Read32(thread.GetTlsAddress() + 0x1fc)};
+ const VAddr argument_thread_type{thread.GetArgument()};
if (argument_thread_type && tls_thread_type != argument_thread_type) {
// Probably not created by nnsdk, no name available.
@@ -464,10 +477,10 @@ static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory&
}
static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory,
- const Kernel::KThread* thread) {
+ const Kernel::KThread& thread) {
// Read thread type from TLS
- const VAddr tls_thread_type{memory.Read64(thread->GetTlsAddress() + 0x1f8)};
- const VAddr argument_thread_type{thread->GetArgument()};
+ const VAddr tls_thread_type{memory.Read64(thread.GetTlsAddress() + 0x1f8)};
+ const VAddr argument_thread_type{thread.GetArgument()};
if (argument_thread_type && tls_thread_type != argument_thread_type) {
// Probably not created by nnsdk, no name available.
@@ -495,16 +508,16 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
}
static std::optional<std::string> GetThreadName(Core::System& system,
- const Kernel::KThread* thread) {
- if (system.ApplicationProcess()->Is64BitProcess()) {
+ const Kernel::KThread& thread) {
+ if (system.ApplicationProcess()->Is64Bit()) {
return GetNameFromThreadType64(system.ApplicationMemory(), thread);
} else {
return GetNameFromThreadType32(system.ApplicationMemory(), thread);
}
}
-static std::string_view GetThreadWaitReason(const Kernel::KThread* thread) {
- switch (thread->GetWaitReasonForDebugging()) {
+static std::string_view GetThreadWaitReason(const Kernel::KThread& thread) {
+ switch (thread.GetWaitReasonForDebugging()) {
case Kernel::ThreadWaitReasonForDebugging::Sleep:
return "Sleep";
case Kernel::ThreadWaitReasonForDebugging::IPC:
@@ -522,8 +535,8 @@ static std::string_view GetThreadWaitReason(const Kernel::KThread* thread) {
}
}
-static std::string GetThreadState(const Kernel::KThread* thread) {
- switch (thread->GetState()) {
+static std::string GetThreadState(const Kernel::KThread& thread) {
+ switch (thread.GetState()) {
case Kernel::ThreadState::Initialized:
return "Initialized";
case Kernel::ThreadState::Waiting:
@@ -591,7 +604,7 @@ void GDBStub::HandleQuery(std::string_view command) {
const auto& threads = system.ApplicationProcess()->GetThreadList();
std::vector<std::string> thread_ids;
for (const auto& thread : threads) {
- thread_ids.push_back(fmt::format("{:x}", thread->GetThreadId()));
+ thread_ids.push_back(fmt::format("{:x}", thread.GetThreadId()));
}
SendReply(fmt::format("m{}", fmt::join(thread_ids, ",")));
} else if (command.starts_with("sThreadInfo")) {
@@ -603,14 +616,14 @@ void GDBStub::HandleQuery(std::string_view command) {
buffer += "<threads>";
const auto& threads = system.ApplicationProcess()->GetThreadList();
- for (const auto* thread : threads) {
+ for (const auto& thread : threads) {
auto thread_name{GetThreadName(system, thread)};
if (!thread_name) {
- thread_name = fmt::format("Thread {:d}", thread->GetThreadId());
+ thread_name = fmt::format("Thread {:d}", thread.GetThreadId());
}
buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="{}">{}</thread>)",
- thread->GetThreadId(), thread->GetActiveCore(),
+ thread.GetThreadId(), thread.GetActiveCore(),
EscapeXML(*thread_name), GetThreadState(thread));
}
@@ -809,11 +822,13 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
const char i = True(mem_info.attribute & MemoryAttribute::IpcLocked) ? 'I' : '-';
const char d = True(mem_info.attribute & MemoryAttribute::DeviceShared) ? 'D' : '-';
const char u = True(mem_info.attribute & MemoryAttribute::Uncached) ? 'U' : '-';
+ const char p =
+ True(mem_info.attribute & MemoryAttribute::PermissionLocked) ? 'P' : '-';
- reply +=
- fmt::format(" {:#012x} - {:#012x} {} {} {}{}{}{} [{}, {}]\n",
- mem_info.base_address, mem_info.base_address + mem_info.size - 1,
- perm, state, l, i, d, u, mem_info.ipc_count, mem_info.device_count);
+ reply += fmt::format(" {:#012x} - {:#012x} {} {} {}{}{}{}{} [{}, {}]\n",
+ mem_info.base_address,
+ mem_info.base_address + mem_info.size - 1, perm, state, l, i,
+ d, u, p, mem_info.ipc_count, mem_info.device_count);
}
const uintptr_t next_address = mem_info.base_address + mem_info.size;
@@ -835,10 +850,10 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
}
Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) {
- const auto& threads{system.ApplicationProcess()->GetThreadList()};
- for (auto* thread : threads) {
- if (thread->GetThreadId() == thread_id) {
- return thread;
+ auto& threads{system.ApplicationProcess()->GetThreadList()};
+ for (auto& thread : threads) {
+ if (thread.GetThreadId() == thread_id) {
+ return std::addressof(thread);
}
}