Skip to content

Commit

Permalink
[GDBStub] Provide exception type to debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Oct 7, 2024
1 parent 8939003 commit 3149396
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 11 deletions.
3 changes: 3 additions & 0 deletions src/xenia/cpu/debug_listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class DebugListener {
// end.
virtual void OnDetached() = 0;

// Handles exception info (will be followed by OnExecutionPaused)
virtual void OnUnhandledException(Exception* ex) = 0;

// Handles execution being interrupted and transitioning to
// ExceutionState::kPaused.
virtual void OnExecutionPaused() = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/cpu/processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ bool Processor::OnUnhandledException(Exception* ex) {
execution_state_ = ExecutionState::kPaused;

// Notify debugger that exceution stopped.
// debug_listener_->OnException(info);
debug_listener_->OnUnhandledException(ex);
debug_listener_->OnExecutionPaused();

// Suspend self.
Expand Down
44 changes: 36 additions & 8 deletions src/xenia/debug/gdb/gdbstub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "xenia/cpu/breakpoint.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/stack_walker.h"
#include "xenia/cpu/thread.h"
#include "xenia/kernel/xmodule.h"
#include "xenia/kernel/xthread.h"

Expand All @@ -50,7 +51,9 @@ enum class GdbStubControl : char {
constexpr const char* kGdbReplyOK = "OK";
constexpr const char* kGdbReplyError = "E01";

constexpr int kSignalSigtrap = 5;
constexpr int kSignalSigill = 4; // Illegal instruction
constexpr int kSignalSigtrap = 5; // Trace trap
constexpr int kSignalSigsegv = 11; // Segmentation fault

// must start with l for debugger to accept it
constexpr char kMemoryMapXml[] =
Expand Down Expand Up @@ -222,12 +225,26 @@ void GDBStub::Listen(std::unique_ptr<Socket>& client) {
{
std::unique_lock<std::mutex> lock(mtx_);
if (cache_.notify_stopped) {
if (cache_.notify_bp_thread_id != -1) {
cache_.cur_thread_id = cache_.notify_bp_thread_id;
if (cache_.notify_thread_id != -1) {
cache_.cur_thread_id = cache_.notify_thread_id;
}
SendPacket(client, GetThreadStateReply(cache_.notify_bp_thread_id,
kSignalSigtrap));
cache_.notify_bp_thread_id = -1;

int sig_num = kSignalSigtrap;
if (cache_.notify_exception_code.has_value()) {
if (cache_.notify_exception_code ==
xe::Exception::Code::kIllegalInstruction) {
sig_num = kSignalSigill;
} else {
sig_num = kSignalSigsegv;
}

cache_.notify_exception_code.reset();
cache_.notify_exception_access_violation.reset();
}

SendPacket(client,
GetThreadStateReply(cache_.notify_thread_id, sig_num));
cache_.notify_thread_id = -1;
cache_.notify_stopped = false;
}
}
Expand Down Expand Up @@ -898,6 +915,17 @@ void GDBStub::OnDetached() {
}
}

void GDBStub::OnUnhandledException(Exception* ex) {
#ifdef DEBUG
debugging::DebugPrint("GDBStub: OnUnhandledException {} {}\n",
int(ex->code()), int(ex->access_violation_operation()));
#endif
std::unique_lock<std::mutex> lock(mtx_);
cache_.notify_exception_code = ex->code();
cache_.notify_exception_access_violation = ex->access_violation_operation();
cache_.notify_thread_id = cpu::Thread::GetCurrentThreadId();
}

void GDBStub::OnExecutionPaused() {
#ifdef DEBUG
debugging::DebugPrint("GDBStub: OnExecutionPaused\n");
Expand Down Expand Up @@ -925,7 +953,7 @@ void GDBStub::OnStepCompleted(cpu::ThreadDebugInfo* thread_info) {
#endif
// Some debuggers like IDA will remove the current breakpoint & step into next
// instruction, only re-adding BP after it's told about the step
cache_.notify_bp_thread_id = thread_info->thread_id;
cache_.notify_thread_id = thread_info->thread_id;
cache_.last_bp_thread_id = thread_info->thread_id;
UpdateCache();
}
Expand All @@ -938,7 +966,7 @@ void GDBStub::OnBreakpointHit(Breakpoint* breakpoint,
#endif

cache_.notify_bp_guest_address = breakpoint->address();
cache_.notify_bp_thread_id = thread_info->thread_id;
cache_.notify_thread_id = thread_info->thread_id;
cache_.last_bp_thread_id = thread_info->thread_id;
UpdateCache();
}
Expand Down
7 changes: 5 additions & 2 deletions src/xenia/debug/gdb/gdbstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class GDBStub : public cpu::DebugListener {

void OnFocus() override;
void OnDetached() override;
void OnUnhandledException(Exception* ex) override;
void OnExecutionPaused() override;
void OnExecutionContinued() override;
void OnExecutionEnded() override;
Expand Down Expand Up @@ -100,9 +101,11 @@ class GDBStub : public cpu::DebugListener {
uint32_t last_bp_thread_id = -1;

uint64_t notify_bp_guest_address = -1;
uint32_t notify_bp_thread_id = -1;
std::vector<std::string> notify_debug_messages;
uint32_t notify_thread_id = -1;
bool notify_stopped = false;
std::optional<Exception::AccessViolationOperation>
notify_exception_access_violation;
std::optional<Exception::Code> notify_exception_code;

bool is_stopped = false;
std::vector<kernel::object_ref<kernel::XModule>> modules;
Expand Down
2 changes: 2 additions & 0 deletions src/xenia/debug/ui/debug_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,8 @@ void DebugWindow::OnDetached() {
}
}

void DebugWindow::OnUnhandledException(Exception* ex) {}

void DebugWindow::OnExecutionPaused() {
UpdateCache();
Focus();
Expand Down
1 change: 1 addition & 0 deletions src/xenia/debug/ui/debug_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class DebugWindow : public cpu::DebugListener {

void OnFocus() override;
void OnDetached() override;
void OnUnhandledException(Exception* ex) override;
void OnExecutionPaused() override;
void OnExecutionContinued() override;
void OnExecutionEnded() override;
Expand Down

0 comments on commit 3149396

Please sign in to comment.