summaryrefslogtreecommitdiff
path: root/sigs.py
blob: abad48ff7e9183c0eb48c629af8d30b72b82f3ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env python3
"""
Prints the registered signals for a Linux process.
"""
import signal, subprocess, sys

keyword = sys.argv[1]
try:
    pid = int(keyword)
except ValueError:
    pids = subprocess.check_output(["pgrep", keyword],
            universal_newlines=True).split()
    if len(pids) == 1:
        pid = int(pids[0])
    else:
        if not pids:
            print("No such process: %s", keyword)
        else:
            print("More than one process:", *pids)
        sys.exit(1)

def bits(n):
    i = 0
    while n:
        if n & 1:
            yield i
        n >>= 1
        i += 1

def print_sigs(sigset):
    # Note 32 and 33 are unusable, those are used by nptl(7):
    sigs = {
        32: "(NPTL thread cancellation)",
        33: "(NPTL POSIX timers)",
    }
    for name in dir(signal):
        if not name.startswith("SIG") or name.startswith("SIG_"):
            continue
        signum = int(getattr(signal, name))
        sigs[signum] = name
    for bit in bits(sigset):
        signum = bit + 1
        if signal.SIGRTMIN < signum <= signal.SIGRTMAX:
            signame = "SIGRTMIN+%d" % (signum - signal.SIGRTMIN)
        elif signum in sigs:
            signame = sigs[signum]
        else:
            signame = "(signal %d)" % signum
        print(" %016x %2d %s" % (1 << bit, signum, signame))

with open("/proc/%d/status" % pid) as f:
    for line in f:
        if not any(line.startswith("Sig%s" % suffix)
                for suffix in ("Pnd", "Blk", "Ign", "Cgt")):
            continue
        key, val = line.split()
        sigset = int(val, 16)
        print("%s %016x" % (key, sigset))
        print_sigs(sigset)