1*387f9dfdSAndroid Build Coastguard WorkerDemonstrations of exitsnoop. 2*387f9dfdSAndroid Build Coastguard Worker 3*387f9dfdSAndroid Build Coastguard WorkerThis Linux tool traces all process terminations and reason, it 4*387f9dfdSAndroid Build Coastguard Worker - is implemented using BPF, which requires CAP_SYS_ADMIN and 5*387f9dfdSAndroid Build Coastguard Worker should therefore be invoked with sudo 6*387f9dfdSAndroid Build Coastguard Worker - traces sched_process_exit tracepoint in kernel/exit.c 7*387f9dfdSAndroid Build Coastguard Worker - includes processes by root and all users 8*387f9dfdSAndroid Build Coastguard Worker - includes processes in containers 9*387f9dfdSAndroid Build Coastguard Worker - includes processes that become zombie 10*387f9dfdSAndroid Build Coastguard Worker 11*387f9dfdSAndroid Build Coastguard WorkerThe following example shows the termination of the 'sleep' and 'bash' commands 12*387f9dfdSAndroid Build Coastguard Workerwhen run in a loop that is interrupted with Ctrl-C from the terminal: 13*387f9dfdSAndroid Build Coastguard Worker 14*387f9dfdSAndroid Build Coastguard Worker# ./exitsnoop.py > exitlog & 15*387f9dfdSAndroid Build Coastguard Worker[1] 18997 16*387f9dfdSAndroid Build Coastguard Worker# for((i=65;i<100;i+=5)); do bash -c "sleep 1.$i;exit $i"; done 17*387f9dfdSAndroid Build Coastguard Worker^C 18*387f9dfdSAndroid Build Coastguard Worker# fg 19*387f9dfdSAndroid Build Coastguard Worker./exitsnoop.py > exitlog 20*387f9dfdSAndroid Build Coastguard Worker^C 21*387f9dfdSAndroid Build Coastguard Worker# cat exitlog 22*387f9dfdSAndroid Build Coastguard WorkerPCOMM PID PPID TID AGE(s) EXIT_CODE 23*387f9dfdSAndroid Build Coastguard Workersleep 19004 19003 19004 1.65 0 24*387f9dfdSAndroid Build Coastguard Workerbash 19003 17656 19003 1.65 code 65 25*387f9dfdSAndroid Build Coastguard Workersleep 19007 19006 19007 1.70 0 26*387f9dfdSAndroid Build Coastguard Workerbash 19006 17656 19006 1.70 code 70 27*387f9dfdSAndroid Build Coastguard Workersleep 19010 19009 19010 1.75 0 28*387f9dfdSAndroid Build Coastguard Workerbash 19009 17656 19009 1.75 code 75 29*387f9dfdSAndroid Build Coastguard Workersleep 19014 19013 19014 0.23 signal 2 (INT) 30*387f9dfdSAndroid Build Coastguard Workerbash 19013 17656 19013 0.23 signal 2 (INT) 31*387f9dfdSAndroid Build Coastguard Worker 32*387f9dfdSAndroid Build Coastguard Worker# 33*387f9dfdSAndroid Build Coastguard Worker 34*387f9dfdSAndroid Build Coastguard WorkerThe output shows the process/command name (PCOMM), the PID, 35*387f9dfdSAndroid Build Coastguard Workerthe process that will be notified (PPID), the thread (TID), the AGE 36*387f9dfdSAndroid Build Coastguard Workerof the process with hundredth of a second resolution, and the reason for 37*387f9dfdSAndroid Build Coastguard Workerthe process exit (EXIT_CODE). 38*387f9dfdSAndroid Build Coastguard Worker 39*387f9dfdSAndroid Build Coastguard WorkerA -t option can be used to include a timestamp column, it shows local time 40*387f9dfdSAndroid Build Coastguard Workerby default. The --utc option shows the time in UTC. The --label 41*387f9dfdSAndroid Build Coastguard Workeroption adds a column indicating the tool that generated the output, 42*387f9dfdSAndroid Build Coastguard Worker'exit' by default. If other tools follow this format their outputs 43*387f9dfdSAndroid Build Coastguard Workercan be merged into a single trace with a simple lexical sort 44*387f9dfdSAndroid Build Coastguard Workerincreasing in time order with each line labeled to indicate the event, 45*387f9dfdSAndroid Build Coastguard Workere.g. 'exec', 'open', 'exit', etc. Time is displayed with millisecond 46*387f9dfdSAndroid Build Coastguard Workerresolution. The -x option will show only non-zero exits and fatal 47*387f9dfdSAndroid Build Coastguard Workersignals, which excludes processes that exit with 0 code: 48*387f9dfdSAndroid Build Coastguard Worker 49*387f9dfdSAndroid Build Coastguard Worker# ./exitsnoop.py -t --utc -x --label= > exitlog & 50*387f9dfdSAndroid Build Coastguard Worker[1] 18289 51*387f9dfdSAndroid Build Coastguard Worker# for((i=65;i<100;i+=5)); do bash -c "sleep 1.$i;exit $i"; done 52*387f9dfdSAndroid Build Coastguard Worker^C 53*387f9dfdSAndroid Build Coastguard Worker# fg 54*387f9dfdSAndroid Build Coastguard Worker./exitsnoop.py -t --utc -x --label= > exitlog 55*387f9dfdSAndroid Build Coastguard Worker^C 56*387f9dfdSAndroid Build Coastguard Worker# cat exitlog 57*387f9dfdSAndroid Build Coastguard WorkerTIME-UTC LABEL PCOMM PID PPID TID AGE(s) EXIT_CODE 58*387f9dfdSAndroid Build Coastguard Worker13:20:22.997 exit bash 18300 17656 18300 1.65 code 65 59*387f9dfdSAndroid Build Coastguard Worker13:20:24.701 exit bash 18303 17656 18303 1.70 code 70 60*387f9dfdSAndroid Build Coastguard Worker13:20:26.456 exit bash 18306 17656 18306 1.75 code 75 61*387f9dfdSAndroid Build Coastguard Worker13:20:28.260 exit bash 18310 17656 18310 1.80 code 80 62*387f9dfdSAndroid Build Coastguard Worker13:20:30.113 exit bash 18313 17656 18313 1.85 code 85 63*387f9dfdSAndroid Build Coastguard Worker13:20:31.495 exit sleep 18318 18317 18318 1.38 signal 2 (INT) 64*387f9dfdSAndroid Build Coastguard Worker13:20:31.495 exit bash 18317 17656 18317 1.38 signal 2 (INT) 65*387f9dfdSAndroid Build Coastguard Worker# 66*387f9dfdSAndroid Build Coastguard Worker 67*387f9dfdSAndroid Build Coastguard WorkerUSAGE message: 68*387f9dfdSAndroid Build Coastguard Worker 69*387f9dfdSAndroid Build Coastguard Worker# ./exitsnoop.py -h 70*387f9dfdSAndroid Build Coastguard Workerusage: exitsnoop.py [-h] [-t] [--utc] [-p PID] [--label LABEL] [-x] [--per-thread] 71*387f9dfdSAndroid Build Coastguard Worker 72*387f9dfdSAndroid Build Coastguard WorkerTrace all process termination (exit, fatal signal) 73*387f9dfdSAndroid Build Coastguard Worker 74*387f9dfdSAndroid Build Coastguard Workeroptional arguments: 75*387f9dfdSAndroid Build Coastguard Worker -h, --help show this help message and exit 76*387f9dfdSAndroid Build Coastguard Worker -t, --timestamp include timestamp (local time default) 77*387f9dfdSAndroid Build Coastguard Worker --utc include timestamp in UTC (-t implied) 78*387f9dfdSAndroid Build Coastguard Worker -p PID, --pid PID trace this PID only 79*387f9dfdSAndroid Build Coastguard Worker --label LABEL label each line 80*387f9dfdSAndroid Build Coastguard Worker -x, --failed trace only fails, exclude exit(0) 81*387f9dfdSAndroid Build Coastguard Worker --per-thread trace per thread termination 82*387f9dfdSAndroid Build Coastguard Worker 83*387f9dfdSAndroid Build Coastguard Workerexamples: 84*387f9dfdSAndroid Build Coastguard Worker exitsnoop # trace all process termination 85*387f9dfdSAndroid Build Coastguard Worker exitsnoop -x # trace only fails, exclude exit(0) 86*387f9dfdSAndroid Build Coastguard Worker exitsnoop -t # include timestamps (local time) 87*387f9dfdSAndroid Build Coastguard Worker exitsnoop --utc # include timestamps (UTC) 88*387f9dfdSAndroid Build Coastguard Worker exitsnoop -p 181 # only trace PID 181 89*387f9dfdSAndroid Build Coastguard Worker exitsnoop --label=exit # label each output line with 'exit' 90*387f9dfdSAndroid Build Coastguard Worker exitsnoop --per-thread # trace per thread termination 91*387f9dfdSAndroid Build Coastguard Worker 92*387f9dfdSAndroid Build Coastguard WorkerExit status: 93*387f9dfdSAndroid Build Coastguard Worker 94*387f9dfdSAndroid Build Coastguard Worker 0 EX_OK Success 95*387f9dfdSAndroid Build Coastguard Worker 2 argparse error 96*387f9dfdSAndroid Build Coastguard Worker 70 EX_SOFTWARE syntax error detected by compiler, or 97*387f9dfdSAndroid Build Coastguard Worker verifier error from kernel 98*387f9dfdSAndroid Build Coastguard Worker 77 EX_NOPERM Need sudo (CAP_SYS_ADMIN) for BPF() system call 99*387f9dfdSAndroid Build Coastguard Worker 100*387f9dfdSAndroid Build Coastguard WorkerAbout process termination in Linux 101*387f9dfdSAndroid Build Coastguard Worker---------------------------------- 102*387f9dfdSAndroid Build Coastguard Worker 103*387f9dfdSAndroid Build Coastguard WorkerA program/process on Linux terminates normally 104*387f9dfdSAndroid Build Coastguard Worker - by explicitly invoking the exit( int ) system call 105*387f9dfdSAndroid Build Coastguard Worker - in C/C++ by returning an int from main(), 106*387f9dfdSAndroid Build Coastguard Worker ...which is then used as the value for exit() 107*387f9dfdSAndroid Build Coastguard Worker - by reaching the end of main() without a return 108*387f9dfdSAndroid Build Coastguard Worker ...which is equivalent to return 0 (C99 and C++) 109*387f9dfdSAndroid Build Coastguard Worker Notes: 110*387f9dfdSAndroid Build Coastguard Worker - Linux keeps only the least significant eight bits of the exit value 111*387f9dfdSAndroid Build Coastguard Worker - an exit value of 0 means success 112*387f9dfdSAndroid Build Coastguard Worker - an exit value of 1-255 means an error 113*387f9dfdSAndroid Build Coastguard Worker 114*387f9dfdSAndroid Build Coastguard WorkerA process terminates abnormally if it 115*387f9dfdSAndroid Build Coastguard Worker - receives a signal which is not ignored or blocked and has no handler 116*387f9dfdSAndroid Build Coastguard Worker ... the default action is to terminate with optional core dump 117*387f9dfdSAndroid Build Coastguard Worker - is selected by the kernel's "Out of Memory Killer", 118*387f9dfdSAndroid Build Coastguard Worker equivalent to being sent SIGKILL (9), which cannot be ignored or blocked 119*387f9dfdSAndroid Build Coastguard Worker Notes: 120*387f9dfdSAndroid Build Coastguard Worker - any signal can be sent asynchronously via the kill() system call 121*387f9dfdSAndroid Build Coastguard Worker - synchronous signals are the result of the CPU detecting 122*387f9dfdSAndroid Build Coastguard Worker a fault or trap during execution of the program, a kernel handler 123*387f9dfdSAndroid Build Coastguard Worker is dispatched which determines the cause and the corresponding 124*387f9dfdSAndroid Build Coastguard Worker signal, examples are 125*387f9dfdSAndroid Build Coastguard Worker - attempting to fetch data or instructions at invalid or 126*387f9dfdSAndroid Build Coastguard Worker privileged addresses, 127*387f9dfdSAndroid Build Coastguard Worker - attempting to divide by zero, unmasked floating point exceptions 128*387f9dfdSAndroid Build Coastguard Worker - hitting a breakpoint 129*387f9dfdSAndroid Build Coastguard Worker 130*387f9dfdSAndroid Build Coastguard WorkerLinux keeps process termination information in 'exit_code', an int 131*387f9dfdSAndroid Build Coastguard Workerwithin struct 'task_struct' defined in <linux/sched.c> 132*387f9dfdSAndroid Build Coastguard Worker - if the process terminated normally: 133*387f9dfdSAndroid Build Coastguard Worker - the exit value is in bits 15:8 134*387f9dfdSAndroid Build Coastguard Worker - the least significant 8 bits of exit_code are zero (bits 7:0) 135*387f9dfdSAndroid Build Coastguard Worker - if the process terminates abnormally: 136*387f9dfdSAndroid Build Coastguard Worker - the signal number (>= 1) is in bits 6:0 137*387f9dfdSAndroid Build Coastguard Worker - bit 7 indicates a 'core dump' action, whether a core dump was 138*387f9dfdSAndroid Build Coastguard Worker actually done depends on ulimit. 139*387f9dfdSAndroid Build Coastguard Worker 140*387f9dfdSAndroid Build Coastguard WorkerSuccess is indicated with an exit value of zero. 141*387f9dfdSAndroid Build Coastguard WorkerThe meaning of a non zero exit value depends on the program. 142*387f9dfdSAndroid Build Coastguard WorkerSome programs document their exit values and their meaning. 143*387f9dfdSAndroid Build Coastguard WorkerThis script uses exit values as defined in <include/sysexits.h> 144*387f9dfdSAndroid Build Coastguard Worker 145*387f9dfdSAndroid Build Coastguard WorkerReferences: 146*387f9dfdSAndroid Build Coastguard Worker 147*387f9dfdSAndroid Build Coastguard Worker https://github.com/torvalds/linux/blob/master/kernel/exit.c 148*387f9dfdSAndroid Build Coastguard Worker https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/signal.h 149*387f9dfdSAndroid Build Coastguard Worker https://code.woboq.org/userspace/glibc/misc/sysexits.h.html 150*387f9dfdSAndroid Build Coastguard Worker 151