1#!/usr/bin/ksh
2#
3# lastwords - print last few syscalls for dying processes.
4#             Written using DTrace (Solaris 10 3/05).
5#
6# $Id: lastwords 3 2007-08-01 10:50:08Z brendan $
7#
8# This prints the last few system calls for processes matching
9# the given name, when they exit. This makes use of a ring buffer
10# so that the impact on the system is minimised.
11#
12# USAGE: lastwords command
13#    eg,
14#        lastwords netscape
15#
16# FIELDS:
17#           TIME     Time of syscall return, ns
18#           PID      Process ID
19#           EXEC     Process name (execname)
20#           SYSCALL  System call
21#           RETURN   Return value for system call
22#           ERR      errno for system call
23#
24# BASED ON: /usr/demo/dtrace/ring.d
25#
26# SEE ALSO: DTrace Guide "Buffers and Buffering" chapter (docs.sun.com)
27#           dtruss (DTraceToolkit)
28#
29# PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
30#
31# CDDL HEADER START
32#
33#  The contents of this file are subject to the terms of the
34#  Common Development and Distribution License, Version 1.0 only
35#  (the "License").  You may not use this file except in compliance
36#  with the License.
37#
38#  You can obtain a copy of the license at Docs/cddl1.txt
39#  or http://www.opensolaris.org/os/licensing.
40#  See the License for the specific language governing permissions
41#  and limitations under the License.
42#
43# CDDL HEADER END
44#
45# 09-Jun-2005	Brendan Gregg	Created this.
46# 20-Apr-2006	   "      "	Last update.
47#
48
49### Usage
50function usage
51{
52	cat <<-END >&2
53	USAGE: lastwords command
54	   eg,
55	       lastwords netscape
56	END
57	exit 1
58}
59
60### Process arguments
61if (( $# != 1 )); then
62        usage
63fi
64command=$1
65
66print "Tracing... Waiting for $command to exit..."
67
68### Run DTrace
69/usr/sbin/dtrace -n '
70 #pragma D option quiet
71 #pragma D option bufpolicy=ring
72 #pragma D option bufsize=16k
73
74 syscall:::return
75 /execname == $$1/
76 {
77	/* buffer syscall details */
78	printf("%-18d %5d %12s %12s %10x %3d\n",
79	    timestamp,pid,execname,probefunc,(int)arg0,errno);
80 }
81
82 proc::proc_exit:exit
83 /execname == $$1/
84 {
85	/* print, erm, footer */
86	printf("%-18s %5s %12s %12s %10s %3s\n",
87	    "TIME","PID","EXEC","SYSCALL","RETURN","ERR");
88	exit(0);
89 }
90' "$command"
91