Merge pull request #25399 from DaanDeMeyer/siginfo-crash

crash-handler: Make sure we propagate the original siginfo
This commit is contained in:
Lennart Poettering
2022-11-16 18:42:07 +01:00
committed by GitHub
4 changed files with 26 additions and 5 deletions
+4
View File
@@ -599,6 +599,10 @@ foreach ident : [
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>'''],
['rt_tgsigqueueinfo', '''#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>'''],
['mallinfo', '''#include <malloc.h>'''],
['mallinfo2', '''#include <malloc.h>'''],
['execveat', '''#include <unistd.h>'''],
+14
View File
@@ -363,6 +363,20 @@ static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info)
/* ======================================================================= */
#if !HAVE_RT_TGSIGQUEUEINFO
static inline int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) {
# if defined __NR_rt_tgsigqueueinfo && __NR_rt_tgsigqueueinfo >= 0
return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info);
# else
# error "__NR_rt_tgsigqueueinfo not defined"
# endif
}
# define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
#endif
/* ======================================================================= */
#if !HAVE_EXECVEAT
static inline int missing_execveat(int dirfd, const char *pathname,
char *const argv[], char *const envp[],
+2 -1
View File
@@ -102,7 +102,8 @@ static void sigbus_handler(int sn, siginfo_t *si, void *data) {
if (si->si_code != BUS_ADRERR || !si->si_addr) {
assert_se(sigaction(SIGBUS, &old_sigaction, NULL) == 0);
rt_sigqueueinfo(getpid_cached(), SIGBUS, si);
if (rt_tgsigqueueinfo(getpid_cached(), gettid(), SIGBUS, si) < 0)
(void) raise(SIGBUS);
return;
}
+6 -4
View File
@@ -47,10 +47,11 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
* memory allocation is not async-signal-safe anyway — see signal-safety(7) for details —, and thus
* is not permissible in signal handlers.) */
if (getpid_cached() != 1)
if (getpid_cached() != 1) {
/* Pass this on immediately, if this is not PID 1 */
(void) raise(sig);
else if (!arg_dump_core)
if (rt_tgsigqueueinfo(getpid_cached(), gettid(), sig, siginfo) < 0)
(void) raise(sig);
} else if (!arg_dump_core)
log_emergency("Caught <%s>, not dumping core.", signal_to_string(sig));
else {
sa = (struct sigaction) {
@@ -80,7 +81,8 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
/* Raise the signal again */
pid = raw_getpid();
(void) kill(pid, sig); /* raise() would kill the parent */
if (rt_tgsigqueueinfo(pid, gettid(), sig, siginfo) < 0)
(void) kill(pid, sig); /* raise() would kill the parent */
assert_not_reached();
_exit(EXIT_EXCEPTION);