From 0a8d6eec910099844f3af8520b7554274180fbe2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 4 Aug 2015 18:39:51 -0700 Subject: [PATCH] Simplifying debug stuff, as I'm not going to bother with gdb. --- .../xdp/xdp_client.cc => debug_client.cc} | 33 +- .../xdp/xdp_client.h => debug_client.h} | 16 +- .../xdp/xdp_server.cc => debug_server.cc} | 44 ++- src/xenia/debug/debug_server.h | 56 ++- src/xenia/debug/debugger.cc | 28 +- src/xenia/debug/premake5.lua | 3 - .../debug/server/gdb/gdb_command_processor.cc | 319 ------------------ .../debug/server/gdb/gdb_command_processor.h | 59 ---- src/xenia/debug/server/gdb/gdb_server.cc | 130 ------- src/xenia/debug/server/gdb/gdb_server.h | 55 --- .../debug/server/mi/mi_command_processor.cc | 232 ------------- .../debug/server/mi/mi_command_processor.h | 57 ---- src/xenia/debug/server/mi/mi_protocol.h | 46 --- src/xenia/debug/server/mi/mi_reader.cc | 22 -- src/xenia/debug/server/mi/mi_reader.h | 31 -- src/xenia/debug/server/mi/mi_server.cc | 132 -------- src/xenia/debug/server/mi/mi_server.h | 55 --- src/xenia/debug/server/mi/mi_writer.cc | 137 -------- src/xenia/debug/server/mi/mi_writer.h | 101 ------ src/xenia/debug/server/xdp/xdp_server.h | 76 ----- src/xenia/debug/ui/application.h | 6 +- src/xenia/debug/ui/main_window.cc | 2 - src/xenia/debug/ui/main_window.h | 2 +- src/xenia/debug/ui/model/system.cc | 12 +- src/xenia/debug/ui/model/system.h | 12 +- src/xenia/debug/ui/view.h | 6 +- src/xenia/debug/ui/views/cpu/cpu_view.cc | 4 +- src/xenia/debug/ui/views/cpu/cpu_view.h | 2 +- src/xenia/debug/ui/views/gpu/gpu_view.cc | 2 +- src/xenia/debug/ui/views/gpu/gpu_view.h | 2 +- 30 files changed, 115 insertions(+), 1567 deletions(-) rename src/xenia/debug/{client/xdp/xdp_client.cc => debug_client.cc} (90%) rename src/xenia/debug/{client/xdp/xdp_client.h => debug_client.h} (89%) rename src/xenia/debug/{server/xdp/xdp_server.cc => debug_server.cc} (90%) delete mode 100644 src/xenia/debug/server/gdb/gdb_command_processor.cc delete mode 100644 src/xenia/debug/server/gdb/gdb_command_processor.h delete mode 100644 src/xenia/debug/server/gdb/gdb_server.cc delete mode 100644 src/xenia/debug/server/gdb/gdb_server.h delete mode 100644 src/xenia/debug/server/mi/mi_command_processor.cc delete mode 100644 src/xenia/debug/server/mi/mi_command_processor.h delete mode 100644 src/xenia/debug/server/mi/mi_protocol.h delete mode 100644 src/xenia/debug/server/mi/mi_reader.cc delete mode 100644 src/xenia/debug/server/mi/mi_reader.h delete mode 100644 src/xenia/debug/server/mi/mi_server.cc delete mode 100644 src/xenia/debug/server/mi/mi_server.h delete mode 100644 src/xenia/debug/server/mi/mi_writer.cc delete mode 100644 src/xenia/debug/server/mi/mi_writer.h delete mode 100644 src/xenia/debug/server/xdp/xdp_server.h diff --git a/src/xenia/debug/client/xdp/xdp_client.cc b/src/xenia/debug/debug_client.cc similarity index 90% rename from src/xenia/debug/client/xdp/xdp_client.cc rename to src/xenia/debug/debug_client.cc index 57a292661..22f3e12b3 100644 --- a/src/xenia/debug/client/xdp/xdp_client.cc +++ b/src/xenia/debug/debug_client.cc @@ -7,33 +7,30 @@ ****************************************************************************** */ -#include "xenia/debug/client/xdp/xdp_client.h" +#include "xenia/debug/debug_client.h" #include "xenia/base/logging.h" -#include "xenia/debug/debugger.h" namespace xe { namespace debug { -namespace client { -namespace xdp { using namespace xe::debug::proto; constexpr size_t kReceiveBufferSize = 1 * 1024 * 1024; constexpr size_t kTransmitBufferSize = 1 * 1024 * 1024; -XdpClient::XdpClient() +DebugClient::DebugClient() : packet_reader_(kReceiveBufferSize), packet_writer_(kTransmitBufferSize) { receive_buffer_.resize(kReceiveBufferSize); } -XdpClient::~XdpClient() { +DebugClient::~DebugClient() { socket_->Close(); xe::threading::Wait(thread_.get(), true); thread_.reset(); } -bool XdpClient::Connect(std::string hostname, uint16_t port) { +bool DebugClient::Connect(std::string hostname, uint16_t port) { socket_ = Socket::Connect(std::move(hostname), port); if (!socket_) { XELOGE("Unable to connect to remote host"); @@ -69,7 +66,7 @@ bool XdpClient::Connect(std::string hostname, uint16_t port) { return true; } -bool XdpClient::HandleSocketEvent() { +bool DebugClient::HandleSocketEvent() { if (!socket_->is_connected()) { // Known-disconnected. return false; @@ -95,7 +92,7 @@ bool XdpClient::HandleSocketEvent() { return true; } -bool XdpClient::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { +bool DebugClient::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { // Grow and append the bytes to the receive buffer. packet_reader_.AppendBuffer(buffer, buffer_length); @@ -121,7 +118,7 @@ bool XdpClient::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { return true; } -bool XdpClient::ProcessPacket(const proto::Packet* packet) { +bool DebugClient::ProcessPacket(const proto::Packet* packet) { // Hold lock during processing. std::lock_guard lock(mutex_); @@ -167,7 +164,7 @@ bool XdpClient::ProcessPacket(const proto::Packet* packet) { return true; } -void XdpClient::Flush() { +void DebugClient::Flush() { std::lock_guard lock(mutex_); if (!packet_writer_.buffer_offset()) { return; @@ -176,7 +173,7 @@ void XdpClient::Flush() { packet_writer_.Reset(); } -void XdpClient::Continue() { +void DebugClient::Continue() { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kExecutionRequest); auto body = packet_writer_.Append(); @@ -185,7 +182,7 @@ void XdpClient::Continue() { Flush(); } -void XdpClient::StepOne(uint32_t thread_id) { +void DebugClient::StepOne(uint32_t thread_id) { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kExecutionRequest); auto body = packet_writer_.Append(); @@ -196,7 +193,7 @@ void XdpClient::StepOne(uint32_t thread_id) { Flush(); } -void XdpClient::StepTo(uint32_t thread_id, uint32_t target_pc) { +void DebugClient::StepTo(uint32_t thread_id, uint32_t target_pc) { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kExecutionRequest); auto body = packet_writer_.Append(); @@ -208,7 +205,7 @@ void XdpClient::StepTo(uint32_t thread_id, uint32_t target_pc) { Flush(); } -void XdpClient::Interrupt() { +void DebugClient::Interrupt() { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kExecutionRequest); auto body = packet_writer_.Append(); @@ -217,7 +214,7 @@ void XdpClient::Interrupt() { Flush(); } -void XdpClient::Exit() { +void DebugClient::Exit() { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kExecutionRequest); auto body = packet_writer_.Append(); @@ -226,7 +223,7 @@ void XdpClient::Exit() { Flush(); } -void XdpClient::BeginUpdateAllState() { +void DebugClient::BeginUpdateAllState() { std::lock_guard lock(mutex_); packet_writer_.Begin(PacketType::kModuleListRequest); @@ -237,7 +234,5 @@ void XdpClient::BeginUpdateAllState() { Flush(); } -} // namespace xdp -} // namespace client } // namespace debug } // namespace xe diff --git a/src/xenia/debug/client/xdp/xdp_client.h b/src/xenia/debug/debug_client.h similarity index 89% rename from src/xenia/debug/client/xdp/xdp_client.h rename to src/xenia/debug/debug_client.h index 9d3cbc65a..88d8cd62a 100644 --- a/src/xenia/debug/client/xdp/xdp_client.h +++ b/src/xenia/debug/debug_client.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef XENIA_DEBUG_CLIENT_XDP_XDP_CLIENT_H_ -#define XENIA_DEBUG_CLIENT_XDP_XDP_CLIENT_H_ +#ifndef XENIA_DEBUG_DEBUG_CLIENT_H_ +#define XENIA_DEBUG_DEBUG_CLIENT_H_ #include #include @@ -21,8 +21,6 @@ namespace xe { namespace debug { -namespace client { -namespace xdp { using proto::ModuleListEntry; using proto::ThreadListEntry; @@ -45,10 +43,10 @@ class ClientListener { std::vector entries) = 0; }; -class XdpClient { +class DebugClient { public: - XdpClient(); - ~XdpClient(); + DebugClient(); + ~DebugClient(); Socket* socket() const { return socket_.get(); } void set_listener(ClientListener* listener) { listener_ = listener; } @@ -84,9 +82,7 @@ class XdpClient { ExecutionState execution_state_ = ExecutionState::kStopped; }; -} // namespace xdp -} // namespace client } // namespace debug } // namespace xe -#endif // XENIA_DEBUG_CLIENT_XDP_XDP_CLIENT_H_ +#endif // XENIA_DEBUG_DEBUG_CLIENT_H_ diff --git a/src/xenia/debug/server/xdp/xdp_server.cc b/src/xenia/debug/debug_server.cc similarity index 90% rename from src/xenia/debug/server/xdp/xdp_server.cc rename to src/xenia/debug/debug_server.cc index f499fa110..607c06eaf 100644 --- a/src/xenia/debug/server/xdp/xdp_server.cc +++ b/src/xenia/debug/debug_server.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include "xenia/debug/server/xdp/xdp_server.h" +#include "xenia/debug/debug_server.h" #include @@ -18,12 +18,10 @@ #include "xenia/kernel/objects/xmodule.h" #include "xenia/kernel/objects/xthread.h" -DEFINE_int32(xdp_server_port, 9002, "Debugger XDP server TCP port."); +DEFINE_int32(debug_server_port, 9002, "Debugger XDP server TCP port."); namespace xe { namespace debug { -namespace server { -namespace xdp { using namespace xe::debug::proto; using namespace xe::kernel; @@ -32,19 +30,19 @@ constexpr size_t kReceiveBufferSize = 32 * 1024; constexpr size_t kReadBufferSize = 1 * 1024 * 1024; constexpr size_t kWriteBufferSize = 1 * 1024 * 1024; -XdpServer::XdpServer(Debugger* debugger) - : DebugServer(debugger), +DebugServer::DebugServer(Debugger* debugger) + : debugger_(debugger), packet_reader_(kReadBufferSize), packet_writer_(kWriteBufferSize) { receive_buffer_.resize(kReceiveBufferSize); } -XdpServer::~XdpServer() = default; +DebugServer::~DebugServer() = default; -bool XdpServer::Initialize() { +bool DebugServer::Initialize() { post_event_ = xe::threading::Event::CreateAutoResetEvent(false); - socket_server_ = SocketServer::Create(uint16_t(FLAGS_xdp_server_port), + socket_server_ = SocketServer::Create(uint16_t(FLAGS_debug_server_port), [this](std::unique_ptr client) { AcceptClient(std::move(client)); }); @@ -56,7 +54,7 @@ bool XdpServer::Initialize() { return true; } -void XdpServer::PostSynchronous(std::function fn) { +void DebugServer::PostSynchronous(std::function fn) { xe::threading::Fence fence; { std::lock_guard lock(post_mutex_); @@ -69,7 +67,7 @@ void XdpServer::PostSynchronous(std::function fn) { fence.Wait(); } -void XdpServer::AcceptClient(std::unique_ptr client) { +void DebugServer::AcceptClient(std::unique_ptr client) { // If we have an existing client, kill it and join its thread. if (client_) { // TODO(benvanik): XDP say goodbye? @@ -148,7 +146,7 @@ void XdpServer::AcceptClient(std::unique_ptr client) { }); } -bool XdpServer::HandleClientEvent() { +bool DebugServer::HandleClientEvent() { if (!client_->is_connected()) { // Known-disconnected. return false; @@ -173,7 +171,7 @@ bool XdpServer::HandleClientEvent() { return true; } -bool XdpServer::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { +bool DebugServer::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { // Grow and append the bytes to the receive buffer. packet_reader_.AppendBuffer(buffer, buffer_length); @@ -200,7 +198,7 @@ bool XdpServer::ProcessBuffer(const uint8_t* buffer, size_t buffer_length) { return true; } -bool XdpServer::ProcessPacket(const proto::Packet* packet) { +bool DebugServer::ProcessPacket(const proto::Packet* packet) { auto emulator = debugger()->emulator(); auto kernel_state = emulator->kernel_state(); auto object_table = kernel_state->object_table(); @@ -292,7 +290,7 @@ bool XdpServer::ProcessPacket(const proto::Packet* packet) { return true; } -void XdpServer::OnExecutionContinued() { +void DebugServer::OnExecutionContinued() { packet_writer_.Begin(PacketType::kExecutionNotification); auto body = packet_writer_.Append(); body->current_state = ExecutionNotification::State::kRunning; @@ -300,7 +298,7 @@ void XdpServer::OnExecutionContinued() { Flush(); } -void XdpServer::OnExecutionInterrupted() { +void DebugServer::OnExecutionInterrupted() { packet_writer_.Begin(PacketType::kExecutionNotification); auto body = packet_writer_.Append(); body->current_state = ExecutionNotification::State::kStopped; @@ -309,7 +307,7 @@ void XdpServer::OnExecutionInterrupted() { Flush(); } -void XdpServer::Flush() { +void DebugServer::Flush() { if (!packet_writer_.buffer_offset()) { return; } @@ -317,7 +315,7 @@ void XdpServer::Flush() { packet_writer_.Reset(); } -void XdpServer::SendSuccess(proto::request_id_t request_id) { +void DebugServer::SendSuccess(proto::request_id_t request_id) { packet_writer_.Begin(PacketType::kGenericResponse, request_id); auto body = packet_writer_.Append(); body->code = GenericResponse::Code::kSuccess; @@ -325,8 +323,8 @@ void XdpServer::SendSuccess(proto::request_id_t request_id) { Flush(); } -void XdpServer::SendError(proto::request_id_t request_id, - const char* error_message) { +void DebugServer::SendError(proto::request_id_t request_id, + const char* error_message) { packet_writer_.Begin(PacketType::kGenericResponse, request_id); auto body = packet_writer_.Append(); body->code = GenericResponse::Code::kError; @@ -335,8 +333,8 @@ void XdpServer::SendError(proto::request_id_t request_id, Flush(); } -void XdpServer::SendError(proto::request_id_t request_id, - const std::string& error_message) { +void DebugServer::SendError(proto::request_id_t request_id, + const std::string& error_message) { packet_writer_.Begin(PacketType::kGenericResponse, request_id); auto body = packet_writer_.Append(); body->code = GenericResponse::Code::kError; @@ -345,7 +343,5 @@ void XdpServer::SendError(proto::request_id_t request_id, Flush(); } -} // namespace xdp -} // namespace server } // namespace debug } // namespace xe diff --git a/src/xenia/debug/debug_server.h b/src/xenia/debug/debug_server.h index ac61d7337..dccf1cc01 100644 --- a/src/xenia/debug/debug_server.h +++ b/src/xenia/debug/debug_server.h @@ -11,10 +11,18 @@ #define XENIA_DEBUG_DEBUG_SERVER_H_ #include +#include +#include +#include +#include "xenia/base/socket.h" +#include "xenia/base/threading.h" #include "xenia/cpu/function.h" #include "xenia/cpu/processor.h" #include "xenia/debug/breakpoint.h" +#include "xenia/debug/proto/packet_reader.h" +#include "xenia/debug/proto/packet_writer.h" +#include "xenia/debug/proto/xdp_protocol.h" namespace xe { namespace debug { @@ -23,27 +31,53 @@ class Debugger; class DebugServer { public: - virtual ~DebugServer() = default; + DebugServer(Debugger* debugger); + ~DebugServer(); Debugger* debugger() const { return debugger_; } + Socket* client() const { return client_.get(); } - virtual bool Initialize() = 0; + bool Initialize(); - virtual void PostSynchronous(std::function fn) = 0; + void PostSynchronous(std::function fn); // TODO(benvanik): better thread type (XThread?) - // virtual void OnThreadCreated(ThreadState* thread_state) = 0; - // virtual void OnThreadDestroyed(ThreadState* thread_state) = 0; + // void OnThreadCreated(ThreadState* thread_state); + // void OnThreadDestroyed(ThreadState* thread_state); - virtual void OnExecutionContinued() {} - virtual void OnExecutionInterrupted() {} - /*virtual void OnBreakpointHit(xe::cpu::ThreadState* thread_state, - Breakpoint* breakpoint) = 0;*/ + void OnExecutionContinued(); + void OnExecutionInterrupted(); + /*void OnBreakpointHit(xe::cpu::ThreadState* thread_state, + Breakpoint* breakpoint);*/ - protected: - DebugServer(Debugger* debugger) : debugger_(debugger) {} + private: + void AcceptClient(std::unique_ptr client); + bool HandleClientEvent(); + + bool ProcessBuffer(const uint8_t* buffer, size_t buffer_length); + bool ProcessPacket(const proto::Packet* packet); + + void Flush(); + void SendSuccess(proto::request_id_t request_id); + void SendError(proto::request_id_t request_id, + const char* error_message = nullptr); + void SendError(proto::request_id_t request_id, + const std::string& error_message); Debugger* debugger_ = nullptr; + + std::unique_ptr socket_server_; + + std::unique_ptr client_; + std::unique_ptr client_thread_; + + std::mutex post_mutex_; + std::unique_ptr post_event_; + std::list> post_queue_; + + std::vector receive_buffer_; + proto::PacketReader packet_reader_; + proto::PacketWriter packet_writer_; }; } // namespace debug diff --git a/src/xenia/debug/debugger.cc b/src/xenia/debug/debugger.cc index 8fda12747..4a5dcc29f 100644 --- a/src/xenia/debug/debugger.cc +++ b/src/xenia/debug/debugger.cc @@ -21,9 +21,7 @@ #include "xenia/cpu/function.h" #include "xenia/cpu/processor.h" #include "xenia/cpu/stack_walker.h" -#include "xenia/debug/server/gdb/gdb_server.h" -#include "xenia/debug/server/mi/mi_server.h" -#include "xenia/debug/server/xdp/xdp_server.h" +#include "xenia/debug/debug_server.h" #include "xenia/emulator.h" #include "xenia/kernel/objects/xkernel_module.h" #include "xenia/kernel/objects/xmodule.h" @@ -43,8 +41,6 @@ DEFINE_bool(wait_for_debugger, false, "Waits for a debugger to attach before starting the game."); DEFINE_bool(exit_with_debugger, true, "Exit whe the debugger disconnects."); -DEFINE_string(debug_server, "xdp", "Debug server protocol [gdb, mi, xdp]."); - namespace xe { namespace debug { @@ -91,24 +87,10 @@ bool Debugger::StartSession() { functions_trace_file_ = ChunkedMappedMemoryWriter::Open( functions_trace_path_, 32 * 1024 * 1024, true); - if (FLAGS_debug_server == "gdb") { - server_ = std::make_unique(this); - if (!server_->Initialize()) { - XELOGE("Unable to initialize GDB debug server"); - return false; - } - } else if (FLAGS_debug_server == "gdb") { - server_ = std::make_unique(this); - if (!server_->Initialize()) { - XELOGE("Unable to initialize MI debug server"); - return false; - } - } else { - server_ = std::make_unique(this); - if (!server_->Initialize()) { - XELOGE("Unable to initialize XDP debug server"); - return false; - } + server_ = std::make_unique(this); + if (!server_->Initialize()) { + XELOGE("Unable to initialize XDP debug server"); + return false; } return true; diff --git a/src/xenia/debug/premake5.lua b/src/xenia/debug/premake5.lua index 7fd45380b..0a2e8da88 100644 --- a/src/xenia/debug/premake5.lua +++ b/src/xenia/debug/premake5.lua @@ -13,9 +13,6 @@ project("xenia-debug") defines({ }) includedirs({ - project_root.."/third_party/flatbuffers/include" }) local_platform_files() - recursive_platform_files("client") recursive_platform_files("proto") - recursive_platform_files("server") diff --git a/src/xenia/debug/server/gdb/gdb_command_processor.cc b/src/xenia/debug/server/gdb/gdb_command_processor.cc deleted file mode 100644 index 1fe486f36..000000000 --- a/src/xenia/debug/server/gdb/gdb_command_processor.cc +++ /dev/null @@ -1,319 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/gdb/gdb_command_processor.h" - -#include "xenia/base/logging.h" -#include "xenia/base/string_buffer.h" -#include "xenia/debug/server/gdb/gdb_server.h" - -namespace xe { -namespace debug { -namespace server { -namespace gdb { - -constexpr size_t kReceiveBufferSize = 1 * 1024 * 1024; -constexpr size_t kTransmitBufferSize = 1 * 1024 * 1024; - -GdbCommandProcessor::GdbCommandProcessor(GdbServer* server, Debugger* debugger) - : server_(server), debugger_(debugger) { - receive_buffer_.resize(kReceiveBufferSize); - transmit_buffer_.resize(kTransmitBufferSize); -} - -bool GdbCommandProcessor::ProcessBuffer(const uint8_t* buffer, - size_t buffer_length) { - // Grow and append the bytes to the receive buffer. - while (receive_offset_ + buffer_length > receive_buffer_.capacity()) { - receive_buffer_.resize(receive_buffer_.size() * 2); - } - std::memcpy(receive_buffer_.data() + receive_offset_, buffer, buffer_length); - receive_offset_ += buffer_length; - - // While there are bytes pending in the buffer we scan through looking for end - // markers. When we find one, we emit the packet and move on. - size_t process_offset = 0; - while (process_offset < receive_offset_) { - // Look for an end marker. - size_t end_offset = -1; - size_t buffer_end_offset = -1; - for (size_t i = process_offset; i < receive_offset_; ++i) { - if (receive_buffer_[i] == '#') { - end_offset = i - 1; - buffer_end_offset = i + 2; - break; - } - } - if (end_offset == -1) { - // No end marker found - break out for now. - break; - } - - // Emit packet. - if (!ProcessPacket((const char*)(receive_buffer_.data() + process_offset), - end_offset - process_offset)) { - // Failed to process line. - std::string line(receive_buffer_.data() + process_offset, - receive_buffer_.data() + end_offset); - XELOGE("Failed to process incoming GDB line: %s", line.c_str()); - return false; - } - process_offset = buffer_end_offset + 1; - } - - // If we have leftover unprocessed bytes move them to the front of the buffer. - if (process_offset < receive_offset_) { - size_t remaining_bytes = receive_offset_ - process_offset; - std::memmove(receive_buffer_.data(), - receive_buffer_.data() + process_offset, remaining_bytes); - receive_offset_ = remaining_bytes; - } else { - receive_offset_ = 0; - } - - return true; -} - -bool GdbCommandProcessor::ProcessPacket(const char* buffer, - size_t buffer_length) { - // There may be any number of leading +'s or -'s. - size_t offset = 0; - for (; offset < buffer_length; ++offset) { - if (buffer[offset] == '$') { - // Command start. - ++offset; - break; - } else if (buffer[offset] == '+') { - // Ack. - } else if (buffer[offset] == '-') { - // No good - means transmission error. - XELOGE("GDB client remorted transmission error"); - return false; - } - } - - std::string line((const char*)(buffer + offset), buffer_length - 1); - XELOGI("GDB -> %s", line.c_str()); - - // Immediately send ACK. - if (!no_ack_mode_) { - server_->client()->Send("+", 1); - } - - const char* buffer_ptr = buffer + offset; - bool handled = false; - switch (buffer[offset]) { - case '!': - // Enable extended mode. - SendResponse("OK"); - handled = true; - break; - case 'v': - // Verbose packets. - if (std::strstr(buffer_ptr, "vRun") == buffer_ptr) { - SendResponse("S05"); - handled = true; - } else if (std::strstr(buffer_ptr, "vCont") == buffer_ptr) { - SendResponse("S05"); - handled = true; - } - break; - case 'q': - // Query packets. - switch (buffer_ptr[1]) { - case 'C': - // Get current thread ID. - SendResponse("QC01"); - handled = true; - break; - case 'R': - // Command. - SendResponse("OK"); - handled = true; - break; - default: - if (std::strstr(buffer_ptr, "qSupported") == buffer_ptr) { - // Get/set feature support. - handled = Process_qSupported(line); - } else if (std::strstr(buffer_ptr, "qAttached") == buffer_ptr) { - // Check attach mode; 0 = new process, 1 = existing process. - SendResponse("0"); - handled = true; - } else if (std::strstr(buffer_ptr, "qfThreadInfo") == buffer_ptr) { - // Start of thread list request. - SendResponse("m01"); - handled = true; - } else if (std::strstr(buffer_ptr, "qsThreadInfo") == buffer_ptr) { - // Continuation of thread list request. - SendResponse("l"); // l = last. - handled = true; - } - break; - } - break; - case 'Q': - // Set packets. - switch (buffer_ptr[1]) { - default: - if (std::strstr(buffer_ptr, "QStartNoAckMode") == buffer_ptr) { - no_ack_mode_ = true; - SendResponse("OK"); - handled = true; - } - break; - } - break; - case 'H': - // Set thread for subsequent operations. - SendResponse("OK"); - handled = true; - break; - case 'g': - // Read all registers. - handled = ProcessReadRegisters(line); - break; - case 'G': - // Write all registers. - handled = true; - break; - case 'p': - // Read register. - handled = true; - break; - case 'P': - // Write register. - handled = true; - break; - case 'm': - // Read memory. - handled = true; - break; - case 'M': - // Write memory. - handled = true; - break; - case 'Z': - // Insert breakpoint. - handled = true; - break; - case 'z': - // Remove breakpoint. - handled = true; - break; - case '?': - // Query halt reason. - SendResponse("S05"); - handled = true; - break; - case 'c': - // Continue (vCont should be used instead). - // NOTE: reply is sent on halt, not right now. - SendResponse("S05"); - handled = true; - break; - case 's': - // Single step. - // NOTE: reply is sent on halt, not right now. - SendResponse("S05"); - handled = true; - break; - } - if (!handled) { - XELOGE("Unknown GDB packet: %s", buffer_ptr); - SendResponse(""); - } - return true; -} - -void GdbCommandProcessor::SendResponse(const char* value, size_t length) { - XELOGI("GDB <- %s", value); - uint8_t checksum = 0; - for (size_t i = 0; i < length; ++i) { - uint8_t c = uint8_t(value[i]); - if (!c) { - break; - } - checksum += c; - } - char crc[4]; - sprintf(crc, "#%.2X", checksum); - std::pair buffers[] = { - {"$", 1}, {value, length}, {crc, 3}, - }; - server_->client()->Send(buffers, xe::countof(buffers)); -} - -bool GdbCommandProcessor::Process_qSupported(const std::string& line) { - StringBuffer response; - - // Read in the features the client supports. - // qSupported[:gdbfeature[;gdbfeature]...] - size_t feature_offset = line.find(':'); - while (feature_offset != std::string::npos) { - size_t next_offset = line.find(';', feature_offset + 1); - std::string feature = - line.substr(feature_offset + 1, next_offset - feature_offset - 1); - feature_offset = next_offset; - if (feature.find("multiprocess") == 0) { - bool is_supported = feature[12] == '+'; - } else if (feature.find("xmlRegisters") == 0) { - // xmlRegisters=A,B,C - } else if (feature.find("qRelocInsn") == 0) { - bool is_supported = feature[10] == '+'; - } else if (feature.find("swbreak") == 0) { - bool is_supported = feature[7] == '+'; - } else if (feature.find("hwbreak") == 0) { - bool is_supported = feature[7] == '+'; - } else { - XELOGW("Unknown GDB client support feature: %s", feature.c_str()); - } - } - - response.Append("PacketSize=4000;"); - response.Append("QStartNoAckMode+;"); - response.Append("qRelocInsn-;"); - response.Append("multiprocess-;"); - response.Append("ConditionalBreakpoints-;"); - response.Append("ConditionalTracepoints-;"); - response.Append("ReverseContinue-;"); - response.Append("ReverseStep-;"); - response.Append("swbreak+;"); - response.Append("hwbreak+;"); - - SendResponse(response.GetString()); - return true; -} - -bool GdbCommandProcessor::ProcessReadRegisters(const std::string& line) { - StringBuffer response; - - for (int32_t n = 0; n < 32; n++) { - // gpr - response.AppendFormat("%08X", n); - } - for (int64_t n = 0; n < 32; n++) { - // fpr - response.AppendFormat("%016llX", n); - } - response.AppendFormat("%08X", 0x8202FB40); // pc - response.AppendFormat("%08X", 65); // msr - response.AppendFormat("%08X", 66); // cr - response.AppendFormat("%08X", 67); // lr - response.AppendFormat("%08X", 68); // ctr - response.AppendFormat("%08X", 69); // xer - response.AppendFormat("%08X", 70); // fpscr - - SendResponse(response.GetString()); - return true; -} - -} // namespace gdb -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/gdb/gdb_command_processor.h b/src/xenia/debug/server/gdb/gdb_command_processor.h deleted file mode 100644 index 634e0c8f6..000000000 --- a/src/xenia/debug/server/gdb/gdb_command_processor.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_GDB_GDB_COMMAND_PROCESSOR_H_ -#define XENIA_DEBUG_SERVER_GDB_GDB_COMMAND_PROCESSOR_H_ - -#include -#include - -#include "xenia/debug/debugger.h" - -namespace xe { -namespace debug { -namespace server { -namespace gdb { - -class GdbServer; - -class GdbCommandProcessor { - public: - GdbCommandProcessor(GdbServer* server, Debugger* debugger); - ~GdbCommandProcessor() = default; - - bool ProcessBuffer(const uint8_t* buffer, size_t buffer_length); - - private: - bool ProcessPacket(const char* buffer, size_t buffer_length); - void SendResponse(const char* value, size_t length); - void SendResponse(const char* value) { - SendResponse(value, std::strlen(value)); - } - void SendResponse(std::string value) { - SendResponse(value.data(), value.size()); - } - - bool Process_qSupported(const std::string& line); - bool ProcessReadRegisters(const std::string& line); - - GdbServer* server_ = nullptr; - Debugger* debugger_ = nullptr; - std::vector receive_buffer_; - size_t receive_offset_ = 0; - std::vector transmit_buffer_; - - bool no_ack_mode_ = false; -}; - -} // namespace gdb -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_GDB_GDB_COMMAND_PROCESSOR_H_ diff --git a/src/xenia/debug/server/gdb/gdb_server.cc b/src/xenia/debug/server/gdb/gdb_server.cc deleted file mode 100644 index 08d2e25c1..000000000 --- a/src/xenia/debug/server/gdb/gdb_server.cc +++ /dev/null @@ -1,130 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/gdb/gdb_server.h" - -#include - -#include "xenia/base/logging.h" -#include "xenia/debug/debugger.h" -#include "xenia/debug/server/gdb/gdb_command_processor.h" - -DEFINE_int32(gdb_server_port, 9000, "Debugger gdbserver TCP port."); - -namespace xe { -namespace debug { -namespace server { -namespace gdb { - -constexpr size_t kReceiveBufferSize = 32 * 1024; - -GdbServer::GdbServer(Debugger* debugger) : DebugServer(debugger) { - receive_buffer_.resize(kReceiveBufferSize); - command_processor_ = std::make_unique(this, debugger); -} - -GdbServer::~GdbServer() = default; - -bool GdbServer::Initialize() { - socket_server_ = SocketServer::Create(uint16_t(FLAGS_gdb_server_port), - [this](std::unique_ptr client) { - AcceptClient(std::move(client)); - }); - if (!socket_server_) { - XELOGE("Unable to create GDB socket server - port in use?"); - return false; - } - - return true; -} - -void GdbServer::PostSynchronous(std::function fn) { assert_always(); } - -void GdbServer::AcceptClient(std::unique_ptr client) { - // If we have an existing client, kill it and join its thread. - if (client_) { - // TODO(benvanik): GDB say goodbye? - - client_->Close(); - xe::threading::Wait(client_thread_.get(), true); - client_thread_.reset(); - } - - // Take ownership of the new one. - client_ = std::move(client); - - // Create a thread to manage the connection. - client_thread_ = xe::threading::Thread::Create({}, [this]() { - // TODO(benvanik): GDB protocol stuff? Do we say hi? - // TODO(benvanik): move hello to thread - - // Let the debugger know we are present. - debugger_->set_attached(true); - - // Junk just to poke the remote client. - client_->Send("(gdb)\n"); - - // Main loop. - bool running = true; - while (running) { - auto wait_result = xe::threading::Wait(client_->wait_handle(), true); - switch (wait_result) { - case xe::threading::WaitResult::kSuccess: - // Event (read or close). - running = HandleClientEvent(); - continue; - case xe::threading::WaitResult::kAbandoned: - case xe::threading::WaitResult::kFailed: - // Error - kill the thread. - running = false; - continue; - default: - // Eh. Continue. - continue; - } - } - - // Kill client (likely already disconnected). - client_.reset(); - - // Notify debugger we are no longer attached. - debugger_->set_attached(false); - }); -} - -bool GdbServer::HandleClientEvent() { - if (!client_->is_connected()) { - // Known-disconnected. - return false; - } - // Attempt to read into our buffer. - size_t bytes_read = - client_->Receive(receive_buffer_.data(), receive_buffer_.capacity()); - if (bytes_read == -1) { - // Disconnected. - return false; - } else if (bytes_read == 0) { - // No data available. Wait again. - return true; - } - - // Pass off the command processor to do with it what it wants. - if (!command_processor_->ProcessBuffer(receive_buffer_.data(), bytes_read)) { - // Error. - XELOGE("Error processing incoming GDB command; forcing disconnect"); - return false; - } - - return true; -} - -} // namespace gdb -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/gdb/gdb_server.h b/src/xenia/debug/server/gdb/gdb_server.h deleted file mode 100644 index 645306dcb..000000000 --- a/src/xenia/debug/server/gdb/gdb_server.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_GDB_GDB_SERVER_H_ -#define XENIA_DEBUG_SERVER_GDB_GDB_SERVER_H_ - -#include - -#include "xenia/base/socket.h" -#include "xenia/base/threading.h" -#include "xenia/debug/debug_server.h" - -namespace xe { -namespace debug { -namespace server { -namespace gdb { - -class GdbCommandProcessor; - -class GdbServer : public DebugServer { - public: - GdbServer(Debugger* debugger); - ~GdbServer() override; - - Socket* client() const { return client_.get(); } - - bool Initialize() override; - - void PostSynchronous(std::function fn) override; - - private: - void AcceptClient(std::unique_ptr client); - bool HandleClientEvent(); - - std::unique_ptr socket_server_; - - std::unique_ptr client_; - std::unique_ptr client_thread_; - std::vector receive_buffer_; - - std::unique_ptr command_processor_; -}; - -} // namespace gdb -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_GDB_GDB_SERVER_H_ diff --git a/src/xenia/debug/server/mi/mi_command_processor.cc b/src/xenia/debug/server/mi/mi_command_processor.cc deleted file mode 100644 index 0f9326595..000000000 --- a/src/xenia/debug/server/mi/mi_command_processor.cc +++ /dev/null @@ -1,232 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/mi/mi_command_processor.h" - -#include "xenia/base/logging.h" -#include "xenia/base/string_buffer.h" -#include "xenia/debug/server/mi/mi_reader.h" -#include "xenia/debug/server/mi/mi_server.h" -#include "xenia/debug/server/mi/mi_writer.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -constexpr size_t kReceiveBufferSize = 1 * 1024 * 1024; -constexpr size_t kTransmitBufferSize = 1 * 1024 * 1024; - -MICommandProcessor::MICommandProcessor(MIServer* server, Debugger* debugger) - : server_(server), debugger_(debugger) { - receive_buffer_.resize(kReceiveBufferSize); - transmit_buffer_.resize(kTransmitBufferSize); -} - -bool MICommandProcessor::ProcessBuffer(const uint8_t* buffer, - size_t buffer_length) { - // Grow and append the bytes to the receive buffer. - while (receive_offset_ + buffer_length > receive_buffer_.capacity()) { - receive_buffer_.resize(receive_buffer_.size() * 2); - } - std::memcpy(receive_buffer_.data() + receive_offset_, buffer, buffer_length); - receive_offset_ += buffer_length; - - // While there are bytes pending in the buffer we scan through looking for end - // markers. When we find one, we emit the packet and move on. - size_t process_offset = 0; - while (process_offset < receive_offset_) { - // Look for an end marker. - size_t end_offset = -1; - size_t buffer_end_offset = -1; - for (size_t i = process_offset; i < receive_offset_; ++i) { - if (receive_buffer_[i] == '\r') { - end_offset = i - 1; - buffer_end_offset = i + 1; - break; - } else if (receive_buffer_[i] == '\n') { - end_offset = i - 1; - buffer_end_offset = i; - } - } - if (end_offset == -1) { - // No end marker found - break out for now. - break; - } - - // Emit packet. - if (!ProcessPacket((const char*)(receive_buffer_.data() + process_offset), - end_offset - process_offset)) { - // Failed to process line. - std::string line(receive_buffer_.data() + process_offset, - receive_buffer_.data() + end_offset); - XELOGE("Failed to process incoming MI line: %s", line.c_str()); - return false; - } - process_offset = buffer_end_offset + 1; - } - - // If we have leftover unprocessed bytes move them to the front of the buffer. - if (process_offset < receive_offset_) { - size_t remaining_bytes = receive_offset_ - process_offset; - std::memmove(receive_buffer_.data(), - receive_buffer_.data() + process_offset, remaining_bytes); - receive_offset_ = remaining_bytes; - } else { - receive_offset_ = 0; - } - - return true; -} - -bool MICommandProcessor::ProcessPacket(const char* buffer, - size_t buffer_length) { - // Will likely have a request prefix, like '#####-....'. - auto buffer_ptr = std::strchr(buffer, '-'); - if (!buffer_ptr) { - XELOGE("Malformed MI command"); - return false; - } - std::string token; - if (buffer_ptr != buffer) { - token = std::string(buffer, buffer_ptr); - } - ++buffer_ptr; // Skip leading '-'. - - std::string line((const char*)buffer_ptr, - buffer_length - (buffer_ptr - buffer) + 1); - XELOGI("MI -> %s", line.c_str()); - - auto command = line.substr(0, line.find(' ')); - auto args = - command.size() == line.size() ? "" : line.substr(command.size() + 1); - - bool handled = false; - if (command == "gdb-set") { - auto key = args.substr(0, args.find(' ')); - auto value = args.substr(args.find(' ') + 1); - if (key == "mi-async" || key == "target-async") { - bool is_enabled = value == "1" || value == "on"; - SendResult(token, ResultClass::kDone); - handled = true; - } else if (key == "stop-on-solib-events") { - bool is_enabled = value == "1" || value == "on"; - SendResult(token, ResultClass::kDone); - handled = true; - } - } else if (command == "file-exec-and-symbols") { - // args=foo - SendResult(token, ResultClass::kDone); - handled = true; - } else if (command == "break-insert") { - // args=main - SendResult(token, ResultClass::kDone); - handled = true; - } else if (command == "exec-run") { - exec_token_ = token; - SendResult(token, ResultClass::kRunning); - handled = true; - - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.AppendRaw(exec_token_); - writer.BeginAsyncNotifyRecord("library-loaded"); - writer.AppendString("id=123"); - writer.AppendString("target-name=\"foo.xex\""); - writer.AppendString("host-name=\"foo.xex\""); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); - } else if (command == "exec-continue") { - exec_token_ = token; - SendResult(token, ResultClass::kRunning); - handled = true; - } else if (command == "exec-interrupt") { - SendResult(token, ResultClass::kDone); - handled = true; - - // later: - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.AppendRaw(exec_token_); - writer.BeginAsyncExecRecord("stopped"); - writer.AppendString("reason=\"signal-received\""); - writer.AppendString("signal-name=\"SIGINT\""); - writer.AppendString("signal-meaning=\"Interrupt\""); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); - } else if (command == "exec-abort") { - XELOGI("Debug client requested abort"); - SendResult(token, ResultClass::kDone); - exit(1); - handled = true; - } else if (command == "gdb-exit") { - // TODO(benvanik): die better? - XELOGI("Debug client requested exit"); - exit(1); - SendResult(token, ResultClass::kDone); - handled = true; - } - if (!handled) { - XELOGE("Unknown GDB packet: %s", buffer_ptr); - SendErrorResult(token, "Unknown/unimplemented"); - } - return true; -} - -void MICommandProcessor::SendConsoleStreamOutput(const char* value) { - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.BeginConsoleStreamOutput(); - writer.AppendString(value); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); -} - -void MICommandProcessor::SendTargetStreamOutput(const char* value) { - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.BeginTargetStreamOutput(); - writer.AppendString(value); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); -} - -void MICommandProcessor::SendLogStreamOutput(const char* value) { - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.BeginLogStreamOutput(); - writer.AppendString(value); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); -} - -void MICommandProcessor::SendResult(const std::string& prefix, - ResultClass result_class) { - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.AppendRaw(prefix); - writer.BeginResultRecord(result_class); - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); -} - -void MICommandProcessor::SendErrorResult(const std::string& prefix, - const char* message, - const char* code) { - MIWriter writer(transmit_buffer_.data(), transmit_buffer_.size()); - writer.AppendRaw(prefix); - writer.BeginResultRecord(ResultClass::kError); - if (message) { - writer.AppendResult("msg", message); - } - if (code) { - writer.AppendResult("code", code); - } - writer.EndRecord(); - server_->client()->Send(transmit_buffer_.data(), writer.buffer_offset()); -} - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/mi/mi_command_processor.h b/src/xenia/debug/server/mi/mi_command_processor.h deleted file mode 100644 index 8d144d398..000000000 --- a/src/xenia/debug/server/mi/mi_command_processor.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_MI_MI_COMMAND_PROCESSOR_H_ -#define XENIA_DEBUG_SERVER_MI_MI_COMMAND_PROCESSOR_H_ - -#include -#include - -#include "xenia/debug/debugger.h" -#include "xenia/debug/server/mi/mi_protocol.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -class MIServer; - -class MICommandProcessor { - public: - MICommandProcessor(MIServer* server, Debugger* debugger); - ~MICommandProcessor() = default; - - bool ProcessBuffer(const uint8_t* buffer, size_t buffer_length); - - private: - bool ProcessPacket(const char* buffer, size_t buffer_length); - void SendConsoleStreamOutput(const char* value); - void SendTargetStreamOutput(const char* value); - void SendLogStreamOutput(const char* value); - void SendResult(const std::string& prefix, ResultClass result_class); - void SendErrorResult(const std::string& prefix, const char* message = nullptr, - const char* code = nullptr); - - MIServer* server_ = nullptr; - Debugger* debugger_ = nullptr; - std::vector receive_buffer_; - size_t receive_offset_ = 0; - std::vector transmit_buffer_; - - // Token of the last -exec-* command. Sent back on stops. - std::string exec_token_; -}; - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_MI_MI_COMMAND_PROCESSOR_H_ diff --git a/src/xenia/debug/server/mi/mi_protocol.h b/src/xenia/debug/server/mi/mi_protocol.h deleted file mode 100644 index 82a2ad8f8..000000000 --- a/src/xenia/debug/server/mi/mi_protocol.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_MI_MI_PROTOCOL_H_ -#define XENIA_DEBUG_SERVER_MI_MI_PROTOCOL_H_ - -#include - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -enum class RecordToken : char { - kResult = '^', - kAsyncExec = '*', - kAsyncStatus = '+', - kAsyncNotify = '=', -}; - -enum class StreamToken : char { - kConsole = '~', - kTarget = '@', - kLog = '&', -}; - -enum class ResultClass { - kDone, - kRunning, - kConnected, - kError, - kExit, -}; - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_MI_MI_PROTOCOL_H_ diff --git a/src/xenia/debug/server/mi/mi_reader.cc b/src/xenia/debug/server/mi/mi_reader.cc deleted file mode 100644 index 6f8fb76be..000000000 --- a/src/xenia/debug/server/mi/mi_reader.cc +++ /dev/null @@ -1,22 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/mi/mi_reader.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -// - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/mi/mi_reader.h b/src/xenia/debug/server/mi/mi_reader.h deleted file mode 100644 index 0252f46f9..000000000 --- a/src/xenia/debug/server/mi/mi_reader.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_MI_MI_READER_H_ -#define XENIA_DEBUG_SERVER_MI_MI_READER_H_ - -#include - -#include "xenia/debug/server/mi/mi_protocol.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -class MIReader { - public: -}; - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_MI_MI_READER_H_ diff --git a/src/xenia/debug/server/mi/mi_server.cc b/src/xenia/debug/server/mi/mi_server.cc deleted file mode 100644 index a0e3a52e7..000000000 --- a/src/xenia/debug/server/mi/mi_server.cc +++ /dev/null @@ -1,132 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/mi/mi_server.h" - -#include - -#include "xenia/base/logging.h" -#include "xenia/debug/debugger.h" -#include "xenia/debug/server/mi/mi_command_processor.h" - -DEFINE_int32(mi_server_port, 9001, "Debugger MI server TCP port."); - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -constexpr size_t kReceiveBufferSize = 32 * 1024; - -MIServer::MIServer(Debugger* debugger) : DebugServer(debugger) { - receive_buffer_.resize(kReceiveBufferSize); - command_processor_ = std::make_unique(this, debugger); -} - -MIServer::~MIServer() = default; - -bool MIServer::Initialize() { - socket_server_ = SocketServer::Create(uint16_t(FLAGS_mi_server_port), - [this](std::unique_ptr client) { - AcceptClient(std::move(client)); - }); - if (!socket_server_) { - XELOGE("Unable to create MI socket server - port in use?"); - return false; - } - - return true; -} - -void MIServer::PostSynchronous(std::function fn) { assert_always(); } - -void MIServer::AcceptClient(std::unique_ptr client) { - // If we have an existing client, kill it and join its thread. - if (client_) { - // TODO(benvanik): GDB say goodbye? - - client_->Close(); - xe::threading::Wait(client_thread_.get(), true); - client_thread_.reset(); - } - - // Take ownership of the new one. - client_ = std::move(client); - - // Create a thread to manage the connection. - client_thread_ = xe::threading::Thread::Create({}, [this]() { - // TODO(benvanik): GDB protocol stuff? Do we say hi? - // TODO(benvanik): move hello to thread - - // Let the debugger know we are present. - debugger_->set_attached(true); - - // Junk just to poke the remote client. - // The Microsoft MI engine seems to wait for *something* to come through on - // connection. - client_->Send("(gdb)\n"); - - // Main loop. - bool running = true; - while (running) { - auto wait_result = xe::threading::Wait(client_->wait_handle(), true); - switch (wait_result) { - case xe::threading::WaitResult::kSuccess: - // Event (read or close). - running = HandleClientEvent(); - continue; - case xe::threading::WaitResult::kAbandoned: - case xe::threading::WaitResult::kFailed: - // Error - kill the thread. - running = false; - continue; - default: - // Eh. Continue. - continue; - } - } - - // Kill client (likely already disconnected). - client_.reset(); - - // Notify debugger we are no longer attached. - debugger_->set_attached(false); - }); -} - -bool MIServer::HandleClientEvent() { - if (!client_->is_connected()) { - // Known-disconnected. - return false; - } - // Attempt to read into our buffer. - size_t bytes_read = - client_->Receive(receive_buffer_.data(), receive_buffer_.capacity()); - if (bytes_read == -1) { - // Disconnected. - return false; - } else if (bytes_read == 0) { - // No data available. Wait again. - return true; - } - - // Pass off the command processor to do with it what it wants. - if (!command_processor_->ProcessBuffer(receive_buffer_.data(), bytes_read)) { - // Error. - XELOGE("Error processing incoming GDB command; forcing disconnect"); - return false; - } - - return true; -} - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/mi/mi_server.h b/src/xenia/debug/server/mi/mi_server.h deleted file mode 100644 index 8cd5c9a73..000000000 --- a/src/xenia/debug/server/mi/mi_server.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_MI_MI_SERVER_H_ -#define XENIA_DEBUG_SERVER_MI_MI_SERVER_H_ - -#include - -#include "xenia/base/socket.h" -#include "xenia/base/threading.h" -#include "xenia/debug/debug_server.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -class MICommandProcessor; - -class MIServer : public DebugServer { - public: - MIServer(Debugger* debugger); - ~MIServer() override; - - Socket* client() const { return client_.get(); } - - bool Initialize() override; - - void PostSynchronous(std::function fn) override; - - private: - void AcceptClient(std::unique_ptr client); - bool HandleClientEvent(); - - std::unique_ptr socket_server_; - - std::unique_ptr client_; - std::unique_ptr client_thread_; - std::vector receive_buffer_; - - std::unique_ptr command_processor_; -}; - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_MI_MI_SERVER_H_ diff --git a/src/xenia/debug/server/mi/mi_writer.cc b/src/xenia/debug/server/mi/mi_writer.cc deleted file mode 100644 index b2b98cd5d..000000000 --- a/src/xenia/debug/server/mi/mi_writer.cc +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/debug/server/mi/mi_writer.h" - -#include "xenia/base/assert.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -void MIWriter::AppendRaw(const char* value, size_t length) { - assert_true(buffer_offset_ + length < buffer_capacity_); - std::memcpy(buffer_ + buffer_offset_, value, length); - buffer_offset_ += length; -} - -void MIWriter::BeginRecord(RecordToken token, const char* record_class) { - assert_false(in_record_); - in_record_ = true; - size_t record_class_length = std::strlen(record_class); - assert_true(buffer_offset_ + 1 + record_class_length < buffer_capacity_); - buffer_[buffer_offset_++] = char(token); - std::memcpy(buffer_ + buffer_offset_, record_class, record_class_length); - buffer_offset_ += record_class_length; -} - -void MIWriter::BeginResultRecord(ResultClass result_class) { - const char* record_class = "error"; - switch (result_class) { - case ResultClass::kDone: - record_class = "done"; - break; - case ResultClass::kRunning: - record_class = "running"; - break; - case ResultClass::kConnected: - record_class = "connected"; - break; - case ResultClass::kError: - record_class = "error"; - break; - case ResultClass::kExit: - record_class = "exit"; - break; - } - BeginRecord(RecordToken::kResult, record_class); -} - -void MIWriter::BeginStreamRecord(StreamToken token) { - assert_false(in_record_); - in_record_ = true; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = char(token); -} - -void MIWriter::EndRecord() { - assert_true(in_record_); - in_record_ = false; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = '\n'; -} - -void MIWriter::AppendArraySeparator() { - if (array_depth_) { - if (array_count_[array_depth_]) { - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = ','; - } - ++array_count_[array_depth_]; - } -} - -void MIWriter::PushTuple() { - assert_true(in_record_); - AppendArraySeparator(); - ++array_depth_; - assert_true(array_depth_ < kMaxArrayDepth); - array_count_[array_depth_] = 0; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = '{'; -} - -void MIWriter::PopTuple() { - --array_depth_; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = '}'; -} - -void MIWriter::PushList() { - assert_true(in_record_); - AppendArraySeparator(); - ++array_depth_; - assert_true(array_depth_ < kMaxArrayDepth); - array_count_[array_depth_] = 0; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = '['; -} - -void MIWriter::PopList() { - --array_depth_; - assert_true(buffer_offset_ + 1 < buffer_capacity_); - buffer_[buffer_offset_++] = ']'; -} - -void MIWriter::AppendString(const char* value, size_t length) { - assert_true(in_record_); - AppendArraySeparator(); - assert_true(buffer_offset_ + length < buffer_capacity_); - std::memcpy(buffer_ + buffer_offset_, value, length); - buffer_offset_ += length; -} - -void MIWriter::AppendResult(const char* variable, const char* value, - size_t length) { - assert_true(in_record_); - AppendArraySeparator(); - size_t variable_length = std::strlen(variable); - assert_true(buffer_offset_ + 1 + variable_length + length < buffer_capacity_); - std::memcpy(buffer_ + buffer_offset_, variable, variable_length); - buffer_offset_ += variable_length; - buffer_[buffer_offset_++] = '='; - std::memcpy(buffer_ + buffer_offset_, value, length); - buffer_offset_ += length; -} - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe diff --git a/src/xenia/debug/server/mi/mi_writer.h b/src/xenia/debug/server/mi/mi_writer.h deleted file mode 100644 index 905cf353a..000000000 --- a/src/xenia/debug/server/mi/mi_writer.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_MI_MI_WRITER_H_ -#define XENIA_DEBUG_SERVER_MI_MI_WRITER_H_ - -#include -#include - -#include "xenia/debug/server/mi/mi_protocol.h" - -namespace xe { -namespace debug { -namespace server { -namespace mi { - -// https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax -class MIWriter { - public: - MIWriter(uint8_t* buffer, size_t buffer_capacity) - : buffer_(buffer), buffer_capacity_(buffer_capacity) {} - - uint8_t* buffer() const { return buffer_; } - size_t buffer_capacity() const { return buffer_capacity_; } - size_t buffer_offset() const { return buffer_offset_; } - - void AppendRaw(const char* value, size_t length); - void AppendRaw(const char* value) { AppendRaw(value, std::strlen(value)); } - void AppendRaw(const std::string& value) { - AppendRaw(value.c_str(), value.size()); - } - - void BeginResultRecord(ResultClass result_class); - void BeginAsyncExecRecord(const char* async_class) { - BeginRecord(RecordToken::kAsyncExec, async_class); - array_depth_ = 1; - array_count_[array_depth_] = 1; - } - void BeginAsyncStatusRecord(const char* async_class) { - BeginRecord(RecordToken::kAsyncStatus, async_class); - array_depth_ = 1; - array_count_[array_depth_] = 1; - } - void BeginAsyncNotifyRecord(const char* async_class) { - BeginRecord(RecordToken::kAsyncNotify, async_class); - array_depth_ = 1; - array_count_[array_depth_] = 1; - } - void BeginConsoleStreamOutput() { BeginStreamRecord(StreamToken::kConsole); } - void BeginTargetStreamOutput() { BeginStreamRecord(StreamToken::kTarget); } - void BeginLogStreamOutput() { BeginStreamRecord(StreamToken::kLog); } - void EndRecord(); - - void PushTuple(); - void PopTuple(); - void PushList(); - void PopList(); - - void AppendString(const char* value, size_t length); - void AppendString(const char* value) { - AppendString(value, std::strlen(value)); - } - void AppendString(const std::string& value) { - AppendString(value.c_str(), value.size()); - } - - void AppendResult(const char* variable, const char* value, size_t length); - void AppendResult(const char* variable, const char* value) { - AppendResult(variable, value, std::strlen(value)); - } - void AppendResult(const char* variable, const std::string& value) { - AppendResult(variable, value.c_str(), value.size()); - } - - private: - void BeginRecord(RecordToken token, const char* record_class); - void BeginStreamRecord(StreamToken token); - void AppendArraySeparator(); - - uint8_t* buffer_ = nullptr; - size_t buffer_capacity_ = 0; - size_t buffer_offset_ = 0; - - static const int kMaxArrayDepth = 32; - bool in_record_ = false; - int array_depth_ = 0; - int array_count_[kMaxArrayDepth]; -}; - -} // namespace mi -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_MI_MI_WRITER_H_ diff --git a/src/xenia/debug/server/xdp/xdp_server.h b/src/xenia/debug/server/xdp/xdp_server.h deleted file mode 100644 index 6dd6cd510..000000000 --- a/src/xenia/debug/server/xdp/xdp_server.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2015 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_SERVER_XDP_XDP_SERVER_H_ -#define XENIA_DEBUG_SERVER_XDP_XDP_SERVER_H_ - -#include -#include -#include - -#include "xenia/base/socket.h" -#include "xenia/base/threading.h" -#include "xenia/debug/debug_server.h" -#include "xenia/debug/proto/packet_reader.h" -#include "xenia/debug/proto/packet_writer.h" -#include "xenia/debug/proto/xdp_protocol.h" - -namespace xe { -namespace debug { -namespace server { -namespace xdp { - -class XdpServer : public DebugServer { - public: - XdpServer(Debugger* debugger); - ~XdpServer() override; - - Socket* client() const { return client_.get(); } - - bool Initialize() override; - - void PostSynchronous(std::function fn) override; - - void OnExecutionContinued() override; - void OnExecutionInterrupted() override; - - private: - void AcceptClient(std::unique_ptr client); - bool HandleClientEvent(); - - bool ProcessBuffer(const uint8_t* buffer, size_t buffer_length); - bool ProcessPacket(const proto::Packet* packet); - - void Flush(); - void SendSuccess(proto::request_id_t request_id); - void SendError(proto::request_id_t request_id, - const char* error_message = nullptr); - void SendError(proto::request_id_t request_id, - const std::string& error_message); - - std::unique_ptr socket_server_; - - std::unique_ptr client_; - std::unique_ptr client_thread_; - - std::mutex post_mutex_; - std::unique_ptr post_event_; - std::list> post_queue_; - - std::vector receive_buffer_; - proto::PacketReader packet_reader_; - proto::PacketWriter packet_writer_; -}; - -} // namespace xdp -} // namespace server -} // namespace debug -} // namespace xe - -#endif // XENIA_DEBUG_SERVER_XDP_XDP_SERVER_H_ diff --git a/src/xenia/debug/ui/application.h b/src/xenia/debug/ui/application.h index 0c31f580e..86336e408 100644 --- a/src/xenia/debug/ui/application.h +++ b/src/xenia/debug/ui/application.h @@ -12,7 +12,7 @@ #include -#include "xenia/debug/client/xdp/xdp_client.h" +#include "xenia/debug/debug_client.h" #include "xenia/debug/ui/model/system.h" #include "xenia/ui/loop.h" @@ -31,7 +31,7 @@ class Application { xe::ui::Loop* loop() { return loop_.get(); } MainWindow* main_window() const { return main_window_.get(); } - client::xdp::XdpClient* client() { return &client_; } + DebugClient* client() { return &client_; } model::System* system() const { return system_.get(); } void Quit(); @@ -43,7 +43,7 @@ class Application { std::unique_ptr loop_; std::unique_ptr main_window_; - client::xdp::XdpClient client_; + DebugClient client_; std::unique_ptr system_; }; diff --git a/src/xenia/debug/ui/main_window.cc b/src/xenia/debug/ui/main_window.cc index b1fdcadbc..15e47886b 100644 --- a/src/xenia/debug/ui/main_window.cc +++ b/src/xenia/debug/ui/main_window.cc @@ -21,8 +21,6 @@ namespace xe { namespace debug { namespace ui { -using namespace xe::debug::client::xdp; - using xe::ui::MenuItem; const std::wstring kBaseTitle = L"xenia debugger"; diff --git a/src/xenia/debug/ui/main_window.h b/src/xenia/debug/ui/main_window.h index 5f8dc46cb..eb9dc3353 100644 --- a/src/xenia/debug/ui/main_window.h +++ b/src/xenia/debug/ui/main_window.h @@ -42,7 +42,7 @@ class MainWindow { void OnClose(); Application* app_ = nullptr; - xe::debug::client::xdp::XdpClient* client_ = nullptr; + xe::debug::DebugClient* client_ = nullptr; std::unique_ptr window_; std::unique_ptr form_; diff --git a/src/xenia/debug/ui/model/system.cc b/src/xenia/debug/ui/model/system.cc index 3d15782cf..80a9da99e 100644 --- a/src/xenia/debug/ui/model/system.cc +++ b/src/xenia/debug/ui/model/system.cc @@ -18,7 +18,7 @@ namespace model { using namespace xe::debug::proto; -System::System(xe::ui::Loop* loop, client::xdp::XdpClient* client) +System::System(xe::ui::Loop* loop, DebugClient* client) : loop_(loop), client_(client) {} ExecutionState System::execution_state() { @@ -83,7 +83,10 @@ void System::OnModulesUpdated(std::vector entries) { } } for (auto module_handle : extra_modules) { - modules_by_handle_[module_handle]->set_dead(true); + auto module = modules_by_handle_.find(module_handle); + if (module != modules_by_handle_.end()) { + module->second->set_dead(true); + } } } loop_->Post([this]() { @@ -112,7 +115,10 @@ void System::OnThreadsUpdated(std::vector entries) { } } for (auto thread_handle : extra_threads) { - modules_by_handle_[thread_handle]->set_dead(true); + auto thread = threads_by_handle_.find(thread_handle); + if (thread != threads_by_handle_.end()) { + thread->second->set_dead(true); + } } } loop_->Post([this]() { diff --git a/src/xenia/debug/ui/model/system.h b/src/xenia/debug/ui/model/system.h index 00c436ac2..88f814d9d 100644 --- a/src/xenia/debug/ui/model/system.h +++ b/src/xenia/debug/ui/model/system.h @@ -17,7 +17,7 @@ #include #include "xenia/base/delegate.h" -#include "xenia/debug/client/xdp/xdp_client.h" +#include "xenia/debug/debug_client.h" #include "xenia/debug/ui/model/function.h" #include "xenia/debug/ui/model/module.h" #include "xenia/debug/ui/model/thread.h" @@ -28,14 +28,12 @@ namespace debug { namespace ui { namespace model { -using xe::debug::client::xdp::ExecutionState; - -class System : public client::xdp::ClientListener { +class System : public ClientListener { public: - System(xe::ui::Loop* loop, client::xdp::XdpClient* client); + System(xe::ui::Loop* loop, DebugClient* client); xe::ui::Loop* loop() const { return loop_; } - client::xdp::XdpClient* client() const { return client_; } + DebugClient* client() const { return client_; } ExecutionState execution_state(); @@ -57,7 +55,7 @@ class System : public client::xdp::ClientListener { std::vector entries) override; xe::ui::Loop* loop_ = nullptr; - client::xdp::XdpClient* client_ = nullptr; + DebugClient* client_ = nullptr; std::recursive_mutex mutex_; std::vector> modules_; diff --git a/src/xenia/debug/ui/view.h b/src/xenia/debug/ui/view.h index 9105bedb4..8ef335589 100644 --- a/src/xenia/debug/ui/view.h +++ b/src/xenia/debug/ui/view.h @@ -28,12 +28,12 @@ class View { std::string name() const { return name_; } el::LayoutBox* root_element() { return &root_element_; } xe::ui::Loop* loop() const { return Application::current()->loop(); } - client::xdp::XdpClient* client() const { return client_; } + DebugClient* client() const { return client_; } model::System* system() const { return Application::current()->system(); } virtual el::Element* BuildUI() = 0; - virtual void Setup(xe::debug::client::xdp::XdpClient* client) = 0; + virtual void Setup(xe::debug::DebugClient* client) = 0; protected: View(std::string name) : name_(name) {} @@ -41,7 +41,7 @@ class View { std::string name_; el::LayoutBox root_element_; std::unique_ptr handler_; - xe::debug::client::xdp::XdpClient* client_ = nullptr; + xe::debug::DebugClient* client_ = nullptr; }; } // namespace ui diff --git a/src/xenia/debug/ui/views/cpu/cpu_view.cc b/src/xenia/debug/ui/views/cpu/cpu_view.cc index a8e5169d1..ec200f1dd 100644 --- a/src/xenia/debug/ui/views/cpu/cpu_view.cc +++ b/src/xenia/debug/ui/views/cpu/cpu_view.cc @@ -16,8 +16,6 @@ namespace ui { namespace views { namespace cpu { -using namespace xe::debug::client::xdp; - CpuView::CpuView() : View("CPU") {} CpuView::~CpuView() = default; @@ -147,7 +145,7 @@ el::Element* CpuView::BuildUI() { return &root_element_; } -void CpuView::Setup(XdpClient* client) { +void CpuView::Setup(DebugClient* client) { client_ = client; system()->on_execution_state_changed.AddListener( diff --git a/src/xenia/debug/ui/views/cpu/cpu_view.h b/src/xenia/debug/ui/views/cpu/cpu_view.h index b727fc492..1beb40611 100644 --- a/src/xenia/debug/ui/views/cpu/cpu_view.h +++ b/src/xenia/debug/ui/views/cpu/cpu_view.h @@ -28,7 +28,7 @@ class CpuView : public View { el::Element* BuildUI() override; - void Setup(xe::debug::client::xdp::XdpClient* client) override; + void Setup(xe::debug::DebugClient* client) override; protected: void UpdateElementState(); diff --git a/src/xenia/debug/ui/views/gpu/gpu_view.cc b/src/xenia/debug/ui/views/gpu/gpu_view.cc index 382478b3d..20fbb78ea 100644 --- a/src/xenia/debug/ui/views/gpu/gpu_view.cc +++ b/src/xenia/debug/ui/views/gpu/gpu_view.cc @@ -36,7 +36,7 @@ el::Element* GpuView::BuildUI() { return &root_element_; } -void GpuView::Setup(xe::debug::client::xdp::XdpClient* client) { +void GpuView::Setup(xe::debug::DebugClient* client) { // } diff --git a/src/xenia/debug/ui/views/gpu/gpu_view.h b/src/xenia/debug/ui/views/gpu/gpu_view.h index 9d4f5c136..a88d9c34c 100644 --- a/src/xenia/debug/ui/views/gpu/gpu_view.h +++ b/src/xenia/debug/ui/views/gpu/gpu_view.h @@ -28,7 +28,7 @@ class GpuView : public View { el::Element* BuildUI() override; - void Setup(xe::debug::client::xdp::XdpClient* client) override; + void Setup(xe::debug::DebugClient* client) override; protected: };