Skip to content

Commit

Permalink
Stop mce fbdev child process from dumping cores on shutdown
Browse files Browse the repository at this point in the history
The mce fbdev child process by design is meant to exit very late in
the shutdown sequence. If it gets terminated before it exits, the
non-functional signal handlers inherited from the parent process
cause (partially successful) core dumps via SIGABRT.

Remove signal handlers installed by the parent process and trap signals
that would cause core dumping to happen and make an _exit() instead.

[mce] Stop mce fbdev child process from dumping cores on shutdown. Fixes JB#26832
  • Loading branch information
spiiroin committed Mar 4, 2015
1 parent 0886fc9 commit 928282d
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 23 deletions.
35 changes: 35 additions & 0 deletions mce-fbdev.c
Expand Up @@ -21,6 +21,7 @@

#include "mce-fbdev.h"
#include "mce-log.h"
#include "mce.h"

#ifdef ENABLE_HYBRIS
# include "mce-hybris.h"
Expand Down Expand Up @@ -132,6 +133,17 @@ void mce_fbdev_reopen(void)
* POST_EXIT_LINGER
* ========================================================================= */

/** Signal handler that just exits
*
* @param sig signal number (unused)
*/
static void mce_fbdev_linger_signal_hander(int sig)
{
(void) sig;

_exit(EXIT_SUCCESS);
}

/** Create a child process to keep frame buffer device open after mce exits
*
* The frame buffer device powers off automatically when the last open
Expand Down Expand Up @@ -165,6 +177,29 @@ void mce_fbdev_linger_after_exit(int delay_ms)

setsid();

/* The parent process needs to pay special attention to signals
* in order not to leave wakelocks active on exit. Also some
* signals are transferred to mainloop via a pipe. None of this
* should happen if the child process gets signals -> remove
* all signal handlers the parent process has installed. */

mce_signal_handlers_remove();

/* Since the intent is that the child process exits very close to
* power off, it is unlikely that core can be succesfully dumped
* and processed -> trap all signals that do core dump by default
* and make an _exit() instead. */

static const int trap[] =
{
SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
SIGBUS, SIGSYS, SIGTRAP, SIGXCPU, SIGXFSZ,
-1
};

for( size_t i = 0; trap[i] != -1; ++i )
signal(trap[i], mce_fbdev_linger_signal_hander);

/* Close all files, except fbdev & stderr */

int nfd = getdtablesize();
Expand Down
57 changes: 34 additions & 23 deletions mce.c
Expand Up @@ -247,35 +247,46 @@ static void signal_handler(const gint signr)
}
}

/** Install handlers for signals we need to trap
*/
static void install_signal_handlers(void)
/** Array of signals that should be trapped */
static const int mce_signals_to_trap[] =
{
static const int sig[] = {
SIGUSR1,
SIGUSR2,
SIGHUP,
SIGUSR1,
SIGUSR2,
SIGHUP,

SIGINT,
SIGQUIT,
SIGTERM,
SIGINT,
SIGQUIT,
SIGTERM,

#ifdef ENABLE_WAKELOCKS
SIGABRT,
SIGILL,
SIGFPE,
SIGSEGV,
SIGPIPE,
SIGALRM,
SIGBUS,
SIGTSTP,
SIGABRT,
SIGILL,
SIGFPE,
SIGSEGV,
SIGPIPE,
SIGALRM,
SIGBUS,
SIGTSTP,
#endif

-1
};
-1
};

/** Install handlers for signals we need to trap
*/
static void mce_signal_handlers_install(void)
{
for( size_t i = 0; mce_signals_to_trap[i] != -1; ++i ) {
signal(mce_signals_to_trap[i], mce_tx_signal_cb);
}
}

for( size_t i = 0; sig[i] != -1; ++i ) {
signal(sig[i], mce_tx_signal_cb);
/** Restore default handlers for trapped signals
*/
void mce_signal_handlers_remove(void)
{
for( size_t i = 0; mce_signals_to_trap[i] != -1; ++i ) {
signal(mce_signals_to_trap[i], SIG_DFL);
}
}

Expand Down Expand Up @@ -966,7 +977,7 @@ int main(int argc, char **argv)
mce_log(LL_CRIT, "Failed to initialise signal pipe");
exit(EXIT_FAILURE);
}
install_signal_handlers();
mce_signal_handlers_install();

/* Initialise subsystems */

Expand Down
1 change: 1 addition & 0 deletions mce.h
Expand Up @@ -358,6 +358,7 @@ gboolean mce_rem_submode_int32(const submode_t submode);

void mce_abort(void) __attribute__((noreturn));
void mce_quit_mainloop(void);
void mce_signal_handlers_remove(void);

#define display_state_get() ({\
gint res = GPOINTER_TO_INT(display_state_pipe.cached_data);\
Expand Down

0 comments on commit 928282d

Please sign in to comment.