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;