crash.d revision 259065
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 3 2007-08-01 10:50:08Z brendan $
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
57dtrace:::BEGIN
58{
59	printf("Waiting for crashing applications...\n");
60}
61
62/*
63 * Print Report Header
64 */
65proc:::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 */
102proc:::signal-send
103/self->crash && execname == "java"/
104{
105	printf("\nJava Stack Backtrace,");
106	jstack();
107}
108
109/*
110 * Print Ancestors
111 */
112proc:::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 */
122proc:::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}
128proc:::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}
134proc:::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}
140proc:::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}
146proc:::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}
152proc:::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 */
162proc:::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