From e9445a07cf459089df47692a2811c8eb6db2279c Mon Sep 17 00:00:00 2001 From: liutie Date: Tue, 26 Apr 2022 12:11:07 +0800 Subject: [PATCH] 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 #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 Signed-off-by: fu.lin --- ps/display.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ps/display.c b/ps/display.c index 2e1cc665..b2ee131b 100644 --- a/ps/display.c +++ b/ps/display.c @@ -39,6 +39,8 @@ #define SIGCHLD SIGCLD #endif +#define SIG_IS_TERM_OR_HUP(signo) (((signo) == SIGTERM) || (signo) == SIGHUP) + char *myname; long Hertz; @@ -50,20 +52,23 @@ static void signal_handler(int signo){ sigprocmask(SIG_BLOCK, &ss, NULL); if(signo==SIGPIPE) _exit(0); /* "ps | head" will cause this */ /* fprintf() is not reentrant, but we _exit() anyway */ - fprintf(stderr, - _("Signal %d (%s) caught by %s (%s).\n"), - signo, - signal_number_to_name(signo), - myname, - PACKAGE_VERSION - ); + if (!SIG_IS_TERM_OR_HUP(signo)) { + fprintf(stderr, + _("Signal %d (%s) caught by %s (%s).\n"), + signo, + signal_number_to_name(signo), + myname, + PACKAGE_VERSION + ); + } switch (signo) { case SIGHUP: case SIGUSR1: case SIGUSR2: exit(EXIT_FAILURE); 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 */ sigemptyset(&ss); sigaddset(&ss, signo);