xref: /netbsd-src/external/cddl/dtracetoolkit/dist/Proc/crash.d (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
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