मैं कैसे जांच सकता हूं कि एक प्रक्रिया किस संकेतों को सुन रही है?


81

मैं कैसे सत्यापित कर सकता हूं कि क्या कोई रनिंग प्रक्रिया सिग्नल को पकड़ लेगी, या उसे अनदेखा कर देगी, या उसे ब्लॉक कर देगी? आदर्श रूप से मैं संकेतों की एक सूची देखना चाहता हूं, या कम से कम वास्तव में संकेत को जांचने के लिए नहीं भेजना चाहिए।

जवाबों:


109

लिनक्स के तहत, आप अपनी प्रक्रिया का पीआईडी ​​पा सकते हैं, फिर देख सकते हैं /proc/$PID/status। इसमें यह वर्णन करने वाली लाइनें हैं कि कौन से संकेत अवरुद्ध हैं (सिग्लक), अनदेखा (सिग्नगन), या पकड़ा हुआ (सिगगेट)।

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

दाईं ओर संख्या एक बिटमास्क है। यदि आप इसे हेक्स से बाइनरी में परिवर्तित करते हैं, तो प्रत्येक 1-बिट एक पकड़े गए सिग्नल का प्रतिनिधित्व करता है, दाईं से बाईं ओर गिनती 1 से शुरू होती है। इसलिए सिगकट लाइन की व्याख्या करके, हम देख सकते हैं कि मेरी 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बैश से भागकर नंबर-टू-नाम मैपिंग पाया ।)

संपादित करें : और लोकप्रिय मांग से, एक स्क्रिप्ट, पोसिक्स श में।

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
यदि एक संकेत के तहत सूचीबद्ध किया गया SigBlkहै तो क्या यह भी दिखाई देता है SigCgt? क्योंकि इसे अवरुद्ध करने से, इसका मतलब है कि संकेत थोड़ी देर बाद सही हो जाएगा और पकड़े जाने की आवश्यकता होगी?
CMCDragonkai

नहीं, आप इसे पकड़ने के लिए तैयार होने के बिना सिग्नल को ब्लॉक कर सकते हैं। यदि आप सिग्नल नहीं पकड़ते हैं, तो सिग्नल के आधार पर एक डिफ़ॉल्ट क्रिया (आमतौर पर प्रक्रिया समाप्ति) होगी। यदि आप अधिक विवरण चाहते हैं तो आपको एक प्रश्न खोलना चाहिए।
जेंडर

एक स्क्रिप्ट पढ़ने के POSIX संस्करण का उपयोग क्या है /proc? यह केवल Linux पर काम करने वाला है ... और localPOSIX नहीं है। वैसे, यह थोड़े है, लेकिन इसका प्रभाव "अनिर्दिष्ट" है।
Kusalananda

2
@ कुसलानंद: लिनक्स बाश नहीं करता है - उदाहरण के लिए, छोटे एम्बेडेड प्लेटफॉर्म अक्सर बिजीबॉक्स का उपयोग करते हैं - लेकिन पॉसिक्स अनुपालन किसी भी आधुनिक के लिए एक निकट गारंटी है /bin/sh। तुम सही हो local; मैं साफ कर दूंगा।
जेंडर

@ जेंडर फेयर पॉइंट। मैं बैश और लिनक्स के बारे में जल्दबाजी बनाने की बात कबूल करता हूं।
कुसलानंद

23

सोलारिस पर, psigसिग्नल की एक सूची प्राप्त करने के लिए प्रक्रिया आईडी पर चलाएं और उन्हें कैसे संभाला जाएगा।

उदाहरण के लिए:

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 ध्वज को निर्दिष्ट करता है, इसलिए यदि इसका सिग्नल हैंडलर एक सिस्टम कॉल को रोकता है, तो syscall को पुनः आरंभ किया जाएगा।


बहुत बढ़िया! मैं उम्मीद कर रहा था कि कोई व्यक्ति गैर-लिनक्स उत्तर जोड़ देगा।
जैंडर

4

(यह उत्तर @ user18096 के उत्तर के समान है, इसमें यह @ जेंडर के उत्तर के आसपास एक स्क्रिप्ट बनाता है।)

मैंने psig scriptपीआईडी ​​(या सभी पीआईडी) लेने के लिए और सिग्नल मास्क से मानव-पठनीय आउटपुट बनाने के लिए लिखा है /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

चेतावनियां:

  • यह है एक लिनक्स विशिष्ट जवाब।
  • स्क्रिप्ट को चलाने के लिए अपेक्षाकृत नए पायथन संस्करण की आवश्यकता हो सकती है, यह उपयोग करता है withऔर OrderedDict

2

मैं @ Jander के सुंदर जवाब की नकल करते हुए वापस आ रहा हूं, जब इस तरह का सामना करना पड़ रहा है

user@machine:~$ grep Sig...: /proc/18475/status
SigPnd: 0000000000000000
SigBlk: fffffffe7dfbfaff
SigIgn: 0000000000001000
SigCgt: 0000000182006e47
user@machine:~$ 

लगता है मुझे कुछ खटखटाना पड़ेगा ... कहते हैं:

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:~$ 

मैं चाहता था कि यह कुछ हद तक सुपाच्य हो, लेकिन यह एक बिट अनाड़ी है जिसे मैं चाहूंगा, इसलिए, @ alanc के सुझाव के लिए धन्यवाद, मैं इसे ~ / bin / psig के रूप में सहेजूंगा।


2

उपयोग इस(लिंक टूटा हुआ) इस पुस्तकालय में नौकरियों के बारे में जानकारी प्राप्त करने के लिए, जो चल रहे हैं।

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;
}

मुझे अच्छा लगेगा लेकिन लिंक टूट गया है।
माइकल फॉक्स

1
@MichaelFox मेरा संपादन देखें। उपयोगकर्ता ने अपना खाता हटा दिया है। नया लिंक उसी परियोजना की ओर
इशारा करता है

1

FreeBSD पर, procstat -i <PID>यह देखने के लिए उपयोग करें कि कौन से संकेतों को प्रक्रिया द्वारा अनदेखा किया गया है। इसी तरह, procstat -j <PID>यह देखने के लिए कि प्रक्रिया थ्रेड्स द्वारा कौन से सिग्नल अवरुद्ध हैं। यदि कोई संकेत लंबित है, तो दोनों आदेश दिखाते हैं।

नमूना उत्पादन:

$ 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 -- ...

Procstat (1) देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.