From a0351a7fa93332cde0f590bb997266d51501606b Mon Sep 17 00:00:00 2001
From: dd86k
Date: Mon, 2 Sep 2024 16:53:05 -0400
Subject: [PATCH] Move some variables from TLS to global memory, some docs,
free threadlist
---
common/cli.d | 4 +--
debugger/shell.d | 44 +++++++++++++++++++++++++++++++--
src/adbg/error.d | 11 +++++----
src/adbg/include/linux/ptrace.d | 2 +-
src/adbg/process/base.d | 3 +++
src/adbg/process/thread.d | 12 ++++++---
6 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/common/cli.d b/common/cli.d
index 7f44bed1..c04d9b57 100644
--- a/common/cli.d
+++ b/common/cli.d
@@ -192,16 +192,14 @@ int cli_build_info() {
//
int cli_version() {
- static immutable(char) *page_version =
+ __gshared immutable(char) *page_version = // avoid TLS
"Version "~FULL_VERSION~"\n"~
" Built "~__TIMESTAMP__~"\n"~
" "~COPYRIGHT~"\n"~
"License BSD-3-Clause-Clear\n"~
" \n"~
"Homepage https://github.com/dd86k/alicedbg";
-
puts(page_version);
-
exit(0);
return 0;
}
diff --git a/debugger/shell.d b/debugger/shell.d
index cce336f1..b81c8c11 100644
--- a/debugger/shell.d
+++ b/debugger/shell.d
@@ -24,9 +24,9 @@ import term;
extern (C):
///
-int opt_pid;
+__gshared int opt_pid;
///
-const(char) **opt_file_argv;
+__gshared const(char) **opt_file_argv;
/// Application error
enum ShellError {
@@ -471,6 +471,21 @@ immutable command2_t[] shell_commands = [
&command_plist,
},
//
+ // Thread management
+ //
+ {
+ [ "t", "thread" ],
+ "Manage process threads.",
+ [ "ACTION" ],
+ MODULE_DEBUGGER, CATEGORY_PROCESS,
+ [
+ { SECTION_DESCRIPTION,
+ [ "" ]
+ }
+ ],
+ &command_thread,
+ },
+ //
// Shell
//
{
@@ -1199,6 +1214,31 @@ version (UseNewProcessName) {
return 0;
}
+int command_thread(int argc, const(char) **argv) {
+ if (process == null)
+ return ShellError.pauseRequired;
+ if (argc < 2)
+ return ShellError.missingArgument;
+
+ const(char) *action = argv[1];
+ if (strcmp(action, "list") == 0) {
+ void *list = adbg_thread_list(process);
+ if (list == null)
+ return ShellError.alicedbg;
+
+ puts("Threads:");
+ int tid = void;
+ for (size_t i; (tid = adbg_thread_list_get(list, i)) != 0; ++i)
+ printf("%d\n", tid);
+
+ adbg_thread_list_free(list);
+ } else {
+ return ShellError.invalidParameter;
+ }
+
+ return 0;
+}
+
int command_quit(int argc, const(char) **argv) {
//TODO: Quit confirmation if debuggee is alive
// could do with optional "forced yes" type of optional
diff --git a/src/adbg/error.d b/src/adbg/error.d
index 2062a388..0484771b 100644
--- a/src/adbg/error.d
+++ b/src/adbg/error.d
@@ -28,7 +28,7 @@ import adbg.include.capstone : csh, cs_errno, cs_strerror;
// adbg_ensure_params(lvalue, "name")
// - returns string if null found
// - automatically set error code
-// adbg_oopsn(AdbgError)
+// adbg_oops_p(AdbgError, void*)
// - returns null
//TODO: Localize error messages as option (including system ones, when able)
@@ -237,16 +237,17 @@ void adbg_error_reset() {
// puts in the value of the callee instead. To prove this, __LINE__
// and __FUNCTION__ remains unchanged. To fix that, I'm supposed to
// use a template, but function templates pollute the final binary.
-/// Sets the last error code. The module path and line are automatically
-/// populated.
+/// Sets the last error code.
+///
+/// Used internally
/// Params:
/// e = Error code.
/// extra = External resource (handle, code, etc.).
/// f = Automatically set to `__FUNCTION__`.
/// l = Automatically set to `__LINE__`.
/// Returns: Error code
-int adbg_oops(AdbgError e,
- void *extra = null, const(char)* f = __FUNCTION__.ptr, int l = __LINE__) {
+int adbg_oops(AdbgError e, void *extra = null,
+ const(char)* f = __FUNCTION__.ptr, int l = __LINE__) {
version (Trace) trace("code=%d extra=%p caller=%s@%d", e, extra, f, l);
error.func = f;
error.line = l;
diff --git a/src/adbg/include/linux/ptrace.d b/src/adbg/include/linux/ptrace.d
index 3b6662f9..dae6be85 100644
--- a/src/adbg/include/linux/ptrace.d
+++ b/src/adbg/include/linux/ptrace.d
@@ -130,7 +130,7 @@ enum { // __ptrace_eventcodes
///
/// Params:
/// req = PTRACE request
-/// pid = Process ID number
+/// pid = Process ID number (On Linux, that's a thread ID)
/// addr = Memory pointer
/// data = Data pointer
///
diff --git a/src/adbg/process/base.d b/src/adbg/process/base.d
index 6dd652a6..24bcea9d 100644
--- a/src/adbg/process/base.d
+++ b/src/adbg/process/base.d
@@ -183,6 +183,8 @@ version (Windows) {
// GetProcessImageFileNameA
// + cut string manually <- base=true
// + PathGetDriveNumberA <- base=false
+ //
+ // QueryFullProcessImageName
DWORD needed = void;
DWORD pidlist = void;
@@ -304,6 +306,7 @@ AdbgMachine adbg_process_get_machine(adbg_process_t *tracee) {
return adbg_machine_default();
}
+// TODO: Switch to adbg.utils.list
/// Get a list of process IDs running.
///
/// This function allocates memory. The list passed will need to be closed
diff --git a/src/adbg/process/thread.d b/src/adbg/process/thread.d
index 5f8dc049..31958ad3 100644
--- a/src/adbg/process/thread.d
+++ b/src/adbg/process/thread.d
@@ -22,9 +22,8 @@ version (Windows) {
import core.sys.posix.libgen : basename;
}
-/// Get a list of threads for running process.
-/// Params:
-/// process = Process.
+/// Get a list of threads for target process.
+/// Params: process = Process.
/// Returns: Thread list.
void* adbg_thread_list(adbg_process_t *process) {
version (Windows) {
@@ -127,6 +126,11 @@ version (Windows) {
}
}
+/// Get thread ID from list using index.
+/// Params:
+/// list = Thread list instance.
+/// index = Zero-based index.
+/// Returns: Thread ID. Zero means an error occured or end of list.
int adbg_thread_list_get(void *list, size_t index) {
if (list == null)
return 0;
@@ -134,6 +138,8 @@ int adbg_thread_list_get(void *list, size_t index) {
return tid ? *tid : 0;
}
+/// Close the thread list instance.
+/// Params: list = Thread list instance.
void adbg_thread_list_free(void *list) {
if (list == null)
return;