[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 21/30] bsd-user/signal.c: force_sig
|
From: |
Warner Losh |
|
Subject: |
[PATCH 21/30] bsd-user/signal.c: force_sig |
|
Date: |
Sun, 9 Jan 2022 09:19:14 -0700 |
Force delivering a signal and generating a core file.
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
bsd-user/qemu.h | 1 +
bsd-user/signal.c | 59 +++++++++++++++++++++++++++++++++++++++++
bsd-user/syscall_defs.h | 1 +
3 files changed, 61 insertions(+)
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 7c54a933eb8..e12617f5d69 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -223,6 +223,7 @@ void queue_signal(CPUArchState *env, int sig,
target_siginfo_t *info);
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
int target_to_host_signal(int sig);
int host_to_target_signal(int sig);
+void QEMU_NORETURN force_sig(int target_sig);
/* mmap.c */
int target_mprotect(abi_ulong start, abi_ulong len, int prot);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 824535be8b8..97f42f9c45e 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -109,6 +109,65 @@ static int core_dump_signal(int sig)
}
}
+/* Abort execution with signal. */
+void QEMU_NORETURN force_sig(int target_sig)
+{
+ CPUArchState *env = thread_cpu->env_ptr;
+ CPUState *cpu = env_cpu(env);
+ TaskState *ts = cpu->opaque;
+ int core_dumped = 0;
+ int host_sig;
+ struct sigaction act;
+
+ host_sig = target_to_host_signal(target_sig);
+ gdb_signalled(env, target_sig);
+
+ /* Dump core if supported by target binary format */
+ if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
+ stop_all_tasks();
+ core_dumped =
+ ((*ts->bprm->core_dump)(target_sig, env) == 0);
+ }
+ if (core_dumped) {
+ struct rlimit nodump;
+
+ /*
+ * We already dumped the core of target process, we don't want
+ * a coredump of qemu itself.
+ */
+ getrlimit(RLIMIT_CORE, &nodump);
+ nodump.rlim_cur = 0;
+ setrlimit(RLIMIT_CORE, &nodump);
+ (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) "
+ "- %s\n", target_sig, strsignal(host_sig), "core dumped");
+ }
+
+ /*
+ * The proper exit code for dying from an uncaught signal is
+ * -<signal>. The kernel doesn't allow exit() or _exit() to pass
+ * a negative value. To get the proper exit code we need to
+ * actually die from an uncaught signal. Here the default signal
+ * handler is installed, we send ourself a signal and we wait for
+ * it to arrive.
+ */
+ memset(&act, 0, sizeof(act));
+ sigfillset(&act.sa_mask);
+ act.sa_handler = SIG_DFL;
+ sigaction(host_sig, &act, NULL);
+
+ kill(getpid(), host_sig);
+
+ /*
+ * Make sure the signal isn't masked (just reuse the mask inside
+ * of act).
+ */
+ sigdelset(&act.sa_mask, host_sig);
+ sigsuspend(&act.sa_mask);
+
+ /* unreachable */
+ abort();
+}
+
/*
* Queue a signal so that it will be send to the virtual CPU as soon as
* possible.
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index 04a1a886d7b..62b472b990b 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -21,6 +21,7 @@
#define _SYSCALL_DEFS_H_
#include <sys/syscall.h>
+#include <sys/resource.h>
#include "errno_defs.h"
--
2.33.1
- Re: [PATCH 13/30] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*, (continued)
[PATCH 17/30] bsd-user/signal.c: Implement rewind_if_in_safe_syscall, Warner Losh, 2022/01/09
[PATCH 23/30] bsd-user/signal.c: sigset manipulation routines., Warner Losh, 2022/01/09