summaryrefslogtreecommitdiffstats
path: root/doc/SystemTap_Beginners_Guide
diff options
context:
space:
mode:
authorWilliam Cohen <wcohen@redhat.com>2008-11-19 20:27:28 -0500
committerWilliam Cohen <wcohen@redhat.com>2008-11-19 20:27:28 -0500
commita006b96108a8b92b73af5ddb396cb1b1119f5529 (patch)
treea4d14055400a0ff012c45cac54bb1192ed0e716d /doc/SystemTap_Beginners_Guide
parent64db9629ddd2604cad4dc00086e028205fde46a5 (diff)
parentc59943f6936e93819978d5149500ca217d09667a (diff)
downloadsystemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.tar.gz
systemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.tar.xz
systemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'doc/SystemTap_Beginners_Guide')
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml81
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/Arrays.xml8
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/Errors.xml5
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/Introduction.xml10
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml7
-rw-r--r--doc/SystemTap_Beginners_Guide/en-US/Scripts.xml4
6 files changed, 79 insertions, 36 deletions
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml
index f63d1d70..4aef21f4 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml
@@ -20,13 +20,13 @@
<example id="arrays-timestampprocessname">
<title>Associating Timestamps to Process Names</title>
<programlisting>
-foo[execname()] = gettimeofday_s()
+foo[tid()] = gettimeofday_s()
</programlisting>
</example>
-<para>Whenever an event invokes the statement in <xref linkend="arrays-timestampprocessname"/>, SystemTap returns the appropriate <command>execname()</command> value (i.e. the name of a process, which is then used as the unique key). At the same time, SystemTap also uses the function <command>gettimeofday_s()</command> to set the corresponding timestamp as the associated value to the unique key defined by the function <command>execname()</command>. This creates an array composed of key pairs containing process names and timestamps.</para>
+<para>Whenever an event invokes the statement in <xref linkend="arrays-timestampprocessname"/>, SystemTap returns the appropriate <command>tid()</command> value (i.e. the ID of a thread, which is then used as the unique key). At the same time, SystemTap also uses the function <command>gettimeofday_s()</command> to set the corresponding timestamp as the associated value to the unique key defined by the function <command>tid()</command>. This creates an array composed of key pairs containing thread IDs and timestamps.</para>
-<para>In this same example, if <command>execname()</command> returns a value that is already defined in the array <command>foo</command>, the operator will discard the original associated value to it, and replace it with the current timestamp from <command>gettimeofday_s()</command>.</para>
+<para>In this same example, if <command>tid()</command> returns a value that is already defined in the array <command>foo</command>, the operator will discard the original associated value to it, and replace it with the current timestamp from <command>gettimeofday_s()</command>.</para>
</section>
<section id="arrayops-readvalues">
<title>Reading Values From Arrays</title>
@@ -40,12 +40,12 @@ foo[execname()] = gettimeofday_s()
<example id="arrayreadingvaluesfrom">
<title>Using Array Values in Simple Computations</title>
<screen>
-foo[execname()] = gettimeofday_s()
-delta = gettimeofday_s() - foo[execname()]
+foo[tid()] = gettimeofday_s()
+delta = gettimeofday_s() - foo[tid()]
</screen>
</example>
-<para>In <xref linkend="arrayreadingvaluesfrom"/>, the first statement sets a timestamp associated with the returned value of the handler function <command>execname()</command> as a <emphasis>reference point</emphasis>. The second statement computes a value for the variable <command>delta</command> by subtracting the associated value the reference point from the current <command>gettimeofday_s()</command>. Note that the first statement writes the value of <command>gettimeofday_s()</command> into the appropriate key of array <literal>foo</literal>, while in the second statement the value of <command>foo[execname()]</command> is <emphasis>read</emphasis> from the array in order to compute for <literal>delta</literal>.</para>
+<para>In <xref linkend="arrayreadingvaluesfrom"/>, the first statement sets a timestamp associated with the returned value of the handler function <command>tid()</command> as a <emphasis>reference point</emphasis>. The second statement computes a value for the variable <command>delta</command> by subtracting the associated value the reference point from the current <command>gettimeofday_s()</command>. Note that the first statement writes the value of <command>gettimeofday_s()</command> into the appropriate key of array <literal>foo</literal>, while in the second statement the value of <command>foo[tid()]</command> is <emphasis>read</emphasis> from the array in order to compute for <literal>delta</literal>.</para>
<para>In this situation, if the <command><replaceable>index_expression</replaceable></command> cannot find the unique key, it returns a value of 0 (for numerical operations, such as <xref linkend="arrayreadingvaluesfrom"/>) or a null/empty string value (for string operations) by default. </para>
</section>
@@ -73,16 +73,18 @@ probe kernel.function("vfs_read")
</section>
<section id="arrayops-foreach">
- <title>Processing Elements in a Tuple as Iterations</title>
+ <title>Processing Multiple Elements in an Array</title>
+<!-- <title>Processing Elements in a Tuple as Iterations</title> -->
<para>Once you've collected enough information in an array, you will need to retrieve and process all elements in that array to make it useful. Consider <xref linkend="simplesimplevfsread"/>: the script collects information about how many VFS reads each process performs, but does not specify what to do with it. The obvious means for making <xref linkend="simplesimplevfsread"/> useful is to print the key pairs in the array <command>reads</command>, but how?</para>
- <para>The best way to process all elements in a tuple (treating each element as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para>
+ <para>The best way to process all key pairs in an array (as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para>
+<!-- <para>The best way to process all elements in a tuple (treating each element as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para>-->
<example id="simplevfsreadprint">
<title>cumulative-vfsreads.stp</title>
<programlisting>
global reads
-probe kernel.function("vfs_read")
+probe vfs.read
{
reads[execname()] ++
}
@@ -104,12 +106,12 @@ probe timer.s(3)
<screen>
probe timer.s(3)
{
- foreach (count in reads+ limit 4)
+ foreach (count in reads- limit 10)
printf("%s : %d \n", count, reads[count])
}
</screen>
-<para>This <command>foreach</command> statement instructs the script to process the elements in the array <command>reads</command> in ascending order (of associated value). The <command>limit 4</command> option instructs the script to only process the first four elements in the array (i.e. the first 4, starting with the lowest value).</para>
+<para>This <command>foreach</command> statement instructs the script to process the elements in the array <command>reads</command> in descending order (of associated value). The <command>limit 10</command> option instructs the script to only process the first ten elements in the array (i.e. the first 10, starting with the highest value).</para>
</section>
<section id="arrayops-deleting">
@@ -118,12 +120,28 @@ probe timer.s(3)
<para>Sometimes, you may need to clear the associated values in array elements, or reset an entire array for re-use in another probe. <xref linkend="simplevfsreadprint"/> in <xref linkend="arrayops-foreach"/> allows you to track how the number of VFS reads per process grows over time, but it does not show you the number of VFS reads each process makes per 3-second period.</para>
<para>To do that, you will need to clear the values accumulated by the array. You can accomplish this using the <command>delete</command> operator to delete elements in an array, or an entire array. Consider the following example:</para>
-
+<example id="simplevfsreadprintnotcumulative">
+ <title>noncumulative-vfsreads.stp</title>
+<programlisting>
+global reads
+probe vfs.read
+{
+ reads[execname()] ++
+}
+probe timer.s(3)
+{
+ foreach (count in reads)
+ printf("%s : %d \n", count, reads[count])
+ delete reads
+}
+</programlisting>
+</example>
+<!--
<example id="simplevfsreadprintnotcumulative">
<title>vfsreads-per-2secs.stp</title>
<programlisting>
global reads
-probe kernel.function("vfs_read")
+probe vfs.read
{
reads[execname()] ++
@@ -136,7 +154,7 @@ probe timer.s(2)
delete reads
}
</programlisting>
-</example>
+</example>-->
<para>In <xref linkend="simplevfsreadprintnotcumulative"/>, the second probe prints the number of VFS reads each process made <emphasis>within the probed 2-second period only</emphasis>. The <command>delete reads</command> statement clears the <command>reads</command> array within the probe.</para>
@@ -178,7 +196,28 @@ probe end
<para>You can also use associative arrays in <command>if</command> statements. This is useful if you want to execute a subroutine once a value in the array matches a certain condition. Consider the following example:</para>
<example id="simplevfsreadprintif">
- <title>vfsreads-stop-on-stapio.stp</title>
+ <title>vfsreads-print-if-1kb.stp</title>
+<programlisting>
+global reads
+probe vfs.read
+{
+ reads[execname()] ++
+}
+
+probe timer.s(2)
+{
+ printf("=======\n")
+ foreach (count in reads-)
+ if (reads[count] >= 1024)
+ printf("%s : %dkB \n", count, reads[count]/1024)
+ else
+ printf("%s : %dB \n", count, reads[count])
+}
+</programlisting>
+</example>
+
+<para>Every two seconds, <xref linkend="simplevfsreadprintif"/> prints out a list of all processes, along with how many times each process performed a VFS read. If the associated value of a process name is equal or greater than 1024, the <command>if</command> statement in the script converts and prints it out in <command>kB</command>.</para>
+<!-- <title>vfsreads-stop-on-stapio.stp</title>
<programlisting>
global reads
probe kernel.function("vfs_read")
@@ -200,7 +239,7 @@ probe timer.s(2)
</example>
<para>The <command>if(reads["stapio"] >= 20)</command> instructs the script to execute the subroutine <command>exit()</command> once the value associated with the unique key <command>stapio</command> (in the array <command>reads</command>) is greater than or equal to 20.</para>
-
+-->
<formalpara>
<title>Testing for Membership</title>
<para>You can also test whether a specific unique key is a member of an array. Further, membership in an array can be used in <command>if</command> statements, as in:</para>
@@ -217,7 +256,7 @@ if([<replaceable>index_expression</replaceable>] in <replaceable>array_name</rep
<programlisting>
global reads
-probe kernel.function("vfs_read")
+probe vfs.read
{
reads[execname()] ++
}
@@ -251,15 +290,15 @@ probe timer.s(2)
<example id="simpleaggregates">
<title>stat-aggregates.stp</title>
<programlisting>
-global writes
-probe vfs_write
+global reads
+probe vfs.read
{
-writes[execname()] &lt;&lt;&lt; count
+reads[execname()] &lt;&lt;&lt; count
}
</programlisting>
</example>
-<para>In <xref linkend="simpleaggregates"/>, the operator <command>&lt;&lt;&lt; count</command> <emphasis>stores</emphasis> the amount returned by <literal>count</literal> to to the associated value of the corresponding <command>execname()</command> in the <literal>writes</literal> array. Remember, these values are <emphasis>stored</emphasis>; they are not added to the associated values of each unique key, nor are they used to replace the current associated values. In a manner of speaking, think of it as having each unique key (<command>execname()</command>) having multiple associated values, accumulating with each probe handler run.</para>
+<para>In <xref linkend="simpleaggregates"/>, the operator <command>&lt;&lt;&lt; count</command> <emphasis>stores</emphasis> the amount returned by <literal>count</literal> to to the associated value of the corresponding <command>execname()</command> in the <literal>reads</literal> array. Remember, these values are <emphasis>stored</emphasis>; they are not added to the associated values of each unique key, nor are they used to replace the current associated values. In a manner of speaking, think of it as having each unique key (<command>execname()</command>) having multiple associated values, accumulating with each probe handler run.</para>
<note>
<title>Note</title>
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml b/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml
index cf8b2fea..c487503b 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml
@@ -32,11 +32,11 @@ foo["harry"] = 25
<section id="tuples">
- <title>Tuples</title>
+ <title>Array Slots</title>
<para>Another important point to remember in arrays is that each element therein (i.e. the indexed expression) exists in a <emphasis>slot</emphasis>. A key pair's slot is defined by the order in which each pair's unique key is defined. In our sample array <command>foo</command> in <xref linkend="arraysimplestexample"/>, the key pair that uses the unique key <command>tom</command> is in the first slot, since <command>tom</command> was the first unique key to be defined. <command>dick</command> is in the second slot, and so on.</para>
-
-<para>The sequence in which each key pair appears in an array (as defined by each pair's slot) is referred to as a <emphasis>tuple</emphasis>. Tuples allow us to refer to key pairs in an array by the order in which they appear in the sequence.</para>
+<!--
+<para>The sequence in which each key pair appears in an array (as defined by each pair's slot) is referred to as a <emphasis>tuple</emphasis>. Tuples allow us to refer to key pairs in an array by the order in which they appear in the sequence.</para>-->
<para>For example, the array statements in <xref linkend="arraysimplestexample"/> set 23 as the associated value of the unique key <command>tom</command>. Given the same array <command>foo</command>, we can increment the associated value of <command>tom</command> by 1 using the operator <command>++</command>, like so:</para>
@@ -44,7 +44,7 @@ foo["harry"] = 25
foo["tom"] ++
</screen>
-<para>The above statement will increase the associated value of unique key <command>tom</command> to 24. Now, looking back at <xref linkend="arraysimplestexample"/>, we know that <command>dick</command> was the first uniqe key to be defined. As such, we can perform the same operation (i.e. incrementing associated value by 1) to <command>dick</command> using the following statement:</para>
+<para>The above statement will increase the associated value of unique key <command>tom</command> to 24. Now, looking back at <xref linkend="arraysimplestexample"/>, we know that <command>dick</command> was the first unique key to be defined. As such, we can perform the same operation (i.e. incrementing associated value by 1) to <command>dick</command> using the following statement:</para>
<screen>
foo[2] ++
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Errors.xml b/doc/SystemTap_Beginners_Guide/en-US/Errors.xml
index 3dbad229..f88d7c93 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/Errors.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/Errors.xml
@@ -212,8 +212,11 @@ probe syscall.open
<formalpara><title>aggregation overflow</title>
<para>
+An array containing aggregate values contains too many distinct key pairs at this time.
+</para>
+<!--<para>
An array containing aggregate values contains too many distinct key tuples at this time.
-</para>
+</para>-->
</formalpara>
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Introduction.xml b/doc/SystemTap_Beginners_Guide/en-US/Introduction.xml
index d63d7f8c..47a11476 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/Introduction.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/Introduction.xml
@@ -27,12 +27,16 @@
<title>Documentation Goals</title>
<para>SystemTap provides the infrastructure to monitor the running Linux kernel for detailed analysis. This can assist administrators and developers in identifying the underlying cause of a bug or performance problem.</para>
- <para>Without SystemTap, monitoring the activity of a running kernel would require a tedious instrument, recompile, install, and reboot sequence. SystemTap is designed to eliminate this, allowing users to gather the same information by simply running user-written SystemTap scripts.</para>
-
+ <para>Without SystemTap, monitoring the activity of a running kernel would require a tedious instrument, recompile, install, and reboot sequence. SystemTap is designed to eliminate this, allowing users to gather the same information by simply running user-written SystemTap scripts.</para>
+
+ <para>However, SystemTap was initially designed for users with intermediate to advanced knowledge of the kernel. This makes SystemTap less useful to administrators or developers with limited knowledge of and experience with the Linux kernel. Moreover, much of the existing SystemTap documentation is similarly aimed at knowledgeable and experienced users. This makes learning the tool similarly difficult.</para>
+
+ <para>To lower these barriers the SystemTap Beginners Guide was written with the following goals:</para>
+<!--
<para>However, SystemTap was initially designed for users with intermediate to advanced knowledge of the kernel. As such, much of the existing documentation for SystemTap is primarily for advanced users. This could present a steep learning curve for administrators or developers with limited knowledge of and experience with the Linux kernel.</para>
<para>In line with that, the main goals of the <citetitle>SystemTap Beginner's Guide</citetitle> are as follows:</para>
-
+ -->
<itemizedlist>
<listitem><para>To introduce users to SystemTap, familiarize them with its architecture, and provide setup instructions for all kernel types.</para></listitem>
diff --git a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
index fccf0469..1cda95a4 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
@@ -74,19 +74,16 @@ if (<replaceable>condition</replaceable>)
global countread, countnonread
probe kernel.function("vfs_read"),kernel.function("vfs_write")
{
- if (probefunc()=="vfs_read") {
+ if (probefunc()=="vfs_read")
countread ++
- }
- else {
+ else
countnonread ++
- }
}
probe timer.s(5) { exit() }
probe end
{
printf("VFS reads total %d\n VFS writes total %d\n", countread, countnonread)
}
-
</programlisting>
</example>
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml b/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml
index e0b7c12c..b9eb036e 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/Scripts.xml
@@ -85,8 +85,8 @@ probe <replaceable>event</replaceable> {<replaceable>statements</replaceable>}
</note>
<para>
- Systemtap allow you to write functions to factor out code to be used by a
- number of probes. Thus, rather than repeatedly writing the same sequence of
+ Systemtap allows you to write functions to factor out code to be used by a
+ number of probes. Thus, rather than repeatedly writing the same
series of statements in multiple probes, you can just place the instructions
in a <firstterm>function</firstterm>, as in:
</para>