diff options
author | William Cohen <wcohen@redhat.com> | 2008-12-11 10:10:20 -0500 |
---|---|---|
committer | William Cohen <wcohen@redhat.com> | 2008-12-11 10:10:20 -0500 |
commit | 1d2280102dad0e24ee51f865e142ef92b2b952a2 (patch) | |
tree | c903367168fc971898fff239b792182b526744ca /doc/SystemTap_Beginners_Guide/en-US | |
parent | 744cf3ab2a4735510874646ac720b4b28701f16f (diff) | |
parent | c8c12f3cc2181a1964611af79d69b3ffef4e0d34 (diff) | |
download | systemtap-steved-1d2280102dad0e24ee51f865e142ef92b2b952a2.tar.gz systemtap-steved-1d2280102dad0e24ee51f865e142ef92b2b952a2.tar.xz systemtap-steved-1d2280102dad0e24ee51f865e142ef92b2b952a2.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'doc/SystemTap_Beginners_Guide/en-US')
7 files changed, 681 insertions, 602 deletions
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml index 789bf607..bf496321 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml @@ -962,23 +962,23 @@ probe vfs.read <indexterm> <primary>array operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>count (integer extractor)</tertiary> +<tertiary>@count (integer extractor)</tertiary> </indexterm> <indexterm> <primary>operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>count (integer extractor)</tertiary> +<tertiary>@count (integer extractor)</tertiary> </indexterm> <indexterm> <primary>computing for statistical aggregates</primary> <secondary>array operations</secondary> -<tertiary>count (integer extractor)</tertiary> +<tertiary>@count (integer extractor)</tertiary> </indexterm> <indexterm> -<primary>count (integer extractor)</primary> + <primary>@count (integer extractor)</primary> <secondary>computing for statistical aggregates</secondary> <tertiary>array operations</tertiary> </indexterm> @@ -997,23 +997,23 @@ probe vfs.read <indexterm> <primary>array operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>sum (integer extractor)</tertiary> +<tertiary>@sum (integer extractor)</tertiary> </indexterm> <indexterm> <primary>operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>sum (integer extractor)</tertiary> +<tertiary>@sum (integer extractor)</tertiary> </indexterm> <indexterm> <primary>computing for statistical aggregates</primary> <secondary>array operations</secondary> -<tertiary>sum (integer extractor)</tertiary> +<tertiary>@sum (integer extractor)</tertiary> </indexterm> <indexterm> -<primary>sum (integer extractor)</primary> + <primary>@sum (integer extractor)</primary> <secondary>computing for statistical aggregates</secondary> <tertiary>array operations</tertiary> </indexterm> @@ -1033,23 +1033,23 @@ probe vfs.read <indexterm> <primary>array operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>min (integer extractor)</tertiary> +<tertiary>@min (integer extractor)</tertiary> </indexterm> <indexterm> <primary>operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>min (integer extractor)</tertiary> +<tertiary>@min (integer extractor)</tertiary> </indexterm> <indexterm> <primary>computing for statistical aggregates</primary> <secondary>array operations</secondary> -<tertiary>min (integer extractor)</tertiary> +<tertiary>@min (integer extractor)</tertiary> </indexterm> <indexterm> -<primary>min (integer extractor)</primary> + <primary>@min (integer extractor)</primary> <secondary>computing for statistical aggregates</secondary> <tertiary>array operations</tertiary> </indexterm> @@ -1069,23 +1069,23 @@ probe vfs.read <indexterm> <primary>array operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>max (integer extractor)</tertiary> +<tertiary>@max (integer extractor)</tertiary> </indexterm> <indexterm> <primary>operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>max (integer extractor)</tertiary> +<tertiary>@max (integer extractor)</tertiary> </indexterm> <indexterm> <primary>computing for statistical aggregates</primary> <secondary>array operations</secondary> -<tertiary>max (integer extractor)</tertiary> +<tertiary>@max (integer extractor)</tertiary> </indexterm> <indexterm> -<primary>max (integer extractor)</primary> + <primary>@max (integer extractor)</primary> <secondary>computing for statistical aggregates</secondary> <tertiary>array operations</tertiary> </indexterm> @@ -1105,23 +1105,23 @@ probe vfs.read <indexterm> <primary>array operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>avg (integer extractor)</tertiary> +<tertiary>@avg (integer extractor)</tertiary> </indexterm> <indexterm> <primary>operations</primary> <secondary>computing for statistical aggregates</secondary> -<tertiary>avg (integer extractor)</tertiary> +<tertiary>@avg (integer extractor)</tertiary> </indexterm> <indexterm> <primary>computing for statistical aggregates</primary> <secondary>array operations</secondary> -<tertiary>avg (integer extractor)</tertiary> +<tertiary>@avg (integer extractor)</tertiary> </indexterm> <indexterm> -<primary>avg (integer extractor)</primary> + <primary>@avg (integer extractor)</primary> <secondary>computing for statistical aggregates</secondary> <tertiary>array operations</tertiary> </indexterm> @@ -1163,7 +1163,7 @@ probe vfs.read } probe timer.s(3) { - foreach([var1,var2] in reads)
+ foreach([var1,var2] in reads) printf("%s (%d) : %d \n", var1, var2, @count(reads[var1,var2])) } </programlisting> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml b/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml index 63c3df04..ac320fcd 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml @@ -6,7 +6,7 @@ <title>Associative Arrays</title> <indexterm> <primary>arrays</primary> -<secondary>introduction</secondary> +<seealso>associative arrays</seealso> </indexterm> <indexterm> @@ -20,11 +20,13 @@ <!-- next 2 indexterms for key pairs --> +<!-- <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>key pairs</tertiary> </indexterm> +--> <indexterm> <primary>associative arrays</primary> @@ -38,14 +40,14 @@ <tertiary>arrays</tertiary> </indexterm> -<!-- next 2 indexterms for unique keys --> +<!-- next 2 indexterms for unique keys <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>unique keys</tertiary> </indexterm> - +--> <indexterm> <primary>associative arrays</primary> <secondary>introduction</secondary> @@ -58,14 +60,14 @@ <tertiary>arrays</tertiary> </indexterm> -<!-- next 2 indexterms for associated values --> +<!-- next 2 indexterms for associated values <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>associated values</tertiary> </indexterm> - +--> <indexterm> <primary>associative arrays</primary> <secondary>introduction</secondary> @@ -78,14 +80,14 @@ <tertiary>arrays</tertiary> </indexterm> -<!-- next 2 indexterms for index expression --> +<!-- next 2 indexterms for index expression <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>index expression</tertiary> </indexterm> - +--> <indexterm> <primary>associative arrays</primary> <secondary>introduction</secondary> @@ -99,13 +101,13 @@ </indexterm> <para>Since associative arrays are normally processed in multiple probes (as we will demonstrate later), they are declared as <command>global</command> variables in the SystemTap script. The syntax for accessing an element in an associative array is similar to that of <command>awk</command>, and is as follows:</para> -<!-- next 3 indexterms for syntax --> +<!-- next 3 indexterms for syntax <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>syntax</tertiary> </indexterm> - +--> <indexterm> <primary>associative arrays</primary> <secondary>introduction</secondary> @@ -131,14 +133,14 @@ <para>Here, the <command><replaceable>array_name</replaceable></command> is any arbitrary name the array uses. The <command><replaceable>index_expression</replaceable></command> is used to refer to a specific unique key in the array. To illustrate, let us try to build an array named <command>foo</command> that specifies the ages of three people (i.e. the unique keys): <command>tom</command>, <command>dick</command>, and <command>harry</command>. To assign them the ages (i.e. associated values) of 23, 24, and 25 respectively, we'd use the following array statements:</para> -<!-- next 2 indexterms for example --> +<!-- next 2 indexterms for example <indexterm> <primary>arrays</primary> <secondary>introduction</secondary> <tertiary>example</tertiary> </indexterm> - +--> <indexterm> <primary>associative arrays</primary> <secondary>introduction</secondary> diff --git a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml index a139015d..2550efce 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml @@ -45,7 +45,7 @@ </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>SystemTap handler constructs</secondary> <tertiary>variables</tertiary> </indexterm> @@ -73,7 +73,7 @@ name, assign a value from a function or expression to it, and use it in an expre </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>SystemTap handler constructs</secondary> <tertiary><command>global</command></tertiary> </indexterm> @@ -130,7 +130,7 @@ probe timer.jiffies(100) { count_jiffies ++ } </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>conditional statements</secondary> </indexterm> <para> @@ -153,7 +153,7 @@ You can do this by using <emphasis>conditionals</emphasis> in handlers. SystemTa </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>conditional statements</secondary> <tertiary>if/else</tertiary> </indexterm> @@ -219,7 +219,7 @@ probe end </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>conditional statements</secondary> <tertiary>while loops</tertiary> </indexterm> @@ -271,7 +271,7 @@ printf("goodbye world\n") </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>conditional statements</secondary> <tertiary>for loops</tertiary> </indexterm> @@ -326,7 +326,7 @@ while (<replaceable>conditional</replaceable>) { </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>conditional statements</secondary> <tertiary>conditional operators</tertiary> </indexterm> @@ -374,7 +374,7 @@ while (<replaceable>conditional</replaceable>) { </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>SystemTap handler constructs</secondary> <tertiary>command-line arguments</tertiary> </indexterm> @@ -407,7 +407,7 @@ probe kernel.function(@1).return { } </indexterm> <indexterm> -<primary>SystemTap handlers</primary> + <primary>SystemTap statements</primary> <secondary>SystemTap handler constructs</secondary> <tertiary>variable notations</tertiary> </indexterm> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml b/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml index a0fc7d52..fe2e69f4 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml @@ -547,578 +547,599 @@ probe timer.s(4) </section> <!-- stophere --> - <section id="systemtapscript-handler"> - <title>Systemtap Handler/Body</title> -<indexterm> -<primary>Handlers</primary> -<secondary>introduction</secondary> -</indexterm> - <para> Consider the following sample script: </para> - -<example id="helloworld"><title>helloworld.stp</title> -<programlisting> -probe begin -{ - printf ("hello world\n") - exit () -} -</programlisting> -</example> - - <para> - In <xref linkend="helloworld"/>, the event <command>begin</command> - (i.e. the start of the session) triggers the handler enclosed in - <command>{ }</command>, which simply prints <command>hello - world</command>, then exits. - </para> - - <note> - <title>Note</title> -<indexterm> -<primary>Handlers</primary> -<secondary><command>exit()</command></secondary> -</indexterm> - -<indexterm> -<primary><command>exit()</command></primary> -<secondary>Handlers</secondary> -</indexterm> - <para> - SystemTap scripts continue to run until the - <command>exit()</command> function executes. If the users wants to stop - the execution of the script, it can interrupted manually with - <keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo>. - </para> - </note> - - <formalpara id="printf"> - <title>printf ( ) Statements</title> -<indexterm> - <primary><command>printf()</command></primary> - <secondary>format strings</secondary> - </indexterm> - - <para> - The <command>printf ()</command> statement is one of the simplest - functions for printing data. <command>printf ()</command> can also be - used to display data using a wide variety of SystemTap functions in the - following format: - </para> - </formalpara> - - -<programlisting> -printf ("<replaceable>format string</replaceable>\n", <replaceable>arguments</replaceable>) -</programlisting> -<indexterm> -<primary><command>printf()</command></primary> -<secondary>format strings</secondary> -</indexterm> - -<indexterm> -<primary>format strings</primary> -<secondary><command>printf()</command></secondary> -</indexterm> - <para> - The <replaceable>format string</replaceable> specifies how - <replaceable>arguments</replaceable> should be printed. The format string - of <xref linkend="helloworld"/> simply instructs SystemTap to print - <command>hello world</command>, and contains no format specifiers. - </para> -<indexterm> -<primary><command>printf()</command></primary> -<secondary>format specifiers</secondary> -</indexterm> - -<indexterm> -<primary>format specifiers</primary> -<secondary><command>printf()</command></secondary> -</indexterm> - <para> - You can use the format specifiers <command>%s</command> (for strings) - and <command>%d</command> (for numbers) in format strings, depending on - your list of arguments. Format strings can have multiple format - specifiers, each matching a corresponding argument; multiple arguments - are delimited by a comma (<command>,</command>). - </para> - - <note> - <title>Note</title> -<indexterm> -<primary><command>printf()</command></primary> -<secondary>syntax and format</secondary> -</indexterm> - -<indexterm> -<primary>syntax and format</primary> -<secondary><command>printf()</command></secondary> -</indexterm> -<indexterm> -<primary>format and syntax</primary> -<secondary><command>printf()</command></secondary> -</indexterm> - <para>Semantically, the SystemTap <command>printf</command> function is - very similar to its C language counterpart. The aforementioned syntax - and format for SystemTap's <command>printf</command> function is - identical to that of the C-style <command>printf</command>. - </para> - </note> - - <para> To illustrate this, consider the following probe example: </para> - -<example id="syscall-open"> -<title>variables-in-printf-statements.stp</title> -<programlisting> -probe syscall.open -{ - printf ("%s(%d) open\n", execname(), pid()) -} -</programlisting> -</example> - - <para> - <xref linkend="syscall-open"/> instructs SystemTap to probe all entries to - the system call <command>open</command>; for each event, it prints the - current <command>execname()</command> (a string with the executable name) and - <command>pid()</command> (the current process ID number), followed by the word - <command>open</command>. A snippet of this probe's output would look like: - </para> - - <remark>editorial review: does a clarification that "format specifier1" is - to "argument1", "format specifier2" is to "argument2", or is this clear - enough? </remark> - -<screen> -vmware-guestd(2206) open -hald(2360) open -hald(2360) open -hald(2360) open -df(3433) open -df(3433) open -df(3433) open -hald(2360) open -</screen> - - <formalpara id="systemtapscript-functions"> - <title>SystemTap Functions</title> -<indexterm> -<primary>functions</primary> -</indexterm> - -<indexterm> -<primary>SystemTap script functions</primary> -</indexterm> - -<indexterm> - <primary>Handlers</primary> - <secondary>handler functions</secondary> -</indexterm> - -<indexterm> - <primary>handler functions</primary> - <secondary>Handlers</secondary> -</indexterm> - - <para> - SystemTap supports a wide variety of functions that can be used as - <command>printf ()</command> arguments. <xref linkend="syscall-open"/> - uses the SystemTap functions <command>execname()</command> (name of the - process that called a kernel function/performed a system call) and - <command>pid()</command> (current process ID). - </para> - </formalpara> - - <remark>is "handler function" an appropriate term? wcohen: use "SystemTap functions" to match up language in man pages</remark> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -</indexterm> - - <para>The following is a list of commonly-used SystemTap functions:</para> -<variablelist> - -<varlistentry> - <term>tid()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>tid()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>tid()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>tid()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - - <para>The ID of the current thread.</para> - </listitem> -</varlistentry> - -<varlistentry> - <term>uid()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>uid()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>uid()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>uid()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - <para>The ID of the current user.</para> - </listitem> -</varlistentry> - -<varlistentry> - <term>cpu()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>cpu()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>cpu()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>cpu()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - <para>The current CPU number.</para> - </listitem> -</varlistentry> - -<varlistentry> - <term>gettimeofday_s()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>gettimeofday_s()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>gettimeofday_s()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>gettimeofday_s()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - - <para>The number of seconds since UNIX epoch (January 1, 1970).</para> - </listitem> -</varlistentry> - -<varlistentry> - <term>ctime()</term> - <listitem> - <para> - Convert number of seconds since UNIX epoch to date.</para> - </listitem> -</varlistentry> - -<!-- -<varlistentry> - <term>get_cycles()</term> - <listitem> - <para>A snapshot of the hardware cycle counter.</para> - </listitem> -</varlistentry> ---> - -<varlistentry> - <term>pp()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>pp()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>pp()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>pp()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - <para>A string describing the probe point currently being handled.</para> - </listitem> -</varlistentry> -<!-- removed, doesnt work as expected anymore -<varlistentry> - <term>probefunc()</term> - <listitem> - <para>If known, the name of the function in which the probe was placed.</para> - </listitem> -</varlistentry> ---> - -<varlistentry> - <term>thread_indent()</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>thread_indent()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>thread_indent()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>thread_indent()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> +<section id="systemtapscript-handler"> + <title>Systemtap Handler/Body</title> + <indexterm> + <primary>handlers</primary> + <secondary>introduction</secondary> + </indexterm> + <para> Consider the following sample script: </para> + + <example id="helloworld"><title>helloworld.stp</title> + <programlisting> + probe begin + { + printf ("hello world\n") + exit () + } + </programlisting> + </example> + <para> - This particular function is quite useful, providing you with a way - to better organize your print results. The function takes one - argument, an indentation delta, which indicates how many - spaces to add or remove from a thread's "indentation counter". - It then returns a - string with some generic trace data along with an appropriate number - of indentation spaces. - </para> - - <para> - The generic data included in the returned string includes a - timestamp (number of microseconds since the - first call to <command>thread_indent()</command> by the thread), - a process name, and the thread ID. This allows you to - identify what functions were called, who called them, and the - duration of each function call. - </para> - - <para> - If call entries and exits immediately precede each other, it is easy - to match them. However, in most cases, after a first function call - entry is made several other call entries and exits may be made - before the first call exits. The indentation counter helps you match - an entry with its corresponding exit by indenting the next function - call if it is not the exit of the previous one. - </para> + In <xref linkend="helloworld"/>, the event <command>begin</command> + (i.e. the start of the session) triggers the handler enclosed in + <command>{ }</command>, which simply prints <command>hello + world</command>, then exits. + </para> + + <note> + <title>Note</title> + <indexterm> + <primary>functions (used in handlers)</primary> + <secondary><command>exit()</command></secondary> + </indexterm> - <para> - Consider the following example on the use of - <command>thread_indent()</command>: - </para> + <indexterm> + <primary><command>exit()</command></primary> + <secondary>Handlers</secondary> + </indexterm> + <para> + SystemTap scripts continue to run until the + <command>exit()</command> function executes. If the users wants to stop + the execution of the script, it can interrupted manually with + <keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo>. + </para> + </note> + + <formalpara id="printf"> + <title>printf ( ) Statements</title> + <indexterm> + <primary><command>printf()</command></primary> + <secondary>format strings</secondary> + </indexterm> -<example id="thread_indent"><title>thread_indent.stp</title> -<programlisting> -probe kernel.function("*@net/socket.c") -{ - printf ("%s -> %s\n", thread_indent(1), probefunc()) -} -probe kernel.function("*@net/socket.c").return -{ - printf ("%s <- %s\n", thread_indent(-1), probefunc()) -} -</programlisting> -</example> - - <para> - <xref linkend="thread_indent"/> prints out the - <command>thread_indent()</command> and probe functions at each event - in the following format:</para> + <para> + The <command>printf ()</command> statement is one of the simplest + functions for printing data. <command>printf ()</command> can also be + used to display data using a wide variety of SystemTap functions in the + following format: + </para> + </formalpara> -<screen> - 0 ftp(7223): -> sys_socketcall - 1159 ftp(7223): -> sys_socket - 2173 ftp(7223): -> __sock_create - 2286 ftp(7223): -> sock_alloc_inode - 2737 ftp(7223): <- sock_alloc_inode - 3349 ftp(7223): -> sock_alloc - 3389 ftp(7223): <- sock_alloc - 3417 ftp(7223): <- __sock_create - 4117 ftp(7223): -> sock_create - 4160 ftp(7223): <- sock_create - 4301 ftp(7223): -> sock_map_fd - 4644 ftp(7223): -> sock_map_file - 4699 ftp(7223): <- sock_map_file - 4715 ftp(7223): <- sock_map_fd - 4732 ftp(7223): <- sys_socket - 4775 ftp(7223): <- sys_socketcall -</screen> - -<para>This sample output contains the following information:</para> - -<itemizedlist> - <listitem><para>The time (in microseconds) since the initial <command>thread_ident()</command> call for the thread (included in the string from <command>thread_ident()</command>).</para></listitem> - <listitem><para>The process name (and its corresponding ID) that made the function call (included in the string from <command>thread_ident()</command>).</para></listitem> + <programlisting> + printf ("<replaceable>format string</replaceable>\n", <replaceable>arguments</replaceable>) + </programlisting> + <indexterm> + <primary><command>printf()</command></primary> + <secondary>format strings</secondary> + </indexterm> - <listitem><para>An arrow signifying whether the call was an entry (<computeroutput><-</computeroutput>) or an exit (<computeroutput>-></computeroutput>); the indentations help you match specific function call entries with their corresponding exits.</para></listitem> + <indexterm> + <primary>format strings</primary> + <secondary><command>printf()</command></secondary> + </indexterm> + <para> + The <replaceable>format string</replaceable> specifies how + <replaceable>arguments</replaceable> should be printed. The format string + of <xref linkend="helloworld"/> simply instructs SystemTap to print + <command>hello world</command>, and contains no format specifiers. + </para> + <indexterm> + <primary><command>printf()</command></primary> + <secondary>format specifiers</secondary> + </indexterm> - <listitem><para>The name of the function called by the process.</para></listitem> -</itemizedlist> - -<remark>remember to add a reference later to "tapsets" from here, to clarify -that thread_indent is defined in tapsets as a special function of sorts</remark> + <indexterm> + <primary>format specifiers</primary> + <secondary><command>printf()</command></secondary> + </indexterm> + <para> + You can use the format specifiers <command>%s</command> (for strings) + and <command>%d</command> (for numbers) in format strings, depending on + your list of arguments. Format strings can have multiple format + specifiers, each matching a corresponding argument; multiple arguments + are delimited by a comma (<command>,</command>). + </para> + + <note> + <title>Note</title> + <indexterm> + <primary><command>printf()</command></primary> + <secondary>syntax and format</secondary> + </indexterm> + + <indexterm> + <primary>syntax and format</primary> + <secondary><command>printf()</command></secondary> + </indexterm> + <indexterm> + <primary>format and syntax</primary> + <secondary><command>printf()</command></secondary> + </indexterm> + <para>Semantically, the SystemTap <command>printf</command> function is + very similar to its C language counterpart. The aforementioned syntax + and format for SystemTap's <command>printf</command> function is + identical to that of the C-style <command>printf</command>. + </para> + </note> + + <para> To illustrate this, consider the following probe example: </para> + + <example id="syscall-open"> + <title>variables-in-printf-statements.stp</title> + <programlisting> + probe syscall.open + { + printf ("%s(%d) open\n", execname(), pid()) + } + </programlisting> + </example> - </listitem> - </varlistentry> - - <varlistentry> - <term>name</term> - <listitem> -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>name</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>name</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>name</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> - <para>Identifies the name of a specific system call. This variable can - only be used in probes that use the event - <command>syscall.<replaceable>system_call</replaceable></command>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>target()</term> - <listitem> - -<indexterm> -<primary>Handlers</primary> -<secondary>handler functions</secondary> -<tertiary><command>target()</command></tertiary> -</indexterm> - -<indexterm> -<primary>handler functions</primary> -<secondary>Handlers</secondary> -<tertiary><command>target()</command></tertiary> -</indexterm> - -<indexterm> -<primary><command>target()</command></primary> -<secondary>Handlers</secondary> -<tertiary>handler functions</tertiary> -</indexterm> <para> - Used in conjunction with <command>stap - <replaceable>script</replaceable> -x <replaceable>process - ID</replaceable></command> or <command>stap - <replaceable>script</replaceable> -c - <replaceable>command</replaceable></command>. If you want to specify - a script to take an argument of a process ID or command, use - <command>target()</command> as the variable in the script to refer - to it. For example: - </para> - -<example id="targetexample"> -<title>targetexample.stp</title> -<programlisting> -probe syscall.* { - if (pid() == target()) - printf("%s/n", name) -} -</programlisting> -</example> - - <para> - When <xref linkend="targetexample"/> is run with the argument - <command>-x <replaceable>process ID</replaceable></command>, it - watches all system calls (as specified by the event - <command>syscall.*</command>) and prints out the name of all system - calls made by the specified process. - </para> + <xref linkend="syscall-open"/> instructs SystemTap to probe all entries to + the system call <command>open</command>; for each event, it prints the + current <command>execname()</command> (a string with the executable name) and + <command>pid()</command> (the current process ID number), followed by the word + <command>open</command>. A snippet of this probe's output would look like: + </para> - <para> - This has the same effect as specifying <command>if (pid() == - <replaceable>process ID</replaceable>)</command> each time you wish - to target a specific process. However, using - <command>target()</command> makes it easier for you to re-use the - script, giving you the ability to simply pass a process ID as an - argument each time you wish to run the script (e.g. <command>stap - targetexample.stp -x <replaceable>process ID</replaceable></command>). - </para> -<!-- -<note> - <title>Note</title> - <para>In <xref linkend="targetexample"/>, <command>name</command> instructs SystemTap to capture the name of the process</para> -</note> --> - - </listitem> - </varlistentry> - -<!-- -<varlistentry> - <term></term> - <listitem> - <para></para> - </listitem> -</varlistentry> ---> - </variablelist> - - <para>For more information about supported SystemTap functions, refer to - <command>man stapfuncs</command>. - </para> - -<remark>will need a complete listing of supported handler functions? also, SystemTap function descriptions seem ambiguous, please advise.</remark> - -<!-- -<para> - <replaceable>variable</replaceable> can be either <command>%s</command> for strings, or <command>%d</command> for numbers, depending on the <replaceable>handler function</replaceable> used. Each <command>printf ()</command> statement can contain multiple <replaceable>variable</replaceable>s, with each one corresponding to a matching <replaceable>handler function</replaceable>. Multiple <replaceable>handler function</replaceable>s are delimited by comma (<command>,</command>). -</para> - - <command>printf ()</command> is a SystemTap-supported C statement, and can also trap data using a wide variety + <remark>editorial review: does a clarification that "format specifier1" is + to "argument1", "format specifier2" is to "argument2", or is this clear + enough? </remark> - SystemTap supports a wide variety of handler functions that can trap data when triggered by events. One way to display these functions is to use the <command>print()</command> -</para> + <screen> + vmware-guestd(2206) open + hald(2360) open + hald(2360) open + hald(2360) open + df(3433) open + df(3433) open + df(3433) open + hald(2360) open + </screen> + + <formalpara id="systemtapscript-functions"> + <title>SystemTap Functions</title> + <indexterm> + <primary>functions</primary> + </indexterm> + <indexterm> + <primary>SystemTap script functions</primary> + </indexterm> -<para> - <xref linkend="wildcards"/> illustrates an example of a SystemTap script that contains no handlers. SystemTap will still be able to run the script, but no information will be displayed. -</para> ---> - + <indexterm> + <primary>handler functions</primary> + </indexterm> + + <para> + SystemTap supports a wide variety of functions that can be used as + <command>printf ()</command> arguments. <xref linkend="syscall-open"/> + uses the SystemTap functions <command>execname()</command> (name of the + process that called a kernel function/performed a system call) and + <command>pid()</command> (current process ID). + </para> + </formalpara> + + <remark>is "handler function" an appropriate term? wcohen: use "SystemTap functions" to match up language in man pages</remark> + + <para>The following is a list of commonly-used SystemTap functions:</para> + <variablelist> + + <varlistentry> + <term>tid()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>tid()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>tid()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>tid()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + + <para>The ID of the current thread.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>uid()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>uid()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>uid()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>uid()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para>The ID of the current user.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>cpu()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>cpu()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>cpu()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>cpu()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para>The current CPU number.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>gettimeofday_s()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>gettimeofday_s()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>gettimeofday_s()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>gettimeofday_s()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + + <para>The number of seconds since UNIX epoch (January 1, 1970).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ctime()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>ctime()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>ctime()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>ctime()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para> + Convert number of seconds since UNIX epoch to date. + </para> + </listitem> + </varlistentry> + + <!-- + <varlistentry> + <term>get_cycles()</term> + <listitem> + <para>A snapshot of the hardware cycle counter.</para> + </listitem> + </varlistentry> + --> + + <varlistentry> + <term>pp()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>pp()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>pp()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>pp()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para>A string describing the probe point currently being handled.</para> + </listitem> + </varlistentry> + <!-- removed, doesnt work as expected anymore + <varlistentry> + <term>probefunc()</term> + <listitem> + <para>If known, the name of the function in which the probe was placed.</para> + </listitem> + </varlistentry> + --> + + <varlistentry> + <term>thread_indent()</term> + <listitem> + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>thread_indent()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>thread_indent()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>thread_indent()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para> + This particular function is quite useful, providing you with a way + to better organize your print results. The function takes one + argument, an indentation delta, which indicates how many + spaces to add or remove from a thread's "indentation counter". + It then returns a + string with some generic trace data along with an appropriate number + of indentation spaces. + </para> + + <para> + The generic data included in the returned string includes a + timestamp (number of microseconds since the + first call to <command>thread_indent()</command> by the thread), + a process name, and the thread ID. This allows you to + identify what functions were called, who called them, and the + duration of each function call. + </para> + + <para> + If call entries and exits immediately precede each other, it is easy + to match them. However, in most cases, after a first function call + entry is made several other call entries and exits may be made + before the first call exits. The indentation counter helps you match + an entry with its corresponding exit by indenting the next function + call if it is not the exit of the previous one. + </para> + + <para> + Consider the following example on the use of + <command>thread_indent()</command>: + </para> + + <example id="thread_indent"><title>thread_indent.stp</title> + <programlisting> + probe kernel.function("*@net/socket.c") + { + printf ("%s -> %s\n", thread_indent(1), probefunc()) + } + probe kernel.function("*@net/socket.c").return + { + printf ("%s <- %s\n", thread_indent(-1), probefunc()) + } + </programlisting> + </example> + + <para> + <xref linkend="thread_indent"/> prints out the + <command>thread_indent()</command> and probe functions at each event + in the following format:</para> + + <screen> + 0 ftp(7223): -> sys_socketcall + 1159 ftp(7223): -> sys_socket + 2173 ftp(7223): -> __sock_create + 2286 ftp(7223): -> sock_alloc_inode + 2737 ftp(7223): <- sock_alloc_inode + 3349 ftp(7223): -> sock_alloc + 3389 ftp(7223): <- sock_alloc + 3417 ftp(7223): <- __sock_create + 4117 ftp(7223): -> sock_create + 4160 ftp(7223): <- sock_create + 4301 ftp(7223): -> sock_map_fd + 4644 ftp(7223): -> sock_map_file + 4699 ftp(7223): <- sock_map_file + 4715 ftp(7223): <- sock_map_fd + 4732 ftp(7223): <- sys_socket + 4775 ftp(7223): <- sys_socketcall + </screen> + + <para>This sample output contains the following information:</para> + + <itemizedlist> + <listitem><para>The time (in microseconds) since the initial <command>thread_ident()</command> call for the thread (included in the string from <command>thread_ident()</command>).</para></listitem> + + <listitem><para>The process name (and its corresponding ID) that made the function call (included in the string from <command>thread_ident()</command>).</para></listitem> + + <listitem><para>An arrow signifying whether the call was an entry (<computeroutput><-</computeroutput>) or an exit (<computeroutput>-></computeroutput>); the indentations help you match specific function call entries with their corresponding exits.</para></listitem> + + <listitem><para>The name of the function called by the process.</para></listitem> + </itemizedlist> + + <remark>remember to add a reference later to "tapsets" from here, to clarify + that thread_indent is defined in tapsets as a special function of sorts</remark> + + </listitem> + </varlistentry> + + <varlistentry> + <term>name</term> + <listitem> +<indexterm> +<primary>local variables</primary> +<secondary>name</secondary> +</indexterm> + +<indexterm> +<primary>variables (local)</primary> +<secondary>name</secondary> +</indexterm> + +<indexterm> +<primary>name</primary> +<secondary>local variables</secondary> +</indexterm> +<!-- <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>name</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>name</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>name</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm>--> + <para>Identifies the name of a specific system call. This variable can + only be used in probes that use the event + <command>syscall.<replaceable>system_call</replaceable></command>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>target()</term> + <listitem> + + <indexterm> + <primary>functions</primary> + <secondary>handler functions</secondary> + <tertiary><command>target()</command></tertiary> + </indexterm> + + <indexterm> + <primary>handler functions</primary> + <secondary>Handlers</secondary> + <tertiary><command>target()</command></tertiary> + </indexterm> + + <indexterm> + <primary><command>target()</command></primary> + <secondary>Handlers</secondary> + <tertiary>handler functions</tertiary> + </indexterm> + <para> + Used in conjunction with <command>stap + <replaceable>script</replaceable> -x <replaceable>process + ID</replaceable></command> or <command>stap + <replaceable>script</replaceable> -c + <replaceable>command</replaceable></command>. If you want to specify + a script to take an argument of a process ID or command, use + <command>target()</command> as the variable in the script to refer + to it. For example: + </para> + + <example id="targetexample"> + <title>targetexample.stp</title> + <programlisting> + probe syscall.* { + if (pid() == target()) + printf("%s/n", name) + } + </programlisting> + </example> + + <para> + When <xref linkend="targetexample"/> is run with the argument + <command>-x <replaceable>process ID</replaceable></command>, it + watches all system calls (as specified by the event + <command>syscall.*</command>) and prints out the name of all system + calls made by the specified process. + </para> + + <para> + This has the same effect as specifying <command>if (pid() == + <replaceable>process ID</replaceable>)</command> each time you wish + to target a specific process. However, using + <command>target()</command> makes it easier for you to re-use the + script, giving you the ability to simply pass a process ID as an + argument each time you wish to run the script (e.g. <command>stap + targetexample.stp -x <replaceable>process ID</replaceable></command>). + </para> + <!-- + <note> + <title>Note</title> + <para>In <xref linkend="targetexample"/>, <command>name</command> instructs SystemTap to capture the name of the process</para> + </note> --> + + </listitem> + </varlistentry> + + <!-- + <varlistentry> + <term></term> + <listitem> + <para></para> + </listitem> + </varlistentry> + --> + </variablelist> + + <para>For more information about supported SystemTap functions, refer to + <command>man stapfuncs</command>. + </para> + + <remark>will need a complete listing of supported handler functions? also, SystemTap function descriptions seem ambiguous, please advise.</remark> + + <!-- + <para> + <replaceable>variable</replaceable> can be either <command>%s</command> for strings, or <command>%d</command> for numbers, depending on the <replaceable>handler function</replaceable> used. Each <command>printf ()</command> statement can contain multiple <replaceable>variable</replaceable>s, with each one corresponding to a matching <replaceable>handler function</replaceable>. Multiple <replaceable>handler function</replaceable>s are delimited by comma (<command>,</command>). + </para> + + <command>printf ()</command> is a SystemTap-supported C statement, and can also trap data using a wide variety + + SystemTap supports a wide variety of handler functions that can trap data when triggered by events. One way to display these functions is to use the <command>print()</command> + </para> + + + <para> + <xref linkend="wildcards"/> illustrates an example of a SystemTap script that contains no handlers. SystemTap will still be able to run the script, but no information will be displayed. + </para> + --> + </section> - </section> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-disktop.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-disktop.xml index 42f1986b..8a786d82 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-disktop.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-disktop.xml @@ -107,7 +107,24 @@ <para>The time and date in the output of <xref linkend="scriptdisktop"/> is returned by the functions <command>ctime()</command> and <command>gettimeofday_s()</command>. <command>ctime()</command> derives calendar time in terms of seconds passed since the Unix epoch (January 1, 1970). <command>gettimeofday_s()</command> counts the <emphasis>actual</emphasis> number of seconds since Unix epoch, which gives a fairly accurate human-readable timestamp for the output.</para> - +<!-- next 3 indexterms for $return --> +<indexterm> + <primary>local variables</primary> + <secondary>sample usage</secondary> + <tertiary>$return</tertiary> +</indexterm> + +<indexterm> + <primary>variables (local)</primary> + <secondary>sample usage</secondary> + <tertiary>$return</tertiary> +</indexterm> + +<indexterm> + <primary>$return</primary> + <secondary>sample usage</secondary> + <tertiary>local variables</tertiary> +</indexterm> <para> In this script, the <command>$return</command> is a local variable that stores the actual number of bytes each process reads or writes from the virtual file system. diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-iotime.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-iotime.xml index 7a1633aa..4d7d6b17 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-iotime.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-iotime.xml @@ -52,6 +52,26 @@ of microseconds it takes for any reads or writes to finish and tracks the amount of data (in bytes) read from or written to the file. </para> +<!-- next 2 indexterms for $count --> + +<indexterm> + <primary>local variables</primary> + <secondary>sample usage</secondary> + <tertiary>$count</tertiary> +</indexterm> + +<indexterm> + <primary>variables (local)</primary> + <secondary>sample usage</secondary> + <tertiary>$count</tertiary> +</indexterm> + +<indexterm> + <primary>$count</primary> + <secondary>sample usage</secondary> + <tertiary>local variables</tertiary> +</indexterm> + <para> <xref linkend="iotime"/> also uses the local variable <command>$count</command> to track the @@ -70,8 +90,10 @@ [...] 825946 3364 (NetworkManager) access /sys/class/net/eth0/carrier read: 8190 write: 0 825955 3364 (NetworkManager) iotime /sys/class/net/eth0/carrier time: 9 +[...] 117061 2460 (pcscd) access /dev/bus/usb/003/001 read: 43 write: 0 117065 2460 (pcscd) iotime /dev/bus/usb/003/001 time: 7 +[...] 3973737 2886 (sendmail) access /proc/loadavg read: 4096 write: 0 3973744 2886 (sendmail) iotime /proc/loadavg time: 11 [...] diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-traceio.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-traceio.xml index ab260d63..1af1475d 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-traceio.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-traceio.xml @@ -55,7 +55,24 @@ executables. This information is tracked and printed out in 1-second intervals, and in descending order. </para> +<!-- next 3 indexterms for $return --> +<indexterm> + <primary>local variables</primary> + <secondary>sample usage</secondary> + <tertiary>$return</tertiary> +</indexterm> +<indexterm> + <primary>variables (local)</primary> + <secondary>sample usage</secondary> + <tertiary>$return</tertiary> +</indexterm> + +<indexterm> + <primary>$return</primary> + <secondary>sample usage</secondary> + <tertiary>local variables</tertiary> +</indexterm> <para> Note that <xref linkend="traceio"/> also uses the local variable <command>$return</command>, which is also used by <xref linkend="scriptdisktop"/> from <xref linkend="disktop"/>. |