프로세스가 어떤 신호를 듣고 있는지 확인하는 방법은 무엇입니까?

프로세스가 어떤 신호를 듣고 있는지 확인하는 방법은 무엇입니까?

실행 중인 프로세스가 신호를 포착하는지, 무시하는지, 아니면 차단하는지 확인하는 방법은 무엇입니까? 이상적으로는 신호 목록을 보고 싶거나 적어도 확인하기 위해 실제로 신호를 보낼 필요는 없습니다.

답변1

Linux에서는 프로세스의 PID를 찾아 볼 수 있습니다 /proc/$PID/status. 여기에는 어떤 신호가 차단되었는지(SigBlk), 무시되었는지(SigIgn) 또는 포착되었는지(SigCgt) 설명하는 줄이 포함되어 있습니다.

# cat /proc/1/status
...
SigBlk: 0000000000000000
SigIgn: fffffffe57f0d8fc
SigCgt: 00000000280b2603
...

오른쪽의 숫자는 비트 마스크입니다. 이를 16진수에서 2진수로 변환하면 각 1비트는 캡처된 신호를 나타내며 오른쪽에서 왼쪽으로 1씩 계산됩니다. 따라서 SigCgt 라인을 해석하면 내 init프로세스가 다음 신호를 포착하고 있음 을 알 수 있습니다 .

00000000280b2603 ==> 101000000010110010011000000011
                     | |       | ||  |  ||       |`->  1 = SIGHUP
                     | |       | ||  |  ||       `-->  2 = SIGINT
                     | |       | ||  |  |`----------> 10 = SIGUSR1
                     | |       | ||  |  `-----------> 11 = SIGSEGV
                     | |       | ||  `--------------> 14 = SIGALRM
                     | |       | |`-----------------> 17 = SIGCHLD
                     | |       | `------------------> 18 = SIGCONT
                     | |       `--------------------> 20 = SIGTSTP
                     | `----------------------------> 28 = SIGWINCH
                     `------------------------------> 30 = SIGPWR

kill -l(bash에서 실행하여 숫자-이름 매핑을 찾았습니다.)

편집하다: 대중의 요구에 따라 POSIX sh 형식의 스크립트가 작성되었습니다.

sigparse () {
    i=0
    # bits="$(printf "16i 2o %X p" "0x$1" | dc)" # variant for busybox
    bits="$(printf "ibase=16; obase=2; %X\n" "0x$1" | bc)"
    while [ -n "$bits" ] ; do
        i="$(expr "$i" + 1)"
        case "$bits" in
            *1) printf " %s(%s)" "$(kill -l "$i")" "$i" ;;
        esac
        bits="${bits%?}"
    done
}

grep "^Sig...:" "/proc/$1/status" | while read a b ; do
        printf "%s%s\n" "$a" "$(sigparse "$b")"
    done # | fmt -t  # uncomment for pretty-printing

답변2

솔라리스에서는 다음을 실행하세요.psig프로세스 ID에 대한 신호 목록과 이를 처리하는 방법을 가져옵니다.

예를 들어:

bash-4.2$ psig $$
11088:  bash
HUP     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
INT     caught  sigint_sighandler   0
QUIT    ignored
ILL     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
TRAP    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
ABRT    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
EMT     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
FPE     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
KILL    default
BUS     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
SEGV    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
SYS     caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
PIPE    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
ALRM    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
TERM    ignored
USR1    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
USR2    caught  termsig_sighandler  0   HUP,INT,ILL,TRAP,ABRT,EMT,FPE,BUS,SEGV,SYS,PIPE,ALRM,TERM,USR1,USR2,VTALRM,XCPU,XFSZ,LOST
CLD     blocked,caught  0x4898e8    RESTART
PWR     default
WINCH   caught  sigwinch_sighandler 0
[...]

이는 SIGHUP, SIGILL 등이 모두 동일한 신호 처리 기능에 의해 포착되며 이를 termsig_sighandler통해 설정할 수 있는 플래그 없이 실행됨을 나타냅니다.sigaction및 신호 처리기가 실행되는 동안 일시적으로 마스크되는 모든 신호(이 경우 모든 신호는 동일한 신호 처리기를 사용하므로 런타임에 다시 입력되지 않습니다). 또한 SIGQUIT 및 SIGTERM이 무시되고 SIGKILL 및 SIGPWR이 시스템 기본 신호 작업을 사용하며 SIGCLD가 RESTART 플래그를 지정하므로 해당 신호 처리기가 시스템 호출을 중단하면 시스템 호출이 다시 시작되는 것을 볼 수 있습니다.

답변3

(이 답변은 @Jander의 답변을 중심으로 스크립트를 생성한다는 점에서 @user18096의 답변과 유사합니다.)

나는 썼다psig scriptPID(또는 모든 PID)를 가져오고 신호 마스크에서 사람이 읽을 수 있는 출력을 생성합니다 /proc/<PID>/status.

출력 예:

% ./psig -a
[     1] Signals Queued: 8/773737
[     1] Signals Pending:
[     1] Signals Pending (Shared):
[     1] Signals Blocked:
[     1] Signals Ignored: SIGPIPE
[     1] Signals Caught: SIGHUP,SIGINT,SIGABRT,SIGUSR1,SIGSEGV,SIGALRM,SIGTERM,SIGCHLD,SIGPWR
...
[ 31001] Signals Queued: 0/773737
[ 31001] Signals Pending:
[ 31001] Signals Pending (Shared):
[ 31001] Signals Blocked: SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,SIGABRT,SIGBUS,SIGFPE,SIGUSR1,SIGUSR2,SIGPIPE,SIGALRM,SIGTERM,SIGSTKFLT,SIGCHLD,SIGCONT,SIGTSTP,SIGTTIN,SIGTTOU,SIGURG,SIGXCPU,SIGXFSZ,SIGPROF,SIGWINCH,SIGIO,SIGPWR,SIGSYS,SIGRTMIN,SIGRTMIN+1,SIGRTMIN+2,SIGRTMIN+3,SIGRTMIN+4,SIGRTMIN+5,SIGRTMIN+6,SIGRTMIN+7,SIGRTMIN+8,SIGRTMIN+9,SIGRTMIN+10,SIGRTMIN+11,SIGRTMIN+12,SIGRTMIN+13,SIGRTMIN+14,SIGRTMIN+15,SIGRTMAX-14,SIGRTMAX-13,SIGRTMAX-12,SIGRTMAX-11,SIGRTMAX-10,SIGRTMAX-9,SIGRTMAX-8,SIGRTMAX-7,SIGRTMAX-6,SIGRTMAX-5,SIGRTMAX-4,SIGRTMAX-3,SIGRTMAX-2,SIGRTMAX-1,SIGRTMAX
[ 31001] Signals Ignored: SIGHUP,SIGINT,SIGQUIT,SIGPIPE,SIGXFSZ
[ 31001] Signals Caught: SIGBUS,SIGUSR1,SIGSEGV,SIGUSR2,SIGALRM,SIGTERM,SIGVTALRM

지침:

  • 이것Linux 관련 답변.
  • with이 스크립트를 실행하려면 및 를 사용하는 비교적 새로운 버전의 Python이 필요할 수 있습니다 OrderedDict.

답변4

사용이것(링크가 깨졌습니다) 이것 작업 실행에 대한 정보를 가져오는 라이브러리입니다.

struct Job신호에는 다음과 같은 특수 필드가 있습니다.sigCgt

다음과 같이 사용할 수 있습니다.

#include"read_proc.h"
int main(void)
{
    struct Root * rt=read_proc();
    struct Job * jb=rt->first->job;
    printf("%ull\n",jb->sigCgt);
    return 0;
}

관련 정보