summaryrefslogtreecommitdiffstats
path: root/src/core/debugger/debugger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/debugger/debugger.cpp')
-rw-r--r--src/core/debugger/debugger.cpp76
1 files changed, 59 insertions, 17 deletions
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index 68ab33e46..edf991d71 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -20,15 +20,16 @@ template <typename Readable, typename Buffer, typename Callback>
static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) {
static_assert(std::is_trivial_v<Buffer>);
auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))};
- r.async_read_some(boost_buffer, [&](const boost::system::error_code& error, size_t bytes_read) {
- if (!error.failed()) {
- const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
- std::span<const u8> received_data{buffer_start, buffer_start + bytes_read};
- c(received_data);
- }
+ r.async_read_some(
+ boost_buffer, [&, c](const boost::system::error_code& error, size_t bytes_read) {
+ if (!error.failed()) {
+ const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
+ std::span<const u8> received_data{buffer_start, buffer_start + bytes_read};
+ c(received_data);
+ }
- AsyncReceiveInto(r, buffer, c);
- });
+ AsyncReceiveInto(r, buffer, c);
+ });
}
template <typename Readable, typename Buffer>
@@ -41,6 +42,16 @@ static std::span<const u8> ReceiveInto(Readable& r, Buffer& buffer) {
return received_data;
}
+enum class SignalType {
+ Stopped,
+ ShuttingDown,
+};
+
+struct SignalInfo {
+ SignalType type;
+ Kernel::KThread* thread;
+};
+
namespace Core {
class DebuggerImpl : public DebuggerBackend {
@@ -55,7 +66,7 @@ public:
ShutdownServer();
}
- bool NotifyThreadStopped(Kernel::KThread* thread) {
+ bool SignalDebugger(SignalInfo signal_info) {
std::scoped_lock lk{connection_lock};
if (stopped) {
@@ -63,9 +74,13 @@ public:
// It should be ignored.
return false;
}
+
+ // Set up the state.
stopped = true;
+ info = signal_info;
- signal_pipe.write_some(boost::asio::buffer(&thread, sizeof(thread)));
+ // Write a single byte into the pipe to wake up the debug interface.
+ boost::asio::write(signal_pipe, boost::asio::buffer(&stopped, sizeof(stopped)));
return true;
}
@@ -74,7 +89,7 @@ public:
}
void WriteToClient(std::span<const u8> data) override {
- client_socket.write_some(boost::asio::buffer(data.data(), data.size_bytes()));
+ boost::asio::write(client_socket, boost::asio::buffer(data.data(), data.size_bytes()));
}
void SetActiveThread(Kernel::KThread* thread) override {
@@ -95,7 +110,7 @@ private:
connection_thread = std::jthread([&, port](std::stop_token stop_token) {
try {
// Initialize the listening socket and accept a new client.
- tcp::endpoint endpoint{boost::asio::ip::address_v4::loopback(), port};
+ tcp::endpoint endpoint{boost::asio::ip::address_v4::any(), port};
tcp::acceptor acceptor{io_context, endpoint};
acceptor.async_accept(client_socket, [](const auto&) {});
@@ -123,7 +138,7 @@ private:
Common::SetCurrentThreadName("yuzu:Debugger");
// Set up the client signals for new data.
- AsyncReceiveInto(signal_pipe, active_thread, [&](auto d) { PipeData(d); });
+ AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); });
AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); });
// Stop the emulated CPU.
@@ -141,9 +156,28 @@ private:
}
void PipeData(std::span<const u8> data) {
- AllCoreStop();
- UpdateActiveThread();
- frontend->Stopped(active_thread);
+ switch (info.type) {
+ case SignalType::Stopped:
+ // Stop emulation.
+ AllCoreStop();
+
+ // Notify the client.
+ active_thread = info.thread;
+ UpdateActiveThread();
+ frontend->Stopped(active_thread);
+
+ break;
+ case SignalType::ShuttingDown:
+ frontend->ShuttingDown();
+
+ // Wait for emulation to shut down gracefully now.
+ suspend.reset();
+ signal_pipe.close();
+ client_socket.shutdown(boost::asio::socket_base::shutdown_both);
+ LOG_INFO(Debug_GDBStub, "Shut down server");
+
+ break;
+ }
}
void ClientData(std::span<const u8> data) {
@@ -245,7 +279,9 @@ private:
boost::asio::ip::tcp::socket client_socket;
std::optional<std::unique_lock<std::mutex>> suspend;
+ SignalInfo info;
Kernel::KThread* active_thread;
+ bool pipe_data;
bool stopped;
std::array<u8, 4096> client_data;
@@ -262,7 +298,13 @@ Debugger::Debugger(Core::System& system, u16 port) {
Debugger::~Debugger() = default;
bool Debugger::NotifyThreadStopped(Kernel::KThread* thread) {
- return impl && impl->NotifyThreadStopped(thread);
+ return impl && impl->SignalDebugger(SignalInfo{SignalType::Stopped, thread});
+}
+
+void Debugger::NotifyShutdown() {
+ if (impl) {
+ impl->SignalDebugger(SignalInfo{SignalType::ShuttingDown, nullptr});
+ }
}
} // namespace Core