diff --git a/headers/os/kernel/debugger.h b/headers/os/kernel/debugger.h index ea23c64f06..dace1995c8 100644 --- a/headers/os/kernel/debugger.h +++ b/headers/os/kernel/debugger.h @@ -533,6 +533,7 @@ typedef struct { debug_origin origin; int signal; // the signal struct sigaction handler; // the signal handler + siginfo_t info; // the signal info bool deadly; // true, if handling the signal will kill // the team } debug_signal_received; diff --git a/headers/private/kernel/user_debugger.h b/headers/private/kernel/user_debugger.h index 27824a4830..c013ac4c96 100644 --- a/headers/private/kernel/user_debugger.h +++ b/headers/private/kernel/user_debugger.h @@ -255,7 +255,7 @@ void user_debug_post_syscall(uint32 syscall, void *args, uint64 returnValue, bigtime_t startTime); bool user_debug_exception_occurred(debug_exception_type exception, int signal); bool user_debug_handle_signal(int signal, struct sigaction *handler, - bool deadly); + siginfo_t *info, bool deadly); void user_debug_stop_thread(); void user_debug_team_created(team_id teamID); void user_debug_team_deleted(team_id teamID, port_id debuggerPort); diff --git a/src/bin/debug/strace/Jamfile b/src/bin/debug/strace/Jamfile index 3b8598523c..bf3f3c4dc6 100644 --- a/src/bin/debug/strace/Jamfile +++ b/src/bin/debug/strace/Jamfile @@ -24,6 +24,7 @@ local straceSources = fcntl.cpp ioctl.cpp network.cpp + signals.cpp ; # Our compiler badly chokes when compiling the generated file. So will diff --git a/src/bin/debug/strace/signals.cpp b/src/bin/debug/strace/signals.cpp new file mode 100644 index 0000000000..d517178b2f --- /dev/null +++ b/src/bin/debug/strace/signals.cpp @@ -0,0 +1,201 @@ +/* + * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include "signals.h" + + +// signal names +static const char *kSignalName[] = { + /* 0 */ "SIG0", + /* 1 */ "SIGHUP", + /* 2 */ "SIGINT", + /* 3 */ "SIGQUIT", + /* 4 */ "SIGILL", + /* 5 */ "SIGCHLD", + /* 6 */ "SIGABRT", + /* 7 */ "SIGPIPE", + /* 8 */ "SIGFPE", + /* 9 */ "SIGKILL", + /* 10 */ "SIGSTOP", + /* 11 */ "SIGSEGV", + /* 12 */ "SIGCONT", + /* 13 */ "SIGTSTP", + /* 14 */ "SIGALRM", + /* 15 */ "SIGTERM", + /* 16 */ "SIGTTIN", + /* 17 */ "SIGTTOU", + /* 18 */ "SIGUSR1", + /* 19 */ "SIGUSR2", + /* 20 */ "SIGWINCH", + /* 21 */ "SIGKILLTHR", + /* 22 */ "SIGTRAP", + /* 23 */ "SIGPOLL", + /* 24 */ "SIGPROF", + /* 25 */ "SIGSYS", + /* 26 */ "SIGURG", + /* 27 */ "SIGVTALRM", + /* 28 */ "SIGXCPU", + /* 29 */ "SIGXFSZ", + /* 30 */ "SIGBUS", + /* 31 */ "SIGRESERVED1", + /* 32 */ "SIGRESERVED2", +}; + + +std::string +signal_name(int signal) +{ + if (signal >= 0 && signal <= SIGRESERVED2) + return kSignalName[signal]; + + static char buffer[32]; + sprintf(buffer, "%d", signal); + return buffer; +} + + +static const char * +signal_code(int signal, int code) +{ +#define CASE(X) case X: return #X; + switch (code) { + CASE(SI_USER) + CASE(SI_QUEUE) + CASE(SI_TIMER) + CASE(SI_ASYNCIO) + CASE(SI_MESGQ) + } + + switch (signal) { + case SIGILL: + switch (code) { + CASE(ILL_ILLOPC) + CASE(ILL_ILLOPN) + CASE(ILL_ILLADR) + CASE(ILL_ILLTRP) + CASE(ILL_PRVOPC) + CASE(ILL_PRVREG) + CASE(ILL_COPROC) + CASE(ILL_BADSTK) + } + break; + case SIGFPE: + switch (code) { + CASE(FPE_INTDIV) + CASE(FPE_INTOVF) + CASE(FPE_FLTDIV) + CASE(FPE_FLTOVF) + CASE(FPE_FLTUND) + CASE(FPE_FLTRES) + CASE(FPE_FLTINV) + CASE(FPE_FLTSUB) + } + break; + case SIGSEGV: + switch (code) { + CASE(SEGV_MAPERR) + CASE(SEGV_ACCERR) + } + break; + case SIGBUS: + switch (code) { + CASE(BUS_ADRALN) + CASE(BUS_ADRERR) + CASE(BUS_OBJERR) + } + break; + case SIGTRAP: + switch (code) { + CASE(TRAP_BRKPT) + CASE(TRAP_TRACE) + } + break; + case SIGCHLD: + switch (code) { + CASE(CLD_EXITED) + CASE(CLD_KILLED) + CASE(CLD_DUMPED) + CASE(CLD_TRAPPED) + CASE(CLD_STOPPED) + CASE(CLD_CONTINUED) + } + break; + case SIGPOLL: + switch (code) { + CASE(POLL_IN) + CASE(POLL_OUT) + CASE(POLL_MSG) + CASE(POLL_ERR) + CASE(POLL_PRI) + CASE(POLL_HUP) + } + break; + } +#undef CASE + + static char buffer[32]; + sprintf(buffer, "%d", code); + return buffer; +} + + +std::string +signal_info(siginfo_t& info) +{ + static char buffer[32]; + std::string string; + + string.reserve(256); + + string += "{"; + string += "si_signo="; + string += signal_name(info.si_signo); + string += ", si_code="; + string += signal_code(info.si_signo, info.si_code); + + if (info.si_errno != 0) { + string += ", si_errno=0x"; + sprintf(buffer, "%x", info.si_errno); + string += buffer; + } + + string += ", si_pid="; + sprintf(buffer, "%d", (int)info.si_pid); + string += buffer; + string += ", si_uid="; + sprintf(buffer, "%d", (int)info.si_uid); + string += buffer; + + if (info.si_signo == SIGILL || info.si_signo == SIGFPE || info.si_signo == SIGSEGV + || info.si_signo == SIGBUS || info.si_signo == SIGTRAP) { + string += ", si_addr="; + sprintf(buffer, "%p", info.si_addr); + string += buffer; + } + + if (info.si_signo == SIGCHLD) { + string += ", si_status="; + sprintf(buffer, "%d", info.si_status); + string += buffer; + } + + if (info.si_signo == SIGPOLL) { + string += ", si_band="; + sprintf(buffer, "%ld", info.si_band); + string += buffer; + } + + string += ", si_value="; + sprintf(buffer, "%p", info.si_value.sival_ptr); + string += buffer; + string += "}"; + + return string; +} diff --git a/src/bin/debug/strace/signals.h b/src/bin/debug/strace/signals.h new file mode 100644 index 0000000000..5cb0d0a69c --- /dev/null +++ b/src/bin/debug/strace/signals.h @@ -0,0 +1,18 @@ +/* + * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. + * Distributed under the terms of the MIT License. + */ +#ifndef STRACE_SIGNAL_H +#define STRACE_SIGNAL_H + + +#include + +#include + + +std::string signal_name(int signal); +std::string signal_info(siginfo_t& info); + + +#endif // STRACE_SIGNAL_H diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 82425d9acc..7fd95a2ab9 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -25,6 +25,7 @@ #include "debug_utils.h" +#include "signals.h" #include "Context.h" #include "MemoryReader.h" #include "Syscall.h" @@ -115,44 +116,6 @@ static const char *kTerminalTextMagenta = "\33[35m"; static const char *kTerminalTextBlue = "\33[34m"; -// signal names -static const char *kSignalName[] = { - /* 0 */ "SIG0", - /* 1 */ "SIGHUP", - /* 2 */ "SIGINT", - /* 3 */ "SIGQUIT", - /* 4 */ "SIGILL", - /* 5 */ "SIGCHLD", - /* 6 */ "SIGABRT", - /* 7 */ "SIGPIPE", - /* 8 */ "SIGFPE", - /* 9 */ "SIGKILL", - /* 10 */ "SIGSTOP", - /* 11 */ "SIGSEGV", - /* 12 */ "SIGCONT", - /* 13 */ "SIGTSTP", - /* 14 */ "SIGALRM", - /* 15 */ "SIGTERM", - /* 16 */ "SIGTTIN", - /* 17 */ "SIGTTOU", - /* 18 */ "SIGUSR1", - /* 19 */ "SIGUSR2", - /* 20 */ "SIGWINCH", - /* 21 */ "SIGKILLTHR", - /* 22 */ "SIGTRAP", - /* 23 */ "SIGPOLL", - /* 24 */ "SIGPROF", - /* 25 */ "SIGSYS", - /* 26 */ "SIGURG", - /* 27 */ "SIGVTALRM", - /* 28 */ "SIGXCPU", - /* 29 */ "SIGXFSZ", - /* 30 */ "SIGBUS", - /* 31 */ "SIGRESERVED1", - /* 32 */ "SIGRESERVED2", -}; - - // command line args static int sArgc; static const char *const *sArgv; @@ -507,18 +470,6 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message, } -static const char * -signal_name(int signal) -{ - if (signal >= 0 && signal <= SIGRESERVED2) - return kSignalName[signal]; - - static char buffer[32]; - sprintf(buffer, "%d", signal); - return buffer; -} - - static void print_signal(FILE *outputFile, debug_signal_received &message, bool colorize) @@ -529,13 +480,14 @@ print_signal(FILE *outputFile, debug_signal_received &message, // print signal name if (colorize) { - print_to_string(&string, &length, "[%6" B_PRId32 "] --- %s%s (%s) %s---\n", - message.origin.thread, kTerminalTextRed, signal_name(signalNumber), - strsignal(signalNumber), kTerminalTextNormal); + print_to_string(&string, &length, "[%6" B_PRId32 "] --- %s%s (%s)%s %s ---\n", + message.origin.thread, kTerminalTextRed, + signal_name(signalNumber).c_str(), strsignal(signalNumber), + kTerminalTextNormal, signal_info(message.info).c_str()); } else { - print_to_string(&string, &length, "[%6" B_PRId32 "] --- %s (%s) ---\n", - message.origin.thread, signal_name(signalNumber), - strsignal(signalNumber)); + print_to_string(&string, &length, "[%6" B_PRId32 "] --- %s (%s) %s ---\n", + message.origin.thread, signal_name(signalNumber).c_str(), + strsignal(signalNumber), signal_info(message.info).c_str()); } print_buffer(outputFile, buffer, sizeof(buffer) - length); diff --git a/src/system/kernel/debug/user_debugger.cpp b/src/system/kernel/debug/user_debugger.cpp index 273c7dd44a..ddd186b31c 100644 --- a/src/system/kernel/debug/user_debugger.cpp +++ b/src/system/kernel/debug/user_debugger.cpp @@ -928,7 +928,8 @@ user_debug_exception_occurred(debug_exception_type exception, int signal) bool -user_debug_handle_signal(int signal, struct sigaction *handler, bool deadly) +user_debug_handle_signal(int signal, struct sigaction *handler, siginfo_t *info, + bool deadly) { // check, if a debugger is installed and is interested in signals Thread *thread = thread_get_current_thread(); @@ -942,6 +943,7 @@ user_debug_handle_signal(int signal, struct sigaction *handler, bool deadly) debug_signal_received message; message.signal = signal; message.handler = *handler; + message.info = *info; message.deadly = deadly; status_t result = thread_hit_debug_event(B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED, diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 6300c08cf2..917dc75571 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -821,8 +821,19 @@ notify_debugger(Thread* thread, Signal* signal, struct sigaction& handler, threadDebugInfoLocker.Unlock(); + siginfo_t info; + info.si_signo = signal->Number(); + info.si_code = signal->SignalCode(); + info.si_errno = signal->ErrorCode(); + info.si_pid = signal->SendingProcess(); + info.si_uid = signal->SendingUser(); + info.si_addr = signal->Address(); + info.si_status = signal->Status(); + info.si_band = signal->PollBand(); + info.si_value = signal->UserValue(); + // deliver the event - return user_debug_handle_signal(signal->Number(), &handler, deadly); + return user_debug_handle_signal(signal->Number(), &handler, &info, deadly); }