main: generate coredump and exit upon SIGABRT received

Previous code relied on abort() switching sigaction to SIG_FDL +
retriggering SIGABRT in case the signal handler returns, which would
then generate the coredump + terminate the process.
However, if a SIGABRT is received from somewhere else (kill -SIGABRT),
then the process would print the talloc report and continue running,
which is not desired.

Change-Id: Iff66eea9ee70850a4d038ece1d8473457023e1ee
Fixes: OS#4865
This commit is contained in:
Pau Espin 2020-11-25 18:51:06 +01:00
parent 4dc5dcf4e0
commit e917b1983a
1 changed files with 15 additions and 6 deletions

View File

@ -273,20 +273,29 @@ void msc_network_shutdown(struct gsm_network *net)
static struct gsm_network *msc_network = NULL;
extern void *tall_vty_ctx;
static void signal_handler(int signal)
static void signal_handler(int signum)
{
fprintf(stdout, "signal %u received\n", signal);
fprintf(stdout, "signal %u received\n", signum);
switch (signal) {
switch (signum) {
case SIGINT:
case SIGTERM:
LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signal);
LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signum);
quit++;
break;
case SIGABRT:
osmo_generate_backtrace();
/* in case of abort, we want to obtain a talloc report
* and then return to the caller, who will abort the process */
/* in case of abort, we want to obtain a talloc report and
* then run default SIGABRT handler, who will generate coredump
* and abort the process. abort() should do this for us after we
* return, but program wouldn't exit if an external SIGABRT is
* received.
*/
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_msc_ctx, stderr);
signal(SIGABRT, SIG_DFL);
raise(SIGABRT);
break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_msc_ctx, stderr);