signal: fix suspending ps when receving SIGTERM or SIGHUP

Call trace:
  #0 __lll_lock_wait_private () at
     ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
  #1 0x00007f95c059f9d7 in _L_lock_638 () from /lib64/libc.so.6
  #2 0x00007f95c059f8b6 in _nl_expand_alias
  #3 0x00007f95c059dad8 in _nl_find_domain
  #4 0x00007f95c059d22e in __dcigettext
  #5 0x00007f95c059c05f in __GI___dcgettext
  #6  0x00000000004032b3 in signal_handler (signo=15) at display.c:54
  #7  <signal handler called>
  #8  __memcpy_sse2 () at ../sysdeps/x86_64/memcpy.S:104
  #9  0x00007f95c05d9934 in __GI__IO_getline_info
  #10 0x00007f95c05d99b8 in __GI__IO_getline
  #11 0x00007f95c05e2a5d in __GI_fgets_unlocked
  #12 0x00007f95c059f478 in read_alias_file
  #13 0x00007f95c059f97a in _nl_expand_alias
  #14 0x00007f95c059dad8 in _nl_find_domain
  #15 0x00007f95c059d22e in __dcigettext
  #16 0x00007f95c059c05f in __GI___dcgettext
  #17 0x0000000000403a8d in reset_global () at global.c:410
  #18 0x0000000000402605 in main at display.c:650

The above call trace happens when the ps process is suspending, and the
signal SIGTERM is sent to the ps process at the same time.
Just cancel the SIGTERM and SIGHUP handler when suspending to prevent
the problem.

Signed-off-by: liutie <liutie4@huawei.com>
Signed-off-by: fu.lin <fulin10@huawei.com>
This commit is contained in:
liutie 2022-04-26 12:11:07 +08:00 committed by Craig Small
parent df4d2dc570
commit e9445a07cf

View File

@ -39,6 +39,8 @@
#define SIGCHLD SIGCLD #define SIGCHLD SIGCLD
#endif #endif
#define SIG_IS_TERM_OR_HUP(signo) (((signo) == SIGTERM) || (signo) == SIGHUP)
char *myname; char *myname;
long Hertz; long Hertz;
@ -50,20 +52,23 @@ static void signal_handler(int signo){
sigprocmask(SIG_BLOCK, &ss, NULL); sigprocmask(SIG_BLOCK, &ss, NULL);
if(signo==SIGPIPE) _exit(0); /* "ps | head" will cause this */ if(signo==SIGPIPE) _exit(0); /* "ps | head" will cause this */
/* fprintf() is not reentrant, but we _exit() anyway */ /* fprintf() is not reentrant, but we _exit() anyway */
fprintf(stderr, if (!SIG_IS_TERM_OR_HUP(signo)) {
_("Signal %d (%s) caught by %s (%s).\n"), fprintf(stderr,
signo, _("Signal %d (%s) caught by %s (%s).\n"),
signal_number_to_name(signo), signo,
myname, signal_number_to_name(signo),
PACKAGE_VERSION myname,
); PACKAGE_VERSION
);
}
switch (signo) { switch (signo) {
case SIGHUP: case SIGHUP:
case SIGUSR1: case SIGUSR1:
case SIGUSR2: case SIGUSR2:
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
default: default:
error_at_line(0, 0, __FILE__, __LINE__, "%s", _("please report this bug")); if (!SIG_IS_TERM_OR_HUP(signo))
error_at_line(0, 0, __FILE__, __LINE__, "%s", _("please report this bug"));
signal(signo, SIG_DFL); /* allow core file creation */ signal(signo, SIG_DFL); /* allow core file creation */
sigemptyset(&ss); sigemptyset(&ss);
sigaddset(&ss, signo); sigaddset(&ss, signo);