View Source

{anchor:top}
h1. {anchor:CHP-SCRIPT} Scripting
You can use the [{{dtrace}}(1M)|http://docs.sun.com/doc/819-2240/dtrace-1m?a=view] utility to create interpreter files out of D programs similar to shell scripts that you can install as reusable interactive DTrace tools. The D compiler and {{dtrace}} command provide a set of _macro variables_ that are expanded by the D compiler that make it easy to create DTrace scripts. This chapter provides a reference for the macro variable facility and tips for creating persistent scripts.

[Top|#top]
h2. {anchor:CHP-SCRIPT-1} Interpreter Files
Similar to your shell and utilities such as [{{awk}}(1)|http://docs.sun.com/doc/819-2239/awk-1?a=view] and [{{perl}}(1)|http://docs.sun.com/doc/819-2239/perl-1?a=view], [{{dtrace}}(1M)|http://docs.sun.com/doc/819-2240/dtrace-1m?a=view] can be used to create executable interpreter files. An interpreter file begins with a line of the form:\\
{noformat}
#! pathname [arg]
{noformat}
\\where _pathname_ is the path of the interpreter and _arg_ is a single optional argument. When an interpreter file is executed, the system invokes the specified interpreter. If _arg_ was specified in the interpreter file, it is passed as an argument to the interpreter. The path to the interpreter file itself and any additional arguments specified when it was executed are then appended to the interpreter argument list. Therefore, you will always need to create DTrace interpreter files with at least these arguments:
{noformat}
#!/usr/sbin/dtrace -s
{noformat}
When your interpreter file is executed, the argument to the \-s option will therefore be the pathname of the interpreter file itself. {{dtrace}} will then read, compile, and execute this file as if you had typed the following command in your shell:
{noformat}
# dtrace -s interpreter-file
{noformat}
The following example shows how to create and execute a {{dtrace}} interpreter file. Type the following D source code and save it in a file named {{interp.d}}:
{noformat}
#!/usr/sbin/dtrace -s

BEGIN
{
trace("hello");
exit(0);
}
{noformat}
Mark the {{interp.d}} file as executable and execute it as follows:
{noformat}
# chmod a+rx interp.d
# ./interp.d
dtrace: script './interp.d' matched 1 probe
CPU ID FUNCTION:NAME
1 1 :BEGIN hello
#
{noformat}
Remember that the {{#!}} directive must comprise the first two characters of your file with no intervening or preceding whitespace. The D compiler knows to automatically ignore this line when it processes the interpreter file.\\
\\ {{dtrace}} uses [{{getopt}}(3C)|http://docs.sun.com/doc/819-2243/getopt-3c?a=view] to process command-line options, so you can combine multiple options in your single interpreter argument. For example, to add the \-q option to the preceding example you could change the interpreter directive to:
{noformat}
#!/usr/sbin/dtrace -qs
{noformat}
If you specify multiple option letters, the \-s option must always end the list of boolean options so that the next argument (the interpreter file name) is processed as the argument corresponding to the \-s option.\\
\\If you need to specify more than one option that requires an argument in your interpreter file, you will not be able to fit all your options and arguments into the single interpreter argument. Instead, use the {{#pragma D option}} directive syntax to set your options. All of the {{dtrace}} command-line options have {{#pragma}} equivalents that you can use, as shown in [Chapter 16, Options and Tunables|Options and Tunables].

[Top|#top]
h2. {anchor:CHP-SCRIPT-2} Macro Variables
The D compiler defines a set of built-in macro variables that you can use when writing D programs or interpreter files. Macro variables are identifiers that are prefixed with a dollar sign ({{$}}) and are expanded once by the D compiler when processing your input file. The D compiler provides the following macro variables:
h6. {anchor:TBL-MACROS} D Macro Variables
||Name||Description||Reference||
|{{$[0-9]+}}|macro arguments|See [Macro Arguments|#CHP-SCRIPT-3]|
|{{$egid}}|effective group-ID|[{{getegid}}(2)|http://docs.sun.com/doc/819-2241/getegid-2?a=view]|
|{{$euid}}|effective user-ID|[{{geteuid}}(2)|http://docs.sun.com/doc/819-2241/geteuid-2?a=view]|
|{{$gid}}|real group-ID|[{{getgid}}(2)|http://docs.sun.com/doc/819-2241/getgid-2?a=view]|
|{{$pid}}|process ID|[{{getpid}}(2)|http://docs.sun.com/doc/819-2241/getpid-2?a=view]|
|{{$pgid}}|process group ID|[{{getpgid}}(2)|http://docs.sun.com/doc/819-2241/getpgid-2?a=view]|
|{{$ppid}}|parent process ID|[{{getppid}}(2)|http://docs.sun.com/doc/819-2241/getppid-2?a=view]|
|{{$projid}}|project ID|[{{getprojid}}(2)|http://docs.sun.com/doc/819-2241/getprojid-2?a=view]|
|{{$sid}}|session ID|[{{getsid}}(2)|http://docs.sun.com/doc/819-2241/getsid-2?a=view]|
|{{$target}}|target process ID|See [Target Process ID|#chp-script-4]|
|{{$taskid}}|task ID|[{{gettaskid}}(2)|http://docs.sun.com/doc/819-2241/gettaskid-2?a=view]|
|{{$uid}}|real user-ID|[{{getuid}}(2)|http://docs.sun.com/doc/819-2241/getuid-2?a=view]|
Except for the {{$[0-9]+}} macro arguments and the {{$target}} macro variable, the macro variables all expand to integers corresponding to system attributes such as the process ID and user ID. The variables expand to the attribute value associated with the current {{dtrace}} process itself, or whatever process is running the D compiler.\\
\\Using macro variables in interpreter files enables you to create persistent D programs that do not need to be edited each time you want to use them. For example, to count all system calls except those executed by the {{dtrace}} command, you can use the following D program clause containing {{$pid}}:
{noformat}
syscall:::entry
/pid != $pid/
{
@calls = count();
}
{noformat}
This clause always produces the desired result, even though each invocation of the {{dtrace}} command will have a different process ID.\\
\\Macro variables can be used anywhere an integer, identifier, or string can be used in a D program. Macro variables are expanded only once (that is, not recursively) when the input file is parsed. Each macro variable is expanded to form a separate input token, and cannot be concatenated with other text to yield a single token. For example, if {{$pid}} expands to the value 456, the D code:
{noformat}
123$pid
{noformat}
would expand to the two adjacent tokens 123 and 456, resulting in a syntax error, rather than the single integer token 123456.\\
\\Macro variables are expanded and concatenated with adjacent text inside of D probe descriptions at the start of your program clauses. For example, the following clause uses the DTrace {{pid}} provider to instrument the {{dtrace}} command:
{noformat}
pid$pid:libc.so:printf:entry
{
...
}
{noformat}
Macro variables are only expanded once within each probe description field; they may not contain probe description delimiters ({{:}}).

[Top|#top]
h2. {anchor:CHP-SCRIPT-3} Macro Arguments
The D compiler also provides a set of macro variables corresponding to any additional argument operands specified as part of the {{dtrace}} command invocation. These _macro arguments_ are accessed using the built-in names {{$0}} for name of the D program file or {{dtrace}} command, {{$1}} for the first additional operand, {{$2}} for the second operand, and so on. If you use the {{dtrace}} \-s option, {{$0}} expands to the value of the name of the input file used with this option. For D programs specified on the command-line, {{$0}} expands to the value of {{argv[0]}} used to exec {{dtrace}} itself.\\
\\Macro arguments can expand to integers, identifiers, or strings, depending on the form of the corresponding text. As with all macro variables, macro arguments can be used anywhere integer, identifier, and string tokens can be used in a D program. All of the following examples could form valid D expressions assuming appropriate macro argument values:
{noformat}
execname == $1 /* with a string macro argument */
x += $1 /* with an integer macro argument */
trace(x->$1) /* with an identifier macro argument */
{noformat}
Macro arguments can be used to create {{dtrace}} interpreter files that act like real Solaris commands and use information specified by a user or by another tool to modify their behavior. For example, the following D interpreter file traces [{{write}}(2)|http://docs.sun.com/doc/819-2241/write-2?a=view] system calls executed by a particular process ID:
{noformat}
#!/usr/sbin/dtrace -s
syscall::write:entry
/pid == $1/
{
}
{noformat}
If you make this interpreter file executable, you can specify the value of {{$1}} using an additional command-line argument to your interpreter file:
{noformat}
# chmod a+rx ./tracewrite
# ./tracewrite 12345
{noformat}
The resulting command invocation counts each [{{write}}(2)|http://docs.sun.com/doc/819-2241/write-2?a=view] system call executed by process ID 12345.\\
\\If your D program references a macro argument that is not provided on the command-line, an appropriate error message will be printed and your program will fail to compile:
{noformat}
# ./tracewrite
dtrace: failed to compile script ./tracewrite: line 4:
macro argument $1 is not defined
{noformat}
D programs can reference unspecified macro arguments if the {{defaultargs}} option is set. If {{defaultargs}} is set, unspecified arguments will have the value {{0}}. See [Chapter 16, Options and Tunables|Options and Tunables] for more information about D compiler options. The D compiler will also produce an error message if additional arguments are specified on the command line that are not referenced by your D program.\\
\\The macro argument values must match the form of an integer, identifier, or string. If the argument does not match any of these forms, the D compiler will report an appropriate error message. When specifying string macro arguments to a DTrace interpreter file, surround the argument in an extra pair of single quotes to avoid interpretation of the double quotes and string contents by your shell:
{noformat}
# ./foo '"a string argument"'
{noformat}
If you want your D macro arguments to be interpreted as string tokens even if they match the form of an integer or identifier, prefix the macro variable or argument name with two leading dollar signs (for example, {{$$1}}) to force the D compiler to interpret the argument value as if it were a string surrounded by double quotes. All the usual D string escape sequences (see [Table 2–5|Types, Operators and Expressions#TBL-ESCS]) are expanded inside of any string macro arguments, regardless of whether they are referenced using the {{$}}_arg_ or {{$$}}_arg_ form of the macro. If the {{defaultargs}} option is set, unspecified arguments that are referenced with the {{$$}}_arg_ form have the value of the empty string ({{""}}).

[Top|#top]
h2. {anchor:CHP-SCRIPT-4} Target Process ID
Use the {{$target}} macro variable to create scripts that can be applied to a particular user process of interest that is selected on the {{dtrace}} command line using the \-p option or created using the \-c option. The D programs specified on the command line or using the \-s option are compiled _after_ processes are created or grabbed and the {{$target}} variable expands to the integer process-ID of the first such process. For example, the following D script could be used to determine the distribution of system calls executed by a particular subject process:
{noformat}
syscall:::entry
/pid == $target/
{
@[probefunc] = count();
}
{noformat}
To determine the number of system calls executed by the [{{date}}(1)|http://docs.sun.com/doc/819-2239/date-1?a=view] command, save the script in the file {{syscall.d}} and execute the following command:
{noformat}
# dtrace -s syscall.d -c date
dtrace: script 'syscall.d' matched 227 probes
Fri Jul 30 13:46:06 PDT 2004
dtrace: pid 109058 has exited

gtime 1
getpid 1
getrlimit 1
rexit 1
ioctl 1
resolvepath 1
read 1
stat 1
write 1
munmap 1
close 2
fstat64 2
setcontext 2
mmap 2
open 2
brk 4
{noformat}
{excerpt:hidden=true}Converted by tech dogg's sgml2wiki on Tue 20 Nov 2007 at 9:27:20 PM{excerpt}

The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

Copyright 1994-2009 Sun Microsystems, Inc.
Powered by Atlassian Confluence
Sun Guidelines on Public Discourse Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact