xref: /freebsd/cddl/usr.sbin/dwatch/libexec/proc (revision 434283fda99e89af20c3fe95fde427624ae96d04)
1# -*- tab-width: 4 -*- ;; Emacs
2# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
3############################################################ IDENT(1)
4#
5# $Title: dwatch(8) module for dtrace_proc(4) activity $
6# $Copyright: 2014-2026 Devin Teske. All rights reserved. $
7#
8############################################################ DESCRIPTION
9#
10# Display process activity
11#
12############################################################ PROBE
13
14case "$PROFILE" in
15proc)
16	: ${PROBE:=$( echo \
17		proc:::create, \
18		proc:::exec, \
19		proc:::exec-failure, \
20		proc:::exec-success, \
21		proc:::exit, \
22		proc:::signal-clear, \
23		proc:::signal-discard, \
24		proc:::signal-send )}
25	;;
26proc-signal)
27	: ${PROBE:=$( echo \
28		proc:::signal-clear, \
29		proc:::signal-discard, \
30		proc:::signal-send )}
31	;;
32proc-signal-fatal)
33	: ${PROBE:=proc:::signal-send}
34	;;
35proc-status)
36	: ${PROBE:=$( echo \
37		proc:::create, \
38		proc:::exec, \
39		proc:::exec-failure, \
40		proc:::exec-success, \
41		proc:::exit )}
42	;;
43*)
44	: ${PROBE:=proc:::${PROFILE#proc-}}
45esac
46
47############################################################ EVENT ACTION
48
49# Answer "what killed my process?" by showing only those signals whose
50# default disposition is to terminate the process (with or without core),
51# most-notably including kernel-generated SIGSEGV/SIGBUS/SIGILL/SIGFPE
52# that no kill(2) watcher will ever see.
53
54[ "$CUSTOM_TEST" ] || case "$PROFILE" in
55proc-signal-fatal)
56	EVENT_TEST="this->sig == SIGABRT || this->sig == SIGBUS ||
57	this->sig == SIGEMT || this->sig == SIGFPE ||
58	this->sig == SIGILL || this->sig == SIGKILL ||
59	this->sig == SIGQUIT || this->sig == SIGSEGV ||
60	this->sig == SIGSYS || this->sig == SIGTRAP ||
61	this->sig == SIGXCPU || this->sig == SIGXFSZ"
62	;;
63esac
64
65############################################################ ACTIONS
66
67exec 9<<EOF
68this int	sig;
69this pid_t	pid;
70this string	details;
71this string	exec_arg0;
72
73inline string probealias[string name] =
74	name == "create" ?		"FORK" :
75	name == "exec" ?		"EXEC" :
76	name == "exec-failure" ?	"FAIL" :
77	name == "exec-success" ?	"INIT" :
78	name == "exit" ?		"EXIT" :
79	name == "signal-clear" ?	"CLEAR" :
80	name == "signal-discard" ?	"DISCARD" :
81	name == "signal-send" ?		"SEND" :
82	name;
83
84$PROBE /* probe ID $ID */
85{${TRACE:+
86	printf("<$ID>");}
87	this->details = "";
88}
89
90proc:::create /* probe ID $(( $ID + 1 )) */
91{${TRACE:+
92	printf("<$(( $ID + 1 ))>");
93}
94	$( pproc -P _create "(struct proc *)args[0]" )
95
96	/* details = "pid <pid of args[0]> -- <proc args of args[0]>" */
97	this->details = strjoin(
98		strjoin("pid ", lltostr(this->pid_create)),
99		strjoin(" -- ", this->args_create));
100}
101
102proc:::exec /* probe ID $(( $ID + 2 )) */
103{${TRACE:+
104	printf("<$(( $ID + 2 ))");}
105	this->details = this->exec_arg0 = stringof(arg0);
106}
107
108proc:::exec-failure /* probe ID $(( $ID + 3 )) */
109{${TRACE:+
110	printf("<$(( $ID + 3 ))>");
111}
112	/* details = "<arg0 from proc:::exec>: <strerror of arg0> (<arg0>)" */
113	this->details = strjoin(
114		strjoin(this->exec_arg0, ": "),
115		strjoin(strerror[(int)arg0],
116			strjoin(" (", strjoin(lltostr((int)arg0), ")"))));
117}
118
119proc:::exec-success /* probe ID $(( $ID + 4 )) */
120{${TRACE:+
121	printf("<$(( $ID + 4 ))>");}
122	this->details = this->args0;
123}
124
125proc:::exit /* probe ID $(( $ID + 5 )) */
126{${TRACE:+
127	printf("<$(( $ID + 5 ))>");}
128	this->details = child_signal_string[(int)arg0];
129}
130
131proc:::signal-clear /* probe ID $(( $ID + 6 )) */
132{${TRACE:+
133	printf("<$(( $ID + 6 ))>");}
134	this->pid = (pid_t)((ksiginfo_t *)args[1])->ksi_info.si_pid;
135	this->sig = (int)arg0;
136}
137
138proc:::signal-discard, proc:::signal-send /* probe ID $(( $ID + 7 )) */
139{${TRACE:+
140	printf("<$(( $ID + 7 ))>");}
141	this->pid = (pid_t)((struct proc *)args[1])->p_pid;
142	this->sig = (int)arg2;
143}
144
145proc:::signal-clear,
146proc:::signal-discard,
147proc:::signal-send /* probe ID $(( $ID + 8 )) */
148{${TRACE:+
149	printf("<$(( $ID + 8 ))>");
150}
151	/* details = "<signal>[<num>] pid <pid>" */
152	this->details = strjoin(strjoin(signal_string[this->sig], "["),
153		strjoin(strjoin(lltostr(this->sig), "] pid "),
154		lltostr(this->pid)));
155}
156
157proc:::signal-send, proc:::signal-discard /* probe ID $(( $ID + 9 )) */
158{${TRACE:+
159	printf("<$(( $ID + 9 ))>");
160}
161	$( pproc -P _signal "(struct proc *)args[1]" )
162
163	this->details = strjoin(this->details,
164		strjoin(" -- ", this->args_signal));
165}
166EOF
167ACTIONS=$( cat <&9 )
168ID=$(( $ID + 10 ))
169
170############################################################ EVENT DETAILS
171
172if [ ! "$CUSTOM_DETAILS" ]; then
173exec 9<<EOF
174	/*
175	 * Print details
176	 */
177	printf("%s %s", probealias[probename], this->details);
178EOF
179EVENT_DETAILS=$( cat <&9 )
180fi
181
182################################################################################
183# END
184################################################################################
185