1#!/usr/sbin/dtrace -s
2/*
3 * newproc.d - snoop new processes as they are executed. DTrace OneLiner.
4 *
5 * This is a DTrace OneLiner from the DTraceToolkit.
6 *
7 * 15-May-2005	Brendan Gregg	Created this.
8 */
9
10/*
11 * Updated to capture arguments in OS X. Unfortunately this isn't straight forward... nor inexpensive ...
12 * Bound the size of copyinstr()'s and printf incrementally to prevent "out of scratch space errors"
13 * print "(...)" if the length of an argument exceeds COPYINSTRLIMIT.
14 * print "<...>" if argc exceeds 5.
15 */
16
17#pragma D option quiet
18
19this unsigned long long argv_ptr; /* Wide enough for 64 bit user procs */
20inline int COPYINSTRLIMIT = 128;
21
22proc:::exec-success
23{
24	print_pid[pid] = 1; /* This pid emerged from an exec, make a note of that. */
25}
26
27/*
28 * The "this" variables are local to (all) of the following syscall::bsdthread_register:return probes,
29 * and only those probes. They must be initialized before use in each new firing.
30 */
31syscall::bsdthread_register:return
32{
33	this->argc = 0; /* Disable argument collection until we notice an exec-success */
34	this->need_newline = 0;
35}
36
37syscall::bsdthread_register:return
38/ print_pid[pid] /
39{
40	print_pid[pid] = 0;
41	this->is64Bit = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? 0 : 1;
42	this->wordsize = this->is64Bit ? 8 : 4;
43
44	this->argc = curpsinfo->pr_argc;
45	this->argc = (this->argc < 0) ? 0 : this->argc; /* Safety */
46
47	this->argv_ptr = curpsinfo->pr_argv;
48
49	printf("%Y %d <%d> %s ", walltimestamp, pid, ppid, this->is64Bit ? "64b" : "32b");
50	this->need_newline = 1;
51}
52
53syscall::bsdthread_register:return
54/ this->argc /
55{
56	this->here_argv = copyin(this->argv_ptr, this->wordsize);
57	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
58	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
59	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
60
61	this->argv_ptr += this->wordsize;
62	this->argc--;
63}
64
65syscall::bsdthread_register:return
66/ this->argc /
67{
68	this->here_argv = copyin(this->argv_ptr, this->wordsize);
69	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
70	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
71	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
72
73	this->argv_ptr += this->wordsize;
74	this->argc--;
75}
76
77syscall::bsdthread_register:return
78/ this->argc /
79{
80	this->here_argv = copyin(this->argv_ptr, this->wordsize);
81	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
82	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
83	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
84
85	this->argv_ptr += this->wordsize;
86	this->argc--;
87}
88
89syscall::bsdthread_register:return
90/ this->argc /
91{
92	this->here_argv = copyin(this->argv_ptr, this->wordsize);
93	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
94	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
95	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
96
97	this->argv_ptr += this->wordsize;
98	this->argc--;
99}
100
101syscall::bsdthread_register:return
102/ this->argc /
103{
104	this->here_argv = copyin(this->argv_ptr, this->wordsize);
105	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
106	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
107	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
108
109	this->argv_ptr += this->wordsize;
110	this->argc--;
111}
112
113syscall::bsdthread_register:return
114/ this->argc /
115{
116	this->here_argv = copyin(this->argv_ptr, this->wordsize);
117	this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
118	this->here_arg = copyinstr(this->arg, COPYINSTRLIMIT);
119	printf(" %s%s", this->here_arg, COPYINSTRLIMIT - 1 < strlen(this->here_arg) ? " (...)" : "");
120
121	this->argv_ptr += this->wordsize;
122	this->argc--;
123}
124
125
126syscall::bsdthread_register:return
127/ this->argc /
128{
129	printf(" <...>");
130	this->argc = 0;
131}
132
133syscall::bsdthread_register:return
134/ this->need_newline /
135{
136	printf("\n");
137	this->need_newline = 0;
138}
139
140ERROR
141/ arg4 == DTRACEFLT_NOSCRATCH /
142{
143	printf(" <...>\n");
144	this->argc = 0;
145	this->need_newline = 0;
146}
147
148
149