File: psig.stp

package info (click to toggle)
systemtap 4.4-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 38,260 kB
  • sloc: cpp: 77,147; ansic: 61,828; xml: 49,277; exp: 42,244; sh: 11,046; python: 2,772; perl: 2,252; tcl: 1,305; makefile: 1,086; lisp: 105; java: 102; awk: 101; asm: 91; sed: 16
file content (155 lines) | stat: -rwxr-xr-x 5,616 bytes parent folder | download | duplicates (7)
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#! /bin/sh

//bin/true && exec stap -DMAXACTION=10000 -g $0 ${1+"$@"}

# psig
# Copyright (C) 2008-2012 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# psig reports information about signals by the process id.
#
# psig is not a port of Solaris' psig tool. It was written based on the example
# output at http://developers.sun.com/solaris/articles/solaris_linux_app.html.
# This script requires the signal.stp-psig.patch for tapset/signal.stp (not in
# the upstream version of SystemTap at the time of writing).
#
# $ psig $$ | head -10
# 1852:    bash
# HUP      caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# INT      caught   0x0808d280  0  
# QUIT     ignored  
# ILL      caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# TRAP     caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# ABRT     caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# BUS      caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# FPE      caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,FPE,USR1,SEGV,USR2,PIPE,ALRM,TERM,XCPU,XFSZ,VTALRM,SYS
# KILL     default  
# $ stap -V # systemtap-20071229.tar.bz2
# SystemTap translator/driver (version 0.6/0.131 built 2008-01-12)
# $ cat /etc/redhat-release 
# Fedora release 8 (Werewolf)
# $ uname -a
# Linux kerndev.xxx.redhat.com 2.6.23.9-85.fc8 #1 SMP Fri Dec 7 15:49:59 EST 2007 i686 i686 i386 GNU/Linux
#
# NOTES:
# HUP      caught   0x0808d040  0  HUP,INT,ILL,TRAP,ABRT,BUS,...
# [.......][.......][..........][.][............................
# |<-- type of signal (1..64)
#          |<-- signal disposition. it can be SIG_{DFL,IGN,ERR} or a pointer to a function
#                   |<-- address of the signal-catching function
#                               |<-- sa_flags. see the code snippet below
#                                  |<-- set of signals to be blocked when executing the handler
#
# linux-2.6/include/asm-x86/signal.h:
# [...]
# /*
#  * SA_FLAGS values:
#  *
#  * SA_ONSTACK indicates that a registered stack_t will be used.
#  * SA_RESTART flag to get restarting signals (which were the default long ago)
#  * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
#  * SA_RESETHAND clears the handler when the signal is delivered.
#  * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
#  * SA_NODEFER prevents the current signal from being masked in the handler.
#  *
#  * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
#  * Unix names RESETHAND and NODEFER respectively.
#  */
# #define SA_NOCLDSTOP    0x00000001u
# #define SA_NOCLDWAIT    0x00000002u
# #define SA_SIGINFO      0x00000004u
# #define SA_ONSTACK      0x08000000u
# #define SA_RESTART      0x10000000u
# #define SA_NODEFER      0x40000000u
# #define SA_RESETHAND    0x80000000u
# 
# #define SA_NOMASK       SA_NODEFER
# #define SA_ONESHOT      SA_RESETHAND
# 
# #define SA_RESTORER     0x04000000
#

global _NSIG = 64

function get_k_sigaction:long (task:long, sig:long) %{
	struct task_struct *p = (struct task_struct *)((long)STAP_ARG_task);

	STAP_RETVALUE = (long)&p->sighand->action[(int)STAP_ARG_sig];
%}

function get_task_info:string (task:long) %{
	char pid[10]; /* just to realign the header properly */
	struct task_struct *p = (struct task_struct *)((long)STAP_ARG_task);

	if (!p)
		strlcpy(STAP_RETVALUE, "NULL", MAXSTRINGLEN);
	else {
		sprintf(pid, "%d:", p->pid);
		snprintf(STAP_RETVALUE, MAXSTRINGLEN, "%-8s %s", pid, p->comm);
	}
%}

function translate_mask:string (mask:string) {
	str = signal_str(strtol(tokenize(mask, ","), 10))
	while (1) {
		sig = signal_str(strtol(tokenize("", ","), 10))
		if (strlen(sig) == 0)
			break;
		str = str . "," . sig
	}
	return str;
}

/*
 * if sa_flags is 0, then return 0. If not, return the interpreted sa_flags.
 */
function sa_flags_str2:string (sa_flags:string) %{
	if (strlen(STAP_ARG_sa_flags) == 0)
		strcpy(STAP_ARG_sa_flags, "0");
	strlcpy (STAP_RETVALUE, STAP_ARG_sa_flags, MAXSTRINGLEN);
%}

probe begin {
%( $# < 1
        %? pid = target()
        %: pid = $1
%)
        # if (pid == 0) error ("Please provide valid target process-id as $1 or -x PID");
	task = pid2task(pid)
  assert(task, "pid2task: process not found. exiting.\n")

	task_info = get_task_info(task)
  assert(!isinstr(task_info, "NULL"), "get_task_info: invalid task_struct. exiting.\n")
	printf("%s\n", task_info)

	for (i = 0; i < _NSIG; ++i) {
		handler_status = ""
		act = get_k_sigaction(task, i)
    assert(act, "get_k_sigaction: invalid k_sigaction pointer. exiting.\n")
		sig = signal_str(i+1)

		handler = sa_handler_str(get_sa_handler(act))
                # XXX: convert hex pointer via usymdata() to useful function
		if (! (isinstr(handler, "default") || isinstr(handler, "ignored"))) {
			blocked = is_sig_blocked(task, i+1)
			if (blocked)
				handler_status = "blocked,"
			handler_status = handler_status . "caught"
		} else
			handler_status = handler

		flags = sa_flags_str2(sa_flags_str(get_sa_flags(act)))
		mask = sigset_mask_str(get_sigaction_mask(act))

		printf("%-8s %-8s ", sig, handler_status);
		if (isinstr(handler_status, "caught"))
			printf("%s  %s  %s\n", handler, flags, translate_mask(mask))
		else
			printf("\n")
	}

	exit()
}