summaryrefslogtreecommitdiff
path: root/src/core/debugger/debugger.cpp
diff options
context:
space:
mode:
authorGravatar Liam2022-05-31 14:37:37 -0400
committerGravatar Liam2022-06-01 02:15:15 -0400
commit989d4a7a41f449af0ea09e34bee331a3a3ac8170 (patch)
treedf24bd9d7e6942b939e3ea42d08c0d65006e539f /src/core/debugger/debugger.cpp
parentcore/debugger: Implement new GDB stub debugger (diff)
downloadyuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.tar.gz
yuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.tar.xz
yuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.zip
core/debugger: Improved stepping mechanism and misc fixes
Diffstat (limited to 'src/core/debugger/debugger.cpp')
-rw-r--r--src/core/debugger/debugger.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index 7a2012d3c..a73f2279d 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
4#include <mutex> 5#include <mutex>
5#include <thread> 6#include <thread>
6 7
@@ -84,31 +85,31 @@ public:
84 return active_thread; 85 return active_thread;
85 } 86 }
86 87
87 bool IsStepping() const {
88 return stepping;
89 }
90
91private: 88private:
92 void InitializeServer(u16 port) { 89 void InitializeServer(u16 port) {
93 using boost::asio::ip::tcp; 90 using boost::asio::ip::tcp;
94 91
95 LOG_INFO(Debug_GDBStub, "Starting server on port {}...", port); 92 LOG_INFO(Debug_GDBStub, "Starting server on port {}...", port);
96 93
97 // Initialize the listening socket and accept a new client.
98 tcp::endpoint endpoint{boost::asio::ip::address_v4::loopback(), port};
99 tcp::acceptor acceptor{io_context, endpoint};
100 client_socket = acceptor.accept();
101
102 // Run the connection thread. 94 // Run the connection thread.
103 connection_thread = std::jthread([&](std::stop_token stop_token) { 95 connection_thread = std::jthread([&, port](std::stop_token stop_token) {
104 try { 96 try {
97 // Initialize the listening socket and accept a new client.
98 tcp::endpoint endpoint{boost::asio::ip::address_v4::loopback(), port};
99 tcp::acceptor acceptor{io_context, endpoint};
100
101 acceptor.async_accept(client_socket, [](const auto&) {});
102 io_context.run_one();
103 io_context.restart();
104
105 if (stop_token.stop_requested()) {
106 return;
107 }
108
105 ThreadLoop(stop_token); 109 ThreadLoop(stop_token);
106 } catch (const std::exception& ex) { 110 } catch (const std::exception& ex) {
107 LOG_CRITICAL(Debug_GDBStub, "Stopping server: {}", ex.what()); 111 LOG_CRITICAL(Debug_GDBStub, "Stopping server: {}", ex.what());
108 } 112 }
109
110 client_socket.shutdown(client_socket.shutdown_both);
111 client_socket.close();
112 }); 113 });
113 } 114 }
114 115
@@ -129,8 +130,7 @@ private:
129 AllCoreStop(); 130 AllCoreStop();
130 131
131 // Set the active thread. 132 // Set the active thread.
132 active_thread = ThreadList()[0]; 133 UpdateActiveThread();
133 active_thread->Resume(Kernel::SuspendType::Debug);
134 134
135 // Set up the frontend. 135 // Set up the frontend.
136 frontend->Connected(); 136 frontend->Connected();
@@ -142,7 +142,7 @@ private:
142 142
143 void PipeData(std::span<const u8> data) { 143 void PipeData(std::span<const u8> data) {
144 AllCoreStop(); 144 AllCoreStop();
145 active_thread->Resume(Kernel::SuspendType::Debug); 145 UpdateActiveThread();
146 frontend->Stopped(active_thread); 146 frontend->Stopped(active_thread);
147 } 147 }
148 148
@@ -156,18 +156,22 @@ private:
156 stopped = true; 156 stopped = true;
157 } 157 }
158 AllCoreStop(); 158 AllCoreStop();
159 active_thread = ThreadList()[0]; 159 UpdateActiveThread();
160 active_thread->Resume(Kernel::SuspendType::Debug);
161 frontend->Stopped(active_thread); 160 frontend->Stopped(active_thread);
162 break; 161 break;
163 } 162 }
164 case DebuggerAction::Continue: 163 case DebuggerAction::Continue:
165 stepping = false; 164 active_thread->SetStepState(Kernel::StepState::NotStepping);
166 ResumeInactiveThreads(); 165 ResumeInactiveThreads();
167 AllCoreResume(); 166 AllCoreResume();
168 break; 167 break;
169 case DebuggerAction::StepThread: 168 case DebuggerAction::StepThreadUnlocked:
170 stepping = true; 169 active_thread->SetStepState(Kernel::StepState::StepPending);
170 ResumeInactiveThreads();
171 AllCoreResume();
172 break;
173 case DebuggerAction::StepThreadLocked:
174 active_thread->SetStepState(Kernel::StepState::StepPending);
171 SuspendInactiveThreads(); 175 SuspendInactiveThreads();
172 AllCoreResume(); 176 AllCoreResume();
173 break; 177 break;
@@ -212,10 +216,20 @@ private:
212 for (auto* thread : ThreadList()) { 216 for (auto* thread : ThreadList()) {
213 if (thread != active_thread) { 217 if (thread != active_thread) {
214 thread->Resume(Kernel::SuspendType::Debug); 218 thread->Resume(Kernel::SuspendType::Debug);
219 thread->SetStepState(Kernel::StepState::NotStepping);
215 } 220 }
216 } 221 }
217 } 222 }
218 223
224 void UpdateActiveThread() {
225 const auto& threads{ThreadList()};
226 if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) {
227 active_thread = threads[0];
228 }
229 active_thread->Resume(Kernel::SuspendType::Debug);
230 active_thread->SetStepState(Kernel::StepState::NotStepping);
231 }
232
219 const std::vector<Kernel::KThread*>& ThreadList() { 233 const std::vector<Kernel::KThread*>& ThreadList() {
220 return system.GlobalSchedulerContext().GetThreadList(); 234 return system.GlobalSchedulerContext().GetThreadList();
221 } 235 }
@@ -233,7 +247,6 @@ private:
233 247
234 Kernel::KThread* active_thread; 248 Kernel::KThread* active_thread;
235 bool stopped; 249 bool stopped;
236 bool stepping;
237 250
238 std::array<u8, 4096> client_data; 251 std::array<u8, 4096> client_data;
239}; 252};
@@ -252,8 +265,4 @@ bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) {
252 return impl && impl->NotifyThreadStopped(thread); 265 return impl && impl->NotifyThreadStopped(thread);
253} 266}
254 267
255bool Debugger::IsStepping() const {
256 return impl && impl->IsStepping();
257}
258
259} // namespace Core 268} // namespace Core