Debugger can pause/resume threads.

This commit is contained in:
Ben Vanik 2015-06-09 20:14:23 -07:00
parent 8dc20eb5cd
commit d482885378
3 changed files with 31 additions and 55 deletions

View File

@ -45,10 +45,6 @@ class ThreadState {
uint32_t pcr_address() const { return pcr_address_; }
xe::cpu::frontend::PPCContext* context() const { return context_; }
bool Suspend() { return Suspend(~0); }
bool Suspend(uint32_t timeout_ms) { return false; }
bool Resume(bool force = false) { return false; }
static void Bind(ThreadState* thread_state);
static ThreadState* Get();
static uint32_t GetThreadID();

View File

@ -24,6 +24,7 @@
#include "xenia/emulator.h"
#include "xenia/kernel/objects/xkernel_module.h"
#include "xenia/kernel/objects/xmodule.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/kernel/objects/xuser_module.h"
// Autogenerated Flatbuffers files:
@ -127,6 +128,8 @@ void SendResponse(SOCKET client_socket, flatbuffers::FlatBufferBuilder& fbb,
void Debugger::PreLaunch() {
accept_thread_ = std::thread([this]() {
xe::threading::set_name("Debugger Server");
while (listen_socket_ != INVALID_SOCKET) {
sockaddr_in6 client_addr;
int client_count = sizeof(client_addr);
@ -148,6 +151,8 @@ void Debugger::PreLaunch() {
// Setup recv thread.
client_socket_ = client_socket_id;
receive_thread_ = std::thread([this]() {
xe::threading::set_name("Debugger Connection");
while (client_socket_ != INVALID_SOCKET) {
// Read length prefix.
uint32_t length = 0;
@ -471,51 +476,36 @@ uint8_t* Debugger::AllocateFunctionTraceData(size_t size) {
return functions_trace_file_->Allocate(size);
}
int Debugger::SuspendAllThreads(uint32_t timeout_ms) {
std::lock_guard<std::mutex> guard(threads_lock_);
int result = 0;
for (auto thread_state : threads_) {
if (thread_state.second->Suspend(timeout_ms)) {
result = 1;
bool Debugger::SuspendAllThreads() {
auto threads =
emulator_->kernel_state()->object_table()->GetObjectsByType<XThread>(
XObject::kTypeThread);
for (auto& thread : threads) {
if (!XSUCCEEDED(thread->Suspend(nullptr))) {
return false;
}
}
return result;
return true;
}
int Debugger::ResumeThread(uint32_t thread_id) {
std::lock_guard<std::mutex> guard(threads_lock_);
auto it = threads_.find(thread_id);
if (it == threads_.end()) {
return 1;
bool Debugger::ResumeThread(uint32_t thread_id) {
auto thread = emulator_->kernel_state()->GetThreadByID(thread_id);
if (!thread) {
return false;
}
// Found thread. Note that it could be deleted as soon as we unlock.
ThreadState* thread_state = it->second;
int result = thread_state->Resume();
return result;
return XSUCCEEDED(thread->Resume());
}
int Debugger::ResumeAllThreads(bool force) {
std::lock_guard<std::mutex> guard(threads_lock_);
int result = 0;
for (auto thread_state : threads_) {
if (thread_state.second->Resume(force)) {
result = 1;
bool Debugger::ResumeAllThreads() {
auto threads =
emulator_->kernel_state()->object_table()->GetObjectsByType<XThread>(
XObject::kTypeThread);
for (auto& thread : threads) {
if (!XSUCCEEDED(thread->Resume())) {
return false;
}
}
return result;
}
void Debugger::ForEachThread(std::function<void(ThreadState*)> callback) {
std::lock_guard<std::mutex> guard(threads_lock_);
for (auto thread_state : threads_) {
callback(thread_state.second);
}
return true;
}
int Debugger::AddBreakpoint(Breakpoint* breakpoint) {
@ -591,16 +581,11 @@ void Debugger::FindBreakpoints(uint32_t address,
}
void Debugger::OnThreadCreated(ThreadState* thread_state) {
std::lock_guard<std::mutex> guard(threads_lock_);
threads_[thread_state->thread_id()] = thread_state;
//
}
void Debugger::OnThreadDestroyed(ThreadState* thread_state) {
std::lock_guard<std::mutex> guard(threads_lock_);
auto it = threads_.find(thread_state->thread_id());
if (it != threads_.end()) {
threads_.erase(it);
}
//
}
void Debugger::OnFunctionDefined(cpu::FunctionInfo* symbol_info,

View File

@ -81,11 +81,9 @@ class Debugger {
uint8_t* AllocateFunctionData(size_t size);
uint8_t* AllocateFunctionTraceData(size_t size);
int SuspendAllThreads(uint32_t timeout_ms = UINT_MAX);
int ResumeThread(uint32_t thread_id);
int ResumeAllThreads(bool force = false);
void ForEachThread(std::function<void(cpu::ThreadState*)> callback);
bool SuspendAllThreads();
bool ResumeThread(uint32_t thread_id);
bool ResumeAllThreads();
int AddBreakpoint(Breakpoint* breakpoint);
int RemoveBreakpoint(Breakpoint* breakpoint);
@ -121,9 +119,6 @@ class Debugger {
std::wstring functions_trace_path_;
std::unique_ptr<ChunkedMappedMemoryWriter> functions_trace_file_;
std::mutex threads_lock_;
std::unordered_map<uint32_t, cpu::ThreadState*> threads_;
std::mutex breakpoints_lock_;
std::multimap<uint32_t, Breakpoint*> breakpoints_;
};