#!/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);
}