bsd-user/strace.c: print_taken_signal

print_taken_signal() prints signals when we're tracing signals.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Warner Losh 2022-01-08 20:04:18 -07:00
parent e625c7ef5c
commit fd5bec9ad2
2 changed files with 107 additions and 0 deletions

View File

@ -204,6 +204,16 @@ print_openbsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6);
void print_openbsd_syscall_ret(int num, abi_long ret);
/**
* print_taken_signal:
* @target_signum: target signal being taken
* @tinfo: target_siginfo_t which will be passed to the guest for the signal
*
* Print strace output indicating that this signal is being taken by the guest,
* in a format similar to:
* --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
*/
void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
extern int do_strace;
/* mmap.c */

View File

@ -31,6 +31,24 @@ int do_strace;
/*
* Utility functions
*/
static const char *
get_comma(int last)
{
return (last) ? "" : ",";
}
/*
* Prints out raw parameter using given format. Caller needs
* to do byte swapping if needed.
*/
static void
print_raw_param(const char *fmt, abi_long param, int last)
{
char format[64];
(void)snprintf(format, sizeof(format), "%s%s", fmt, get_comma(last));
gemu_log(format, param);
}
static void print_sysctl(const struct syscallname *name, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
@ -239,3 +257,82 @@ void print_openbsd_syscall_ret(int num, abi_long ret)
print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
}
static void
print_signal(abi_ulong arg, int last)
{
const char *signal_name = NULL;
switch (arg) {
case TARGET_SIGHUP:
signal_name = "SIGHUP";
break;
case TARGET_SIGINT:
signal_name = "SIGINT";
break;
case TARGET_SIGQUIT:
signal_name = "SIGQUIT";
break;
case TARGET_SIGILL:
signal_name = "SIGILL";
break;
case TARGET_SIGABRT:
signal_name = "SIGABRT";
break;
case TARGET_SIGFPE:
signal_name = "SIGFPE";
break;
case TARGET_SIGKILL:
signal_name = "SIGKILL";
break;
case TARGET_SIGSEGV:
signal_name = "SIGSEGV";
break;
case TARGET_SIGPIPE:
signal_name = "SIGPIPE";
break;
case TARGET_SIGALRM:
signal_name = "SIGALRM";
break;
case TARGET_SIGTERM:
signal_name = "SIGTERM";
break;
case TARGET_SIGUSR1:
signal_name = "SIGUSR1";
break;
case TARGET_SIGUSR2:
signal_name = "SIGUSR2";
break;
case TARGET_SIGCHLD:
signal_name = "SIGCHLD";
break;
case TARGET_SIGCONT:
signal_name = "SIGCONT";
break;
case TARGET_SIGSTOP:
signal_name = "SIGSTOP";
break;
case TARGET_SIGTTIN:
signal_name = "SIGTTIN";
break;
case TARGET_SIGTTOU:
signal_name = "SIGTTOU";
break;
}
if (signal_name == NULL) {
print_raw_param("%ld", arg, last);
return;
}
gemu_log("%s%s", signal_name, get_comma(last));
}
void print_taken_signal(int target_signum, const target_siginfo_t *tinfo)
{
/*
* Print the strace output for a signal being taken:
* --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
*/
gemu_log("%d ", getpid());
gemu_log("--- ");
print_signal(target_signum, 1);
gemu_log(" ---\n");
}