From 4b7e587523a0b6d9bf627d970a2399da84e6290f Mon Sep 17 00:00:00 2001
From: dd86k
Date: Wed, 4 Sep 2024 17:52:45 -0400
Subject: [PATCH] debugger: Add user data pointer to wait callback
---
debugger/shell.d | 88 ++++++++++++++++++++++++---------------------
examples/simple.d | 28 ++++++++-------
src/adbg/debugger.d | 19 +++++-----
3 files changed, 72 insertions(+), 63 deletions(-)
diff --git a/debugger/shell.d b/debugger/shell.d
index b81c8c11..88f2889e 100644
--- a/debugger/shell.d
+++ b/debugger/shell.d
@@ -636,48 +636,54 @@ void shell_event_disassemble(size_t address, int count = 1, bool showAddress = t
}
}
-void shell_event_exception(adbg_process_t *proc, int event, void* evdata) {
- if (event != AdbgEvent.exception)
- return;
-
- adbg_exception_t *ex = cast(adbg_exception_t*)evdata;
-
- printf("* Process %d (thread %d) stopped\n"~
- " Reason : %s ("~ADBG_OS_ERROR_FORMAT~")\n",
- ex.pid, ex.tid,
- adbg_exception_name(ex), ex.oscode);
-
- if (ex.faultz) {
+void shell_event_exception(adbg_process_t *proc, int event, void *edata, void *udata) {
+ switch (event) with (AdbgEvent) {
+ case exception:
+ adbg_exception_t *ex = cast(adbg_exception_t*)edata;
+
+ printf("* Process %d (thread %d) stopped\n"~
+ " Reason : %s ("~ADBG_OS_ERROR_FORMAT~")\n",
+ ex.pid, ex.tid,
+ adbg_exception_name(ex), ex.oscode);
+
+ // No fault address available
+ if (ex.faultz == 0)
+ return;
+
printf(" Address : 0x%llx\n", ex.fault_address);
- if (dis) {
- printf(" Machine :");
-
- // Print machine bytes
- ubyte[MAX_INSTR_SIZE] data = void;
- if (adbg_memory_read(process, ex.faultz, data.ptr, MAX_INSTR_SIZE)) {
- printf(" read error (%s)\n", adbg_error_message());
- return; // Nothing else to do
- }
-
- adbg_opcode_t op = void;
- if (adbg_dis_once(dis, &op, data.ptr, MAX_INSTR_SIZE)) {
- printf(" disassembly error (%s)\n", adbg_error_message());
- return;
- }
-
- // Print machine bytes
- for (size_t bi; bi < op.size; ++bi) {
- printf(" %02x", op.machine[bi]);
- }
- putchar('\n');
-
- // Print mnemonic
- printf(" Mnemonic: %s", op.mnemonic);
- if (op.operands)
- printf(" %s", op.operands);
- putchar('\n');
+ // No disassembler available
+ if (dis == null)
+ return;
+
+ printf(" Machine :");
+
+ // Print machine bytes
+ ubyte[MAX_INSTR_SIZE] data = void;
+ if (adbg_memory_read(process, ex.faultz, data.ptr, MAX_INSTR_SIZE)) {
+ printf(" read error (%s)\n", adbg_error_message());
+ return; // Nothing else to do
+ }
+
+ adbg_opcode_t op = void;
+ if (adbg_dis_once(dis, &op, data.ptr, MAX_INSTR_SIZE)) {
+ printf(" disassembly error (%s)\n", adbg_error_message());
+ return;
+ }
+
+ // Print machine bytes
+ for (size_t bi; bi < op.size; ++bi) {
+ printf(" %02x", op.machine[bi]);
}
+ putchar('\n');
+
+ // Print mnemonic
+ printf(" Mnemonic: %s", op.mnemonic);
+ if (op.operands)
+ printf(" %s", op.operands);
+ putchar('\n');
+ return;
+ default:
}
}
@@ -824,7 +830,7 @@ int command_restart(int argc, const(char) **argv) {
int command_go(int argc, const(char) **argv) {
if (adbg_debugger_continue(process))
return ShellError.alicedbg;
- if (adbg_debugger_wait(process, &shell_event_exception))
+ if (adbg_debugger_wait(process, &shell_event_exception, null))
return ShellError.alicedbg;
// Temporary: Cheap hack for process exit
if (adbg_process_status(process) == AdbgProcStatus.unloaded)
@@ -845,7 +851,7 @@ int command_kill(int argc, const(char) **argv) {
int command_stepi(int argc, const(char) **argv) {
if (adbg_debugger_stepi(process))
return ShellError.alicedbg;
- if (adbg_debugger_wait(process, &shell_event_exception))
+ if (adbg_debugger_wait(process, &shell_event_exception, null))
return ShellError.alicedbg;
return 0;
}
diff --git a/examples/simple.d b/examples/simple.d
index 0a06459c..1f195bbe 100644
--- a/examples/simple.d
+++ b/examples/simple.d
@@ -29,11 +29,11 @@ LINPUT: int c = getchar;
goto LINPUT;
}
-void loop_handler(adbg_process_t *proc, int event, void *evdata) {
+void loop_handler(adbg_process_t *proc, int event, void *edata, void *udata) {
if (event != AdbgEvent.exception)
return;
- adbg_exception_t *ex = cast(adbg_exception_t*)evdata;
+ adbg_exception_t *ex = cast(adbg_exception_t*)edata;
printf(
"\n----------------------------------------\n"~
"* EXCEPTION ("~ADBG_OS_ERROR_FORMAT~"): %s\n"~
@@ -44,18 +44,20 @@ void loop_handler(adbg_process_t *proc, int event, void *evdata) {
ex.fault_address
);
- // Print disassembly if available
- if (dis && ex.faultz) {
- adbg_opcode_t op = void;
- if (adbg_dis_process_once(dis, &op, proc, ex.fault_address)) {
- printf(" (error:%s)\n", adbg_error_message);
- return;
- }
- if (op.operands)
- printf(" (%s %s)\n", op.mnemonic, op.operands);
- else
- printf(" (%s)\n", op.mnemonic);
+ // If disassembler and fault address unavailable,
+ // skip printing disassembly
+ if (dis == null || ex.faultz == 0)
+ return;
+
+ adbg_opcode_t op = void;
+ if (adbg_dis_process_once(dis, &op, proc, ex.fault_address)) {
+ printf(" (error:%s)\n", adbg_error_message);
+ return;
}
+ if (op.operands)
+ printf(" (%s %s)\n", op.mnemonic, op.operands);
+ else
+ printf(" (%s)\n", op.mnemonic);
}
int main(int argc, const(char) **argv) {
diff --git a/src/adbg/debugger.d b/src/adbg/debugger.d
index 3a7effee..ec236b5e 100644
--- a/src/adbg/debugger.d
+++ b/src/adbg/debugger.d
@@ -239,12 +239,11 @@ version (Windows) {
// Introduced in Windows 10, version 1511
// IsWow64Process: 32-bit proc. under aarch64 returns FALSE
// NOTE: Could be moved to adbg_process_get_machine
- version (Win64) {
- if (IsWow64Process(proc.hpid, &proc.wow64) == FALSE) {
- adbg_process_free(proc);
- adbg_oops(AdbgError.os);
- return null;
- }
+ version (Win64)
+ if (IsWow64Process(proc.hpid, &proc.wow64) == FALSE) {
+ adbg_process_free(proc);
+ adbg_oops(AdbgError.os);
+ return null;
}
proc.status = AdbgProcStatus.standby;
@@ -608,9 +607,11 @@ version (Windows) {
/// Params:
/// tracee = Tracee instance.
/// userfunc = User function callback on event.
+/// udata = User data passed to callback. Can be used to identify requests, for example.
/// Returns: Error code.
int adbg_debugger_wait(adbg_process_t *tracee,
- void function(adbg_process_t*, int, void*) userfunc) {
+ void function(adbg_process_t *proc, int type, void *data, void *user) userfunc,
+ void *udata) {
if (tracee == null || userfunc == null)
return adbg_oops(AdbgError.invalidArgument);
if (tracee.creation == AdbgCreation.unloaded)
@@ -761,7 +762,7 @@ Lwait:
adbg_exception_translate(&exception, &tracee.pid, &stopsig);
}
- userfunc(tracee, AdbgEvent.exception, &exception);
+ userfunc(tracee, AdbgEvent.exception, &exception, udata);
return 0;
Lexited:
@@ -785,7 +786,7 @@ int adbg_debugger_terminate(adbg_process_t *tracee) {
tracee.creation = AdbgCreation.unloaded;
scope(exit) {
version (Windows) if (tracee.args) free(tracee.args);
- //version (Posix) if (tracee.argv) close(tracee.argv);
+ version (Posix) if (tracee.argv) close(tracee.argv);
free(tracee);
}