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