/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2013 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #include #include #include #include #include #include #include using namespace xe; using namespace xe::debug; DEFINE_bool(wait_for_debugger, false, "Whether to wait for the debugger to attach before launching."); DebugServer::DebugServer(Emulator* emulator) : emulator_(emulator), lock_(0) { lock_ = xe_mutex_alloc(10000); //protocols_.push_back( // new protocols::gdb::GDBProtocol(this)); protocols_.push_back( new protocols::ws::WSProtocol(this)); } DebugServer::~DebugServer() { Shutdown(); xe_free(lock_); lock_ = 0; } int DebugServer::Startup() { // HACK(benvanik): say we are ok even if we have no listener. if (!protocols_.size()) { return 0; } // Start listeners. // This may launch threads and such. for (std::vector::iterator it = protocols_.begin(); it != protocols_.end(); ++it) { Protocol* protocol = *it; if (protocol->Setup()) { return 1; } } // If desired, wait until the first client connects. //if (FLAGS_wait_for_debugger) { XELOGI("Waiting for debugger..."); if (protocols_[0]->WaitForClient()) { return 1; } XELOGI("Debugger attached, continuing..."); //} return 0; } void DebugServer::Shutdown() { xe_mutex_lock(lock_); std::vector clients(clients_.begin(), clients_.end()); clients_.clear(); for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it) { delete *it; } std::vector protocols(protocols_.begin(), protocols_.end()); protocols_.clear(); for (std::vector::iterator it = protocols.begin(); it != protocols.end(); ++it) { delete *it; } xe_mutex_unlock(lock_); } void DebugServer::AddClient(DebugClient* debug_client) { xe_mutex_lock(lock_); // Only one debugger at a time right now. Kill any old one. while (clients_.size()) { DebugClient* old_client = clients_.back(); clients_.pop_back(); old_client->Close(); } clients_.push_back(debug_client); xe_mutex_unlock(lock_); } void DebugServer::RemoveClient(DebugClient* debug_client) { xe_mutex_lock(lock_); for (std::vector::iterator it = clients_.begin(); it != clients_.end(); ++it) { if (*it == debug_client) { clients_.erase(it); break; } } xe_mutex_unlock(lock_); }