summaryrefslogtreecommitdiffstats
path: root/doc/SystemTap_Beginners_Guide/en-US/Arrays.xml
blob: 3d3dec01598aaef8d708ee59a77c6f8fbb972fde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
<?xml version='1.0'?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>

<section id="associativearrays">
	<title>Associative Arrays</title>
<indexterm>
<primary>arrays</primary>
<seealso>associative arrays</seealso>
</indexterm>

<indexterm>
<primary>associative arrays</primary>
<secondary>introduction</secondary>
</indexterm>	

<para>SystemTap also supports the use of associative arrays. While an ordinary variable represents a single value, associative arrays can represent a collection of values. Simply put, an associative array is a collection of unique keys; each key in the array has a value associated with it.</para>

<!--<para>SystemTap also supports the use of associative arrays. While an ordinary variable represents a single value, associative arrays can represent a list of values. Simply put, an associative array is a collection of unique keys; each key in the array has a value associated with it. Illustrating this visually would be similar to creating a two-column table: the first column would have the unique key, while the second column would have each key's associated value. Each unique key and its associated value is referred to as a <emphasis>key pair</emphasis>.</para>-->

<!-- next 2 indexterms for key pairs -->

<!--
<indexterm>
<primary>arrays</primary>
<secondary>introduction</secondary>
<tertiary>key pairs</tertiary>
</indexterm>
-->

<indexterm>
<primary>associative arrays</primary>
<secondary>introduction</secondary>
<tertiary>key pairs</tertiary>
</indexterm>

<indexterm>
<primary>key pairs</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>

<!-- 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>
<tertiary>unique keys</tertiary>
</indexterm>

<indexterm>
<primary>unique keys</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>

<!-- 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>
<tertiary>associated values</tertiary>
</indexterm>

<indexterm>
<primary>associated values</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>

<!-- 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>
<tertiary>index expression</tertiary>
</indexterm>

<indexterm>
<primary>index expression</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</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 
<indexterm>
<primary>arrays</primary>
<secondary>introduction</secondary>
<tertiary>syntax</tertiary>
</indexterm>
-->
<indexterm>
<primary>associative arrays</primary>
<secondary>introduction</secondary>
<tertiary>syntax</tertiary>
</indexterm>

<indexterm>
<primary>syntax</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>

<indexterm>
<primary>format</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>


<screen>
<replaceable>array_name</replaceable>[<replaceable>index_expression</replaceable>]
</screen>

<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 

<indexterm>
<primary>arrays</primary>
<secondary>introduction</secondary>
<tertiary>example</tertiary>
</indexterm>
-->
<indexterm>
<primary>associative arrays</primary>
<secondary>introduction</secondary>
<tertiary>example</tertiary>
</indexterm>

<indexterm>
<primary>example</primary>
<secondary>introduction</secondary>
<tertiary>arrays</tertiary>
</indexterm>
<example id="arraysimplestexample">
	<title>Basic Array Statements</title>
<screen>
foo["tom"] = 23
foo["dick"] = 24
foo["harry"] = 25
</screen>
</example>

<para>You can specify up to 5 index expressons in an array statement, each one delimited by a comma (<command>,</command>). This is useful if you wish to have a key that contains multiple pieces of information. The following line from <xref linkend="scriptdisktop"/> uses 5 elements for the key: process ID, executable name, user ID, parent process ID, and string "W". It associates the value of <command>devname</command> with that key.</para>

<screen>
device[pid(),execname(),uid(),ppid(),"W"] = devname
</screen>

<important>
	<title>Important</title>
	<para>All associate arrays must be declared as <command>global</command>, regardless of whether the associate array is used in one or multiple probes. </para>
</important>



<!--	
<varlistentry>
	<term></term>
	<listitem>
		<para></para>
	</listitem>	
</varlistentry>
-->	

	
	
	
	
<!-- 
	
<para>SystemTap supports numerous ways to manipulate associative arrays (i.e. <command><replaceable>operation</replaceable></command> in the syntax format). For the purposes of this book, we will only cover the most common examples of manipulating associative arrays, all of which appear in <xref linkend="useful-systemtap-scripts"/>.</para>

<formalpara id="aaexamplesimple">
	<title>Incrementing Associated Values of Unique Keys</title>
<para>The simplest form of data manipulation in associative arrays is incrementing the associated value of a unique key in the array. The syntax for this operation is as follows:</para>
</formalpara>
<screen>
<replaceable>array_name</replaceable>[<replaceable>index_expression</replaceable>"] ++
</screen>

<para>Here, the <command>++</command> operation instructs SystemTap to increment the associated value of <command><replaceable>unique_key</replaceable></command> by <command><replaceable>value</replaceable></command>. For example, to increase the associated value of unique key <command>hello</command> in array <command>foo</command> by 4, use:</para>

<formalpara id="aaexamplesimple-example">
	<title>explicit-incrementing-in-arrays.stp</title>
<para>
<programlisting>
probe begin {	foo[4,"hello"] ++ }
</programlisting>
</para>
</formalpara>

<formalpara id="aaexampleupdatecounting">
	<title>Incrementing Associated Values of Unique Keys (By Variable)</title>
	
<para>One of the most common uses of associative arrays is to tally events per unique key. To do this, use the operator <command>+= $count</command>, as in:</para>
</formalpara>

<screen>
<replaceable>array_name</replaceable>[<replaceable>unique_key</replaceable>] += $count	
</screen>

<para>You can also use a handler function in as the <command><replaceable>unique_key</replaceable></command>. Doing so creates an associate array that uses the values returned by the handler function as the unique keys. The first time that a probe using this array returns a string value, that value is set as a unique key with an initial value of 0. The next time that the probe returns the same string value, it increments the associated value of the unique key by 1.</para>

<para>For example, let's say you need to tally how many times each process performs a read to the virtual file system (VFS). To do this, probe the VFS read opeartion, use the handler <command>execname()</command> to identify which processes performed the VFS read, and tally the reads of each process using the associative array named <command>reads</command>, as in</para>

<formalpara id="aaexamplesimplevfsreads">
	<title>tallying-in-arrays.stp</title>
<para>
<programlisting>
probe vfs.read
{ reads[execname()] += $count }
</programlisting>
</para>
</formalpara>

<para>In <xref linkend="aaexamplesimplevfsreads"/>, the first time that the probe returns the process name <command>gnome-terminal</command> (i.e. the first time <command>gnome-terminal</command> performs a VFS read), that process name is set as a unique key. The next time that the probe returns the process name <command>gnome-terminal</command>, SystemTap increments the associated value of <command>gnome-terminal</command> by 1. SystemTap performs this operation for <emphasis>all</emphasis> process names as the probe returns them.</para>
-->
</section>