mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
Merge pull request #18060 from opensourcerouting/lib-crashlog-signals
lib: crash handlers must be allowed on threads
This commit is contained in:
commit
f64104bd97
|
@ -20,6 +20,7 @@
|
|||
#include "zlog.h"
|
||||
#include "libfrr.h"
|
||||
#include "libfrr_trace.h"
|
||||
#include "sigevent.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread");
|
||||
DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives");
|
||||
|
@ -185,10 +186,9 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
|
|||
|
||||
assert(frr_is_after_fork || !"trying to start thread before fork()");
|
||||
|
||||
/* Ensure we never handle signals on a background thread by blocking
|
||||
* everything here (new thread inherits signal mask)
|
||||
*/
|
||||
sigfillset(&blocksigs);
|
||||
sigemptyset(&blocksigs);
|
||||
frr_sigset_add_mainonly(&blocksigs);
|
||||
/* new thread inherits mask */
|
||||
pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs);
|
||||
|
||||
frrtrace(1, frr_libfrr, frr_pthread_run, fpt->name);
|
||||
|
|
15
lib/frrcu.c
15
lib/frrcu.c
|
@ -42,6 +42,7 @@
|
|||
#include "frrcu.h"
|
||||
#include "seqlock.h"
|
||||
#include "atomlist.h"
|
||||
#include "sigevent.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, RCU_THREAD, "RCU thread");
|
||||
DEFINE_MTYPE_STATIC(LIB, RCU_NEXT, "RCU sequence barrier");
|
||||
|
@ -346,7 +347,19 @@ static void rcu_start(void)
|
|||
*/
|
||||
sigset_t oldsigs, blocksigs;
|
||||
|
||||
sigfillset(&blocksigs);
|
||||
/* technically, the RCU thread is very poorly suited to run even just a
|
||||
* crashlog handler, since zlog_sigsafe() could deadlock on transiently
|
||||
* invalid (due to RCU) logging data structures
|
||||
*
|
||||
* but given that when we try to write a crashlog, we're already in
|
||||
* b0rked territory anyway - give the crashlog handler a chance.
|
||||
*
|
||||
* (also cf. the SIGALRM usage in writing crashlogs to avoid hung
|
||||
* processes on any kind of deadlock in crash handlers)
|
||||
*/
|
||||
sigemptyset(&blocksigs);
|
||||
frr_sigset_add_mainonly(&blocksigs);
|
||||
/* new thread inherits mask */
|
||||
pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs);
|
||||
|
||||
rcu_active = true;
|
||||
|
|
|
@ -45,6 +45,33 @@ bool frr_sigevent_check(sigset_t *setp);
|
|||
/* check whether there are signals to handle, process any found */
|
||||
extern int frr_sigevent_process(void);
|
||||
|
||||
/* Ensure we don't handle "application-type" signals on a secondary thread by
|
||||
* blocking these signals when creating threads
|
||||
*
|
||||
* NB: SIGSEGV, SIGABRT, etc. must be allowed on all threads or we get no
|
||||
* crashlogs. Since signals vary a little bit between platforms, below is a
|
||||
* list of known things to go to the main thread. Any unknown signals should
|
||||
* stay thread-local.
|
||||
*/
|
||||
static inline void frr_sigset_add_mainonly(sigset_t *blocksigs)
|
||||
{
|
||||
/* signals we actively handle */
|
||||
sigaddset(blocksigs, SIGHUP);
|
||||
sigaddset(blocksigs, SIGINT);
|
||||
sigaddset(blocksigs, SIGTERM);
|
||||
sigaddset(blocksigs, SIGUSR1);
|
||||
|
||||
/* signals we don't actively use but that semantically belong */
|
||||
sigaddset(blocksigs, SIGUSR2);
|
||||
sigaddset(blocksigs, SIGQUIT);
|
||||
sigaddset(blocksigs, SIGCHLD);
|
||||
sigaddset(blocksigs, SIGPIPE);
|
||||
sigaddset(blocksigs, SIGTSTP);
|
||||
sigaddset(blocksigs, SIGTTIN);
|
||||
sigaddset(blocksigs, SIGTTOU);
|
||||
sigaddset(blocksigs, SIGWINCH);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue