diff --git a/include/thespian/backtrace.h b/include/thespian/backtrace.h index 49d53ad..c93a082 100644 --- a/include/thespian/backtrace.h +++ b/include/thespian/backtrace.h @@ -1,13 +1,21 @@ #pragma once #ifdef __cplusplus +#include extern "C" { +#else +#include #endif void install_debugger(); +void install_remote_debugger(); void install_backtrace(); void install_jitdebugger(); +void sighdl_debugger(int no, siginfo_t * /*sigi*/, void * /*uco*/); +void sighdl_remote_debugger(int no, siginfo_t * /*sigi*/, void * /*uco*/); +void sighdl_backtrace(int no, siginfo_t * /*sigi*/, void * /*uco*/); + #ifdef __cplusplus } #endif 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..825f97b 100644 --- a/src/thespian.zig +++ b/src/thespian.zig @@ -18,8 +18,14 @@ 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 sighdl_debugger = c.sighdl_debugger; +pub const sighdl_remote_debugger = c.sighdl_remote_debugger; +pub const sighdl_backtrace = c.sighdl_backtrace; + pub const max_message_size = 8 * 4096; const message_buf_allocator = std.heap.c_allocator; threadlocal var message_buffer: std.ArrayList(u8) = std.ArrayList(u8).init(message_buf_allocator);