From 5191b61cb908d096d872ad26f8f632641ff15cc8 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 20 Nov 2008 10:56:02 +1000 Subject: revise as per wcohen, run 2 --- .../en-US/Array-Operations.xml | 46 +++++++++++++++------- doc/SystemTap_Beginners_Guide/en-US/Arrays.xml | 8 ++-- doc/SystemTap_Beginners_Guide/en-US/Errors.xml | 5 ++- .../en-US/Introduction.xml | 10 +++-- .../en-US/ScriptConstructs.xml | 7 +--- doc/SystemTap_Beginners_Guide/en-US/Scripts.xml | 4 +- 6 files changed, 51 insertions(+), 29 deletions(-) (limited to 'doc/SystemTap_Beginners_Guide/en-US') diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml index f63d1d70..270c6fc9 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 @@ Associating Timestamps to Process Names -foo[execname()] = gettimeofday_s() +foo[tid()] = gettimeofday_s() -Whenever an event invokes the statement in , SystemTap returns the appropriate execname() 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 gettimeofday_s() to set the corresponding timestamp as the associated value to the unique key defined by the function execname(). This creates an array composed of key pairs containing process names and timestamps. +Whenever an event invokes the statement in , SystemTap returns the appropriate tid() 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 gettimeofday_s() to set the corresponding timestamp as the associated value to the unique key defined by the function tid(). This creates an array composed of key pairs containing thread IDs and timestamps. -In this same example, if execname() returns a value that is already defined in the array foo, the operator will discard the original associated value to it, and replace it with the current timestamp from gettimeofday_s(). +In this same example, if tid() returns a value that is already defined in the array foo, the operator will discard the original associated value to it, and replace it with the current timestamp from gettimeofday_s().
Reading Values From Arrays @@ -40,12 +40,12 @@ foo[execname()] = gettimeofday_s() Using Array Values in Simple Computations -foo[execname()] = gettimeofday_s() -delta = gettimeofday_s() - foo[execname()] +foo[tid()] = gettimeofday_s() +delta = gettimeofday_s() - foo[tid()] -In , the first statement sets a timestamp associated with the returned value of the handler function execname() as a reference point. The second statement computes a value for the variable delta by subtracting the associated value the reference point from the current gettimeofday_s(). Note that the first statement writes the value of gettimeofday_s() into the appropriate key of array foo, while in the second statement the value of foo[execname()] is read from the array in order to compute for delta. +In , the first statement sets a timestamp associated with the returned value of the handler function tid() as a reference point. The second statement computes a value for the variable delta by subtracting the associated value the reference point from the current gettimeofday_s(). Note that the first statement writes the value of gettimeofday_s() into the appropriate key of array foo, while in the second statement the value of foo[tid()] is read from the array in order to compute for delta. In this situation, if the index_expression cannot find the unique key, it returns a value of 0 (for numerical operations, such as ) or a null/empty string value (for string operations) by default.
@@ -73,16 +73,18 @@ probe kernel.function("vfs_read")
- Processing Elements in a Tuple as Iterations + Processing Multiple Elements in an Array + 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 : 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 useful is to print the key pairs in the array reads, but how? - The best way to process all elements in a tuple (treating each element as an iteration) is to use the foreach statement. Consider the following example: + The best way to process all key pairs in an array (as an iteration) is to use the foreach statement. Consider the following example: + cumulative-vfsreads.stp global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ } @@ -104,12 +106,12 @@ probe timer.s(3) probe timer.s(3) { - foreach (count in reads+ limit 4) + foreach (count in reads- limit 10) printf("%s : %d \n", count, reads[count]) } -This foreach statement instructs the script to process the elements in the array reads in ascending order (of associated value). The limit 4 option instructs the script to only process the first four elements in the array (i.e. the first 4, starting with the lowest value). +This foreach statement instructs the script to process the elements in the array reads in descending order (of associated value). The limit 10 option instructs the script to only process the first ten elements in the array (i.e. the first 10, starting with the highest value).
@@ -118,12 +120,28 @@ probe timer.s(3) Sometimes, you may need to clear the associated values in array elements, or reset an entire array for re-use in another probe. in 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. To do that, you will need to clear the values accumulated by the array. You can accomplish this using the delete operator to delete elements in an array, or an entire array. Consider the following example: - + + noncumulative-vfsreads.stp + +global reads +probe vfs.read +{ + reads[execname()] ++ +} +probe timer.s(3) +{ + foreach (count in reads) + printf("%s : %d \n", count, reads[count]) + delete reads +} + + + In , the second probe prints the number of VFS reads each process made within the probed 2-second period only. The delete reads statement clears the reads array within the probe. 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
- Tuples + Array Slots Another important point to remember in arrays is that each element therein (i.e. the indexed expression) exists in a slot. A key pair's slot is defined by the order in which each pair's unique key is defined. In our sample array foo in , the key pair that uses the unique key tom is in the first slot, since tom was the first unique key to be defined. dick is in the second slot, and so on. - -The sequence in which each key pair appears in an array (as defined by each pair's slot) is referred to as a tuple. Tuples allow us to refer to key pairs in an array by the order in which they appear in the sequence. + For example, the array statements in set 23 as the associated value of the unique key tom. Given the same array foo, we can increment the associated value of tom by 1 using the operator ++, like so: @@ -44,7 +44,7 @@ foo["harry"] = 25 foo["tom"] ++ -The above statement will increase the associated value of unique key tom to 24. Now, looking back at , we know that dick was the first uniqe key to be defined. As such, we can perform the same operation (i.e. incrementing associated value by 1) to dick using the following statement: +The above statement will increase the associated value of unique key tom to 24. Now, looking back at , we know that dick was the first unique key to be defined. As such, we can perform the same operation (i.e. incrementing associated value by 1) to dick using the following statement: 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 aggregation overflow +An array containing aggregate values contains too many distinct key pairs at this time. + + 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 @@ Documentation Goals 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. - 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. - + 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. + + 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. + + To lower these barriers the SystemTap Beginners Guide was written with the following goals: + To introduce users to SystemTap, familiarize them with its architecture, and provide setup instructions for all kernel types. 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 (condition) 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) } - 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 event {statements} - 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 function, as in: -- cgit