1 #!/usr/sbin/dtrace -Cs 2 /* 3 * crash.d - Crashed Application info. 4 * Written in DTrace (Solaris 10 3/05). 5 * 6 * $Id: crash.d,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $ 7 * 8 * When applications crash via a SIGSEGV or SIGBUS, a report of the 9 * process state is printed out. 10 * 11 * USAGE: crash.d 12 * 13 * FIELDS: 14 * Type Signal type 15 * Program Execname of process 16 * Agrs Argument listing of process 17 * PID Process ID 18 * TID Thread ID 19 * LWPs Number of Light Weight Processes 20 * PPID Parent Process ID 21 * UID User ID 22 * GID Group ID 23 * TaskID Task ID 24 * ProjID Project ID 25 * PoolID Pool ID 26 * ZoneID Zone ID 27 * zone Zone name 28 * CWD Current working directory 29 * errno Error number of last syscall 30 * 31 * SEE ALSO: mdb, pstack, coreadm 32 * app_crash.d - Greg Nakhimovsky & Morgan Herrington 33 * 34 * COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 35 * 36 * CDDL HEADER START 37 * 38 * The contents of this file are subject to the terms of the 39 * Common Development and Distribution License, Version 1.0 only 40 * (the "License"). You may not use this file except in compliance 41 * with the License. 42 * 43 * You can obtain a copy of the license at Docs/cddl1.txt 44 * or http://www.opensolaris.org/os/licensing. 45 * See the License for the specific language governing permissions 46 * and limitations under the License. 47 * 48 * CDDL HEADER END 49 * 50 * 29-May-2005 Brendan Gregg Created this. 51 * 24-Apr-2006 " " Last update. 52 */ 53 54 #pragma D option quiet 55 #pragma D option destructive 56 57 dtrace:::BEGIN 58 { 59 printf("Waiting for crashing applications...\n"); 60 } 61 62 /* 63 * Print Report Header 64 */ 65 proc:::signal-send 66 /(args[2] == SIGBUS || args[2] == SIGSEGV) && pid == args[1]->pr_pid/ 67 { 68 stop(); 69 self->elapsed = timestamp - curthread->t_procp->p_mstart; 70 self->crash = 1; 71 72 printf("\n-----------------------------------------------------\n"); 73 printf("CRASH DETECTED at %Y\n", walltimestamp); 74 printf("-----------------------------------------------------\n"); 75 printf("Type: %s\n", args[2] == SIGBUS ? "SIGBUS" : "SIGSEGV"); 76 printf("Program: %s\n", execname); 77 printf("Args: %S\n", curpsinfo->pr_psargs); 78 printf("PID: %d\n", pid); 79 printf("TID: %d\n", tid); 80 printf("LWPs: %d\n", curthread->t_procp->p_lwpcnt); 81 printf("PPID: %d\n", ppid); 82 printf("UID: %d\n", uid); 83 printf("GID: %d\n", gid); 84 printf("TaskID: %d\n", curpsinfo->pr_taskid); 85 printf("ProjID: %d\n", curpsinfo->pr_projid); 86 printf("PoolID: %d\n", curpsinfo->pr_poolid); 87 printf("ZoneID: %d\n", curpsinfo->pr_zoneid); 88 printf("zone: %s\n", zonename); 89 printf("CWD: %s\n", cwd); 90 printf("errno: %d\n", errno); 91 92 printf("\nUser Stack Backtrace,"); 93 ustack(); 94 95 printf("\nKernel Stack Backtrace,"); 96 stack(); 97 } 98 99 /* 100 * Print Java Details 101 */ 102 proc:::signal-send 103 /self->crash && execname == "java"/ 104 { 105 printf("\nJava Stack Backtrace,"); 106 jstack(); 107 } 108 109 /* 110 * Print Ancestors 111 */ 112 proc:::signal-send 113 /self->crash/ 114 { 115 printf("\nAnsestors,\n"); 116 self->level = 1; 117 self->procp = curthread->t_procp; 118 self->ptr = self->procp; 119 } 120 121 /* ancestory un-rolled loop, reverse order, 6 deep */ 122 proc:::signal-send /self->crash && self->ptr != 0/ 123 { 124 printf("%*s %d %S\n", self->level += 2, "", 125 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 126 self->ptr = self->ptr->p_parent; 127 } 128 proc:::signal-send /self->crash && self->ptr != 0/ 129 { 130 printf("%*s %d %S\n", self->level += 2, "", 131 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 132 self->ptr = self->ptr->p_parent; 133 } 134 proc:::signal-send /self->crash && self->ptr != 0/ 135 { 136 printf("%*s %d %S\n", self->level += 2, "", 137 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 138 self->ptr = self->ptr->p_parent; 139 } 140 proc:::signal-send /self->crash && self->ptr != 0/ 141 { 142 printf("%*s %d %S\n", self->level += 2, "", 143 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 144 self->ptr = self->ptr->p_parent; 145 } 146 proc:::signal-send /self->crash && self->ptr != 0/ 147 { 148 printf("%*s %d %S\n", self->level += 2, "", 149 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 150 self->ptr = self->ptr->p_parent; 151 } 152 proc:::signal-send /self->crash && self->ptr != 0/ 153 { 154 printf("%*s %d %S\n", self->level += 2, "", 155 self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs); 156 self->ptr = self->ptr->p_parent; 157 } 158 159 /* 160 * Print Report Footer 161 */ 162 proc:::signal-send 163 /self->crash/ 164 { 165 166 printf("\nTimes,\n"); 167 printf(" User: %d ticks\n", self->procp->p_utime); 168 printf(" Sys: %d ticks\n", self->procp->p_stime); 169 printf(" Elapsed: %d ms\n", self->elapsed/1000000); 170 171 printf("\nSizes,\n"); 172 printf(" Heap: %d bytes\n", self->procp->p_brksize); 173 printf(" Stack: %d bytes\n", self->procp->p_stksize); 174 175 self->ptr = 0; 176 self->procp = 0; 177 self->crash = 0; 178 self->level = 0; 179 self->elapsed = 0; 180 system("/usr/bin/prun %d", pid); 181 } 182