From 2f7228cea6b53d3f286398b6977acc791a9da2e6 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Thu, 3 Jul 2025 15:58:12 +0200 Subject: [PATCH] feat: add support for tty local debugger --- include/thespian/backtrace.h | 4 ++++ src/backtrace.cpp | 33 ++++++++++++++++++++++++++++++--- src/thespian.zig | 1 + 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/thespian/backtrace.h b/include/thespian/backtrace.h index 49d53ad..3f5a031 100644 --- a/include/thespian/backtrace.h +++ b/include/thespian/backtrace.h @@ -1,10 +1,14 @@ #pragma once #ifdef __cplusplus +#include extern "C" { +#else +#include #endif void install_debugger(); +void install_remote_debugger(); void install_backtrace(); void install_jitdebugger(); diff --git a/src/backtrace.cpp b/src/backtrace.cpp index e537f6a..2f22cc5 100644 --- a/src/backtrace.cpp +++ b/src/backtrace.cpp @@ -1,6 +1,5 @@ #ifdef __linux__ -#include #include #include #include @@ -31,7 +30,8 @@ static void get_pid_binpath() { } static const auto lldb{"/usr/bin/lldb"}; -static const auto default_debugger{"/usr/bin/gdbserver"}; +static const auto default_debugger{"/usr/bin/gdb"}; +static const auto default_remote_debugger{"/usr/bin/gdbserver"}; static auto get_debugger() -> const char * { const char *debugger = secure_getenv("JITDEBUG"); @@ -47,6 +47,20 @@ static auto get_debugger() -> const char * { } const char *const debugger = get_debugger(); +static auto get_remote_debugger() -> const char * { + const char *debugger = secure_getenv("JITDEBUG"); + if (not debugger) + return default_remote_debugger; + if (strcmp(debugger, "on") == 0) + return default_remote_debugger; + if (strcmp(debugger, "1") == 0) + return default_remote_debugger; + if (strcmp(debugger, "true") == 0) + return default_remote_debugger; + return debugger; +} +const char *const remote_debugger = get_remote_debugger(); + void start_debugger(const char *dbg, const char **argv) { #if defined(PR_SET_PTRACER) prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); // NOLINT @@ -67,11 +81,21 @@ void start_debugger(const char *dbg, const char **argv) { extern "C" void sighdl_debugger(int no, siginfo_t * /*sigi*/, void * /*uco*/) { get_pid_binpath(); const char *argv[] = {// NOLINT - debugger, "--attach", "[::1]:7777", pid_s, nullptr}; + debugger, "--pid", pid_s, nullptr}; start_debugger(debugger, argv); (void)raise(no); } +extern "C" void sighdl_remote_debugger(int no, siginfo_t * /*sigi*/, + void * /*uco*/) { + get_pid_binpath(); + const char *argv[] = {// NOLINT + remote_debugger, "--attach", "[::1]:7777", pid_s, + "-ex", "continue", nullptr}; + start_debugger(remote_debugger, argv); + (void)raise(no); +} + extern "C" void sighdl_backtrace(int no, siginfo_t * /*sigi*/, void * /*uco*/) { get_pid_binpath(); const char *argv[] = {// NOLINT @@ -98,6 +122,9 @@ static void install_crash_handler(void (*hdlr)(int, siginfo_t *, void *)) { } // namespace extern "C" void install_debugger() { install_crash_handler(sighdl_debugger); } +extern "C" void install_remote_debugger() { + install_crash_handler(sighdl_remote_debugger); +} extern "C" void install_backtrace() { install_crash_handler(sighdl_backtrace); } extern "C" void install_jitdebugger() { if (secure_getenv("JITDEBUG")) diff --git a/src/thespian.zig b/src/thespian.zig index 3cf2069..5097e5a 100644 --- a/src/thespian.zig +++ b/src/thespian.zig @@ -18,6 +18,7 @@ pub var stack_trace_on_errors: bool = false; pub const subprocess = if (builtin.os.tag == .windows) @import("subprocess_windows.zig") else @import("subprocess.zig"); pub const install_debugger = c.install_debugger; +pub const install_remote_debugger = c.install_remote_debugger; pub const install_backtrace = c.install_backtrace; pub const install_jitdebugger = c.install_jitdebugger; pub const max_message_size = 8 * 4096;