diff options
| author | 2022-06-01 20:46:10 -0400 | |
|---|---|---|
| committer | 2022-06-01 20:46:10 -0400 | |
| commit | 858f8ac6d9f39a1be95dc2f5e83c752b725136ad (patch) | |
| tree | 26d5733fe69193e76402bad78b1a3a8b791b6095 /src/core/debugger/debugger.cpp | |
| parent | Merge pull request #8400 from Docteh/fullscreen_glitch (diff) | |
| parent | core/debugger: Improved stepping mechanism and misc fixes (diff) | |
| download | yuzu-858f8ac6d9f39a1be95dc2f5e83c752b725136ad.tar.gz yuzu-858f8ac6d9f39a1be95dc2f5e83c752b725136ad.tar.xz yuzu-858f8ac6d9f39a1be95dc2f5e83c752b725136ad.zip | |
Merge pull request #8402 from liamwhite/better-step
core/debugger: Improved stepping mechanism and misc fixes
Diffstat (limited to 'src/core/debugger/debugger.cpp')
| -rw-r--r-- | src/core/debugger/debugger.cpp | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index dd3e330e6..68ab33e46 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 | |||
| 91 | private: | 88 | private: |
| 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 | ||
| 255 | bool Debugger::IsStepping() const { | ||
| 256 | return impl && impl->IsStepping(); | ||
| 257 | } | ||
| 258 | |||
| 259 | } // namespace Core | 268 | } // namespace Core |