Jawaban:
Di Linux, Anda dapat menemukan PID proses Anda, lalu lihat /proc/$PID/status
. Ini berisi garis yang menggambarkan sinyal mana yang diblokir (SigBlk), diabaikan (SigIgn), atau ditangkap (SigCgt).
# cat /proc/1/status
...
SigBlk: 0000000000000000
SigIgn: fffffffe57f0d8fc
SigCgt: 00000000280b2603
...
Angka di sebelah kanan adalah bitmask. Jika Anda mengonversinya dari hex ke biner, setiap 1-bit mewakili sinyal yang ditangkap, dihitung dari kanan ke kiri mulai dari 1. Jadi dengan menginterpretasikan garis SigCgt, kita dapat melihat bahwa init
proses saya menangkap sinyal berikut:
00000000280b2603 ==> 101000000010110010011000000011
| | | || | || |`-> 1 = SIGHUP
| | | || | || `--> 2 = SIGINT
| | | || | |`----------> 10 = SIGUSR1
| | | || | `-----------> 11 = SIGSEGV
| | | || `--------------> 14 = SIGALRM
| | | |`-----------------> 17 = SIGCHLD
| | | `------------------> 18 = SIGCONT
| | `--------------------> 20 = SIGTSTP
| `----------------------------> 28 = SIGWINCH
`------------------------------> 30 = SIGPWR
(Saya menemukan pemetaan angka-ke-nama dengan menjalankan kill -l
dari bash.)
EDIT : Dan dengan permintaan populer, skrip, dalam 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
/proc
? Ini hanya akan bekerja di Linux ... Dan local
bukan POSIX. Yah, memang agak, tapi efeknya "tidak ditentukan".
/bin/sh
. Anda benar tentang local
; Saya akan membersihkannya.
Di Solaris, jalankan psig
id proses untuk mendapatkan daftar sinyal dan cara penanganannya.
Misalnya:
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
[...]
yang menunjukkan bahwa SIGHUP, SIGILL, dll. semuanya akan ditangkap oleh fungsi pengendali sinyal yang sama termsig_sighandler
, yang akan dijalankan tanpa menggunakan salah satu flag yang dapat diatur melalui sigaction
, dan semua sinyal yang akan ditutup sementara untuk sementara pengendali sinyal berjalan (dalam hal ini semua yang menggunakan penangan sinyal yang sama, sehingga tidak dimasukkan kembali saat sudah berjalan). Anda juga dapat melihat bahwa SIGQUIT & SIGTERM akan diabaikan, SIGKILL & SIGPWR menggunakan aksi sinyal standar sistem, dan SIGCLD menentukan flag RESTART, jadi jika pengendali sinyal menginterupsi panggilan sistem, syscall akan dimulai kembali.
(Jawaban ini mirip dengan jawaban @ user18096, karena ia membuat skrip di sekitar jawaban @ Jander.)
Saya telah menulis psig script
untuk mengambil PID (atau semua PID) dan membuat output yang dapat dibaca manusia dari masker sinyal /proc/<PID>/status
.
Contoh output:
% ./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
Peringatan:
with
dan OrderedDict
.Saya terus kembali ke @ Jander's jawaban cantik berharap untuk decoder copy-and-paste ketika dihadapkan dengan seperti:
user@machine:~$ grep Sig...: /proc/18475/status
SigPnd: 0000000000000000
SigBlk: fffffffe7dfbfaff
SigIgn: 0000000000001000
SigCgt: 0000000182006e47
user@machine:~$
Kira saya harus mengetuk sesuatu ... katakan:
user@machine:~$ ruby -wn - /proc/18475/status <<'EOF'
if $_.match(/Sig(Pnd|Blk|Ign|Cgt):\s([0-9a-f]{16})/) == nil
next
end
field = $1
mask = $2.to_i(16)
names = []
Signal.list().each_pair() {
|name, number|
if number == 0
# "EXIT" => 0
next
end
if (mask & (1 << (number - 1))) == 0
next
end
names << name
}
puts("Sig#{field}: #{names.join(" | ")}")
EOF
SigPnd:
SigBlk: HUP | INT | QUIT | ILL | TRAP | IOT | ABRT | FPE | BUS | SYS | PIPE | ALRM | TERM | URG | TSTP | CONT | CHLD | CLD | TTIN | TTOU | IO | XCPU | XFSZ | PROF | WINCH | USR1 | USR2 | PWR | POLL
SigIgn: PIPE
SigCgt: HUP | INT | QUIT | BUS | SEGV | ALRM | TERM | VTALRM | USR1 | USR2
user@machine:~$
Saya ingin itu agak terbaca, tapi itu membuatnya lebih mudah untuk diminta daripada yang saya inginkan, jadi, berkat saran @ alanc, saya akan menyimpannya sebagai ~ / bin / psig.
Menggunakan ini(tautan rusak)
perpustakaan ini untuk mendapatkan info tentang pekerjaan yang sedang berjalan.
Ada bidang khusus struct Job
untuk sinyal, yang disebutsigCgt
Anda dapat menggunakan sesuatu seperti ini:
#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;
}
Pada FreeBSD, gunakan procstat -i <PID>
untuk melihat sinyal mana yang diabaikan oleh proses. Demikian pula, procstat -j <PID>
untuk melihat sinyal mana yang diblokir oleh utas proses. Kedua perintah menunjukkan jika sinyal tertunda.
Output sampel:
$ procstat -i 38540
PID COMM SIG FLAGS
38540 nsulfd HUP -I-
38540 nsulfd INT -I-
38540 nsulfd QUIT -I-
38540 nsulfd ILL ---
38540 nsulfd TRAP ---
...
$ procstat -j 38540
PID TID COMM SIG FLAGS
38540 101220 nsulfd HUP --
38540 101220 nsulfd INT --
38540 101220 nsulfd QUIT -B
38540 101220 nsulfd ILL --
38540 101220 nsulfd TRAP --
...
Lihat procstat (1) .
SigBlk
apakah itu juga munculSigCgt
? Karena dengan memblokirnya, itu hanya berarti sinyal akan dikirim kembali sedikit kemudian, dan perlu ditangkap?