diff --git a/dub.sdl b/dub.sdl
index 3bf5107..2c77e20 100644
--- a/dub.sdl
+++ b/dub.sdl
@@ -4,7 +4,7 @@ authors "dd86k
"
copyright "Copyright © 2024, dd86k "
license "BSD-3-Clause-Clear"
-dependency "alicedbg" repository="git+https://github.com/dd86k/alicedbg.git" version="3098e250232e248f6376d444ec656c7639694466"
+dependency "alicedbg" repository="git+https://github.com/dd86k/alicedbg.git" version="c6ad0bbefbeeb4ca17d3deedf7324bb53feb0235"
dependency "ddlogger" repository="git+https://github.com/dd86k/ddlogger.git" version="99a077a599c6d56e4fdeefb8b5d5002620cd228f"
# NOTE: By default, docs are built with dependencies.
diff --git a/source/debugger/alicedbg.d b/source/debugger/alicedbg.d
index f4c91bf..60f2c77 100644
--- a/source/debugger/alicedbg.d
+++ b/source/debugger/alicedbg.d
@@ -31,6 +31,7 @@ class AliceDebugger : IDebugger
process = adbg_debugger_spawn(exec.toStringz(), 0);
if (process == null)
throw new AlicedbgException();
+ _configure();
}
void attach(int pid)
@@ -38,13 +39,31 @@ class AliceDebugger : IDebugger
process = adbg_debugger_attach(pid, 0);
if (process == null)
throw new AlicedbgException();
+ _configure();
+ }
+
+ private
+ void _configure()
+ {
+ adbg_debugger_on(process, AdbgEvent.exception, &adbgEventException);
+ adbg_debugger_on(process, AdbgEvent.processExit, &adbgEventExited);
+ adbg_debugger_on(process, AdbgEvent.processContinue, &adbgEventContinued);
+ adbg_debugger_udata(process, &event);
}
void continue_()
{
enforceActiveProcess();
- if (adbg_debugger_continue(process))
- throw new AlicedbgException();
+ // HACK: To allow continuing from a previous event
+ switch (event.type) {
+ case AdapterEventType.stopped:
+ if (adbg_debugger_continue(process, event.stopped.threadId))
+ throw new AlicedbgException();
+ break;
+ default:
+ throw new Exception("Not in a stopped state");
+ }
+ _configure();
}
void terminate()
@@ -67,7 +86,7 @@ class AliceDebugger : IDebugger
{
enforceActiveProcess();
AdapterEvent event = void;
- if (adbg_debugger_wait(process, &handleAdbgEvent, &event))
+ if (adbg_debugger_wait(process))
throw new AlicedbgException();
return event;
}
@@ -75,6 +94,8 @@ class AliceDebugger : IDebugger
private:
/// Current process.
adbg_process_t *process;
+ /// Last adapter event.
+ AdapterEvent event;
// Actively check if we have an active process.
// Otherwise, Alicedbg would complain about an invalid handle, which
@@ -92,10 +113,9 @@ private:
string adbgExceptionName(adbg_exception_t *ex)
{
switch (ex.type) with (AdbgException) {
- case Exit: return "Exit";
case Breakpoint: return "Breakpoint";
case Step: return "Step";
- case Fault: return "Fault";
+ case AccessViolation: return "Access Violation";
case BoundExceeded: return "Bound Exceeded";
case Misalignment: return "Misalignment";
case IllegalInstruction:return "Illegal Instruction";
@@ -111,8 +131,6 @@ string adbgExceptionName(adbg_exception_t *ex)
case FPUOverflow: return "FPU Overflow";
case FPUUnderflow: return "FPU Underflow";
case FPUStackOverflow: return "FPU StackOverflow";
- case Disposition: return "Disposition";
- case NoContinue: return "No Continue";
default: return null;
}
}
@@ -126,27 +144,33 @@ AdapterEventStoppedReason adbgExceptionReason(adbg_exception_t *ex) {
}
}
-// Handle Alicedbg events
+// Handle exceptions
extern (C)
-void handleAdbgEvent(adbg_process_t *proc, int type, void *edata, void *udata)
+void adbgEventException(adbg_process_t *proc, void *udata, adbg_exception_t *exception)
{
AdapterEvent *event = cast(AdapterEvent*)udata;
- switch (type) {
- case AdbgEvent.exception:
- event.type = AdapterEventType.stopped;
- adbg_exception_t *ex = cast(adbg_exception_t*)edata;
- event.stopped.reason = adbgExceptionReason(ex);
- event.stopped.text = adbgExceptionName(ex);
- event.stopped.description = "Exception";
- // TODO: Assign Thread ID once Alicedbg gets TID association
- event.stopped.threadId = 0;
- return;
- case AdbgEvent.processExit:
- event.type = AdapterEventType.exited;
- int *code = cast(int*)edata;
- event.exited.code = *code;
- return;
- default:
- // ...
- }
-}
\ No newline at end of file
+ event.type = AdapterEventType.stopped;
+ event.stopped.reason = adbgExceptionReason(exception);
+ event.stopped.text = adbgExceptionName(exception);
+ event.stopped.description = "Exception";
+ event.stopped.threadId = cast(int)adbg_exception_tid(exception);
+}
+
+// Handle continuations
+extern (C)
+void adbgEventContinued(adbg_process_t *proc, void *udata)
+{
+ AdapterEvent *event = cast(AdapterEvent*)udata;
+ event.type = AdapterEventType.continued;
+ // TODO: Assign Thread ID once Alicedbg gets better TID association
+ event.continued.threadId = adbg_process_id(proc);
+}
+
+// Handle exits
+extern (C)
+void adbgEventExited(adbg_process_t *proc, void *udata, int code)
+{
+ AdapterEvent *event = cast(AdapterEvent*)udata;
+ event.type = AdapterEventType.exited;
+ event.exited.code = code;
+}