182 lines
4.9 KiB
D
Executable File
182 lines
4.9 KiB
D
Executable File
#!/usr/sbin/dtrace -Cs
|
|
/*
|
|
* crash.d - Crashed Application info.
|
|
* Written in DTrace (Solaris 10 3/05).
|
|
*
|
|
* $Id: crash.d 3 2007-08-01 10:50:08Z brendan $
|
|
*
|
|
* When applications crash via a SIGSEGV or SIGBUS, a report of the
|
|
* process state is printed out.
|
|
*
|
|
* USAGE: crash.d
|
|
*
|
|
* FIELDS:
|
|
* Type Signal type
|
|
* Program Execname of process
|
|
* Agrs Argument listing of process
|
|
* PID Process ID
|
|
* TID Thread ID
|
|
* LWPs Number of Light Weight Processes
|
|
* PPID Parent Process ID
|
|
* UID User ID
|
|
* GID Group ID
|
|
* TaskID Task ID
|
|
* ProjID Project ID
|
|
* PoolID Pool ID
|
|
* ZoneID Zone ID
|
|
* zone Zone name
|
|
* CWD Current working directory
|
|
* errno Error number of last syscall
|
|
*
|
|
* SEE ALSO: mdb, pstack, coreadm
|
|
* app_crash.d - Greg Nakhimovsky & Morgan Herrington
|
|
*
|
|
* COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
|
|
*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License, Version 1.0 only
|
|
* (the "License"). You may not use this file except in compliance
|
|
* with the License.
|
|
*
|
|
* You can obtain a copy of the license at Docs/cddl1.txt
|
|
* or http://www.opensolaris.org/os/licensing.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* CDDL HEADER END
|
|
*
|
|
* 29-May-2005 Brendan Gregg Created this.
|
|
* 24-Apr-2006 " " Last update.
|
|
*/
|
|
|
|
#pragma D option quiet
|
|
#pragma D option destructive
|
|
|
|
dtrace:::BEGIN
|
|
{
|
|
printf("Waiting for crashing applications...\n");
|
|
}
|
|
|
|
/*
|
|
* Print Report Header
|
|
*/
|
|
proc:::signal-send
|
|
/(args[2] == SIGBUS || args[2] == SIGSEGV) && pid == args[1]->pr_pid/
|
|
{
|
|
stop();
|
|
self->elapsed = timestamp - curthread->t_procp->p_mstart;
|
|
self->crash = 1;
|
|
|
|
printf("\n-----------------------------------------------------\n");
|
|
printf("CRASH DETECTED at %Y\n", walltimestamp);
|
|
printf("-----------------------------------------------------\n");
|
|
printf("Type: %s\n", args[2] == SIGBUS ? "SIGBUS" : "SIGSEGV");
|
|
printf("Program: %s\n", execname);
|
|
printf("Args: %S\n", curpsinfo->pr_psargs);
|
|
printf("PID: %d\n", pid);
|
|
printf("TID: %d\n", tid);
|
|
printf("LWPs: %d\n", curthread->t_procp->p_lwpcnt);
|
|
printf("PPID: %d\n", ppid);
|
|
printf("UID: %d\n", uid);
|
|
printf("GID: %d\n", gid);
|
|
printf("TaskID: %d\n", curpsinfo->pr_taskid);
|
|
printf("ProjID: %d\n", curpsinfo->pr_projid);
|
|
printf("PoolID: %d\n", curpsinfo->pr_poolid);
|
|
printf("ZoneID: %d\n", curpsinfo->pr_zoneid);
|
|
printf("zone: %s\n", zonename);
|
|
printf("CWD: %s\n", cwd);
|
|
printf("errno: %d\n", errno);
|
|
|
|
printf("\nUser Stack Backtrace,");
|
|
ustack();
|
|
|
|
printf("\nKernel Stack Backtrace,");
|
|
stack();
|
|
}
|
|
|
|
/*
|
|
* Print Java Details
|
|
*/
|
|
proc:::signal-send
|
|
/self->crash && execname == "java"/
|
|
{
|
|
printf("\nJava Stack Backtrace,");
|
|
jstack();
|
|
}
|
|
|
|
/*
|
|
* Print Ancestors
|
|
*/
|
|
proc:::signal-send
|
|
/self->crash/
|
|
{
|
|
printf("\nAnsestors,\n");
|
|
self->level = 1;
|
|
self->procp = curthread->t_procp;
|
|
self->ptr = self->procp;
|
|
}
|
|
|
|
/* ancestory un-rolled loop, reverse order, 6 deep */
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
proc:::signal-send /self->crash && self->ptr != 0/
|
|
{
|
|
printf("%*s %d %S\n", self->level += 2, "",
|
|
self->ptr->p_pidp->pid_id, self->ptr->p_user.u_psargs);
|
|
self->ptr = self->ptr->p_parent;
|
|
}
|
|
|
|
/*
|
|
* Print Report Footer
|
|
*/
|
|
proc:::signal-send
|
|
/self->crash/
|
|
{
|
|
|
|
printf("\nTimes,\n");
|
|
printf(" User: %d ticks\n", self->procp->p_utime);
|
|
printf(" Sys: %d ticks\n", self->procp->p_stime);
|
|
printf(" Elapsed: %d ms\n", self->elapsed/1000000);
|
|
|
|
printf("\nSizes,\n");
|
|
printf(" Heap: %d bytes\n", self->procp->p_brksize);
|
|
printf(" Stack: %d bytes\n", self->procp->p_stksize);
|
|
|
|
self->ptr = 0;
|
|
self->procp = 0;
|
|
self->crash = 0;
|
|
self->level = 0;
|
|
self->elapsed = 0;
|
|
system("/usr/bin/prun %d", pid);
|
|
}
|