summaryrefslogtreecommitdiffstats
path: root/tutorialse4.html
diff options
authorFrank Ch. Eigler <fche@redhat.com>2024-06-01 10:19:04 -0400
committerFrank Ch. Eigler <fche@redhat.com>2024-06-01 10:19:04 -0400
commit4f6d86506bfb5c93ffb1ca161b0771256da3383b (patch)
treeca0a4e4af255f17fb57d3e471fa0538c191d091f /tutorialse4.html
parentadded new man pages (diff)
regen, replace some subdirs with in-place html (not sure why)
Diffstat (limited to 'tutorialse4.html')
-rw-r--r--tutorialse4.html439
1 files changed, 439 insertions, 0 deletions
diff --git a/tutorialse4.html b/tutorialse4.html
new file mode 100644
index 00000000..1246e05e
--- /dev/null
+++ b/tutorialse4.html
@@ -0,0 +1,439 @@
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3<html >
4<head><title>Tapsets</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6<meta name="generator" content="TeX4ht (https://tug.org/tex4ht/)">
7<meta name="originator" content="TeX4ht (https://tug.org/tex4ht/)">
8<!-- html,2 -->
9<meta name="src" content="tutorial.tex">
10<link rel="stylesheet" type="text/css" href="tutorial.css">
11</head><body
12>
13<!--l. 756--><div class="crosslinks"><p class="noindent">[<a
14href="tutorialse3.html" >prev</a>] [<a
15href="tutorialse3.html#tailtutorialse3.html" >prev-tail</a>] [<a
16href="tutorialse3.html#tailtutorialse4.html">tail</a>] [<a
17href="tutorial.html# " >up</a>] </p></div>
18<h3 class="sectionHead"><span class="titlemark">4 </span> <a
19 id="x10-150004"></a>Tapsets</h3>
20<!--l. 758--><p class="noindent" >After writing enough analysis scripts for yourself, you may become known as an expert to your colleagues, who will
21want to use your scripts. Systemtap makes it possible to share in a controlled manner; to build libraries of scripts
22that build on each other. In fact, all of the functions (<span class="obeylines-h"><span class="verb"><span
23class="cmtt-10">pid()</span></span></span>, etc.) used in the scripts above come from
24tapset scripts like that. A &#8220;tapset&#8221; is just a script that designed for reuse by installation into a special
25directory.
26<!--l. 766--><p class="noindent" >
27<h4 class="subsectionHead"><span class="titlemark">4.1 </span> <a
28 id="x10-160004.1"></a>Automatic selection</h4>
29<!--l. 768--><p class="noindent" >Systemtap attempts to resolve references to global symbols (probes, functions, variables) that are not defined within
30the script by a systematic search through the tapset library for scripts that define those symbols. Tapset scripts
31are installed under the default directory named <span class="obeylines-h"><span class="verb"><span
32class="cmtt-10">/usr/share/systemtap/tapset</span></span></span>. A user may give
33additional directories with the <span class="obeylines-h"><span class="verb"><span
34class="cmtt-10">-I</span><span
35class="cmtt-10">&#x00A0;DIR</span></span></span> option. Systemtap searches these directories for script (<span class="obeylines-h"><span class="verb"><span
36class="cmtt-10">.stp</span></span></span>)
37files.
38<!--l. 776--><p class="noindent" >The search process includes subdirectories that are specialized for a particular kernel version and/or architecture,
39and ones that name only larger kernel families. Naturally, the search is ordered from specific to general, as shown in
40Figure&#x00A0;<a
41href="#x10-160017">7<!--tex4ht:ref: fig:tapset-search --></a>.
42<!--l. 784--><p class="noindent" ><hr class="figure"><div class="figure"
43>
44
45
46<a
47 id="x10-160017"></a>
48
49
50<div class="center"
51>
52<!--l. 785--><p class="noindent" >
53
54<div class="fbox"><div class="minipage"><pre class="verbatim" id="verbatim-9">
55
56#&#x00A0;stap&#x00A0;-p1&#x00A0;-vv&#x00A0;-e&#x00A0;&#8217;probe&#x00A0;begin&#x00A0;{&#x00A0;}&#8217;&#x00A0;&#x003E;&#x00A0;/dev/null
57Created&#x00A0;temporary&#x00A0;directory&#x00A0;"/tmp/staplnEBh7"
58Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/2.6.15/i686/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;0
59Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/2.6.15/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;0
60Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/2.6/i686/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;0
61Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/2.6/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;0
62Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/i686/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;1
63Searched&#x00A0;&#8217;/usr/share/systemtap/tapset/*.stp&#8217;,&#x00A0;match&#x00A0;count&#x00A0;12
64Pass&#x00A0;1:&#x00A0;parsed&#x00A0;user&#x00A0;script&#x00A0;and&#x00A0;13&#x00A0;library&#x00A0;script(s)&#x00A0;in&#x00A0;350usr/10sys/375real&#x00A0;ms.
65Running&#x00A0;rm&#x00A0;-rf&#x00A0;/tmp/staplnEBh7
66</pre>
67<!--l. 797--><p class="nopar" > </div></div>
68</div>
69<br /> <div class="caption"
70><span class="id">Figure&#x00A0;7: </span><span
71class="content">Listing the tapset search path.</span></div><!--tex4ht:label?: x10-160017 -->
72
73
74<!--l. 801--><p class="noindent" ></div><hr class="endfigure">
75<!--l. 803--><p class="noindent" >When a script file is found that <span
76class="bchri7t-">defines </span>one of the undefined symbols, that <span
77class="bchri7t-">entire file </span>is added to the probing session
78being analyzed. This search is repeated until no more references can become satisfied. Systemtap signals an error if
79any are still unresolved.
80<!--l. 808--><p class="noindent" >This mechanism enables several programming idioms. First, it allows some global symbols to be defined only
81for applicable kernel version/architecture pairs, and cause an error if their use is attempted on an
82inapplicable host. Similarly, the same symbol can be defined differently depending on kernels, in much
83the same way that different kernel <span class="obeylines-h"><span class="verb"><span
84class="cmtt-10">include/asm/ARCH/</span></span></span> files contain macros that provide a porting
85layer.
86<!--l. 816--><p class="noindent" >Another use is to separate the default parameters of a tapset routine from its implementation. For example, consider
87a tapset that defines code for relating elapsed time intervals to process scheduling activities. The data collection code
88can be generic with respect to which time unit (jiffies, wall-clock seconds, cycle counts) it can use. It should have a
89default, but should not require additional run-time checks to let a user choose another. Figure&#x00A0;<a
90href="#x10-160028">8<!--tex4ht:ref: fig:tapset-default --></a> shows a
91way.
92<!--l. 825--><p class="noindent" ><hr class="figure"><div class="figure"
93>
94
95
96<a
97 id="x10-160028"></a>
98
99
100<div class="center"
101>
102<!--l. 826--><p class="noindent" >
103
104<div class="fbox"><div class="minipage"><pre class="verbatim" id="verbatim-10">
105
106#&#x00A0;cat&#x00A0;tapset/time-common.stp
107global&#x00A0;__time_vars
108function&#x00A0;timer_begin&#x00A0;(name)&#x00A0;{&#x00A0;__time_vars[name]&#x00A0;=&#x00A0;__time_value&#x00A0;()&#x00A0;}
109function&#x00A0;timer_end&#x00A0;(name)&#x00A0;{&#x00A0;return&#x00A0;__time_value()&#x00A0;-&#x00A0;__time_vars[name]&#x00A0;}
110
111#&#x00A0;cat&#x00A0;tapset/time-default.stp
112function&#x00A0;__time_value&#x00A0;()&#x00A0;{&#x00A0;return&#x00A0;gettimeofday_us&#x00A0;()&#x00A0;}
113
114#&#x00A0;cat&#x00A0;tapset-time-user.stp
115probe&#x00A0;begin
116{
117&#x00A0;&#x00A0;timer_begin&#x00A0;("bench")
118&#x00A0;&#x00A0;for&#x00A0;(i=0;&#x00A0;i&#x003C;100;&#x00A0;i++)&#x00A0;;
119&#x00A0;&#x00A0;printf&#x00A0;("%d&#x00A0;cycles\n",&#x00A0;timer_end&#x00A0;("bench"))
120&#x00A0;&#x00A0;exit&#x00A0;()
121}
122function&#x00A0;__time_value&#x00A0;()&#x00A0;{&#x00A0;return&#x00A0;get_ticks&#x00A0;()&#x00A0;}&#x00A0;#&#x00A0;override&#x00A0;for&#x00A0;greater&#x00A0;precision
123
124</pre>
125<!--l. 846--><p class="nopar" > </div></div>
126</div>
127<br /> <div class="caption"
128><span class="id">Figure&#x00A0;8: </span><span
129class="content">Providing an overrideable default.</span></div><!--tex4ht:label?: x10-160028 -->
130
131
132<!--l. 850--><p class="noindent" ></div><hr class="endfigure">
133<!--l. 852--><p class="noindent" >A tapset that exports only <span
134class="bchri7t-">data </span>may be as useful as ones that exports functions or probe point aliases (see below).
135Such global data can be computed and kept up-to-date using probes internal to the tapset. Any outside reference to
136the global variable would incidentally activate all the required probes.
137<h4 class="subsectionHead"><span class="titlemark">4.2 </span> <a
138 id="x10-170004.2"></a>Probe point aliases</h4>
139<!--l. 861--><p class="noindent" >Probe point aliases allow creation of new probe points from existing ones. This is useful if the new probe points are
140named to provide a higher level of abstraction. For example, the system-calls tapset defines probe point aliases of the
141form <span class="obeylines-h"><span class="verb"><span
142class="cmtt-10">syscall.open</span></span></span> etc., in terms of lower level ones like <span class="obeylines-h"><span class="verb"><span
143class="cmtt-10">kernel.function("sys_open")</span></span></span>. Even if some future
144kernel renames <span class="obeylines-h"><span class="verb"><span
145class="cmtt-10">sys_open</span></span></span>, the aliased name can remain valid.
146<!--l. 869--><p class="noindent" >A probe point alias definition looks like a normal probe. Both start with the keyword <span class="obeylines-h"><span class="verb"><span
147class="cmtt-10">probe</span></span></span> and have a probe handler
148statement block at the end. But where a normal probe just lists its probe points, an alias creates a new name using
149the assignment (<span class="obeylines-h"><span class="verb"><span
150class="cmtt-10">=</span></span></span>) operator. Another probe that names the new probe point will create an actual probe, with the
151handler of the alias <span
152class="bchri7t-">prepended</span>.
153<!--l. 876--><p class="noindent" >This prepending behavior serves several purposes. It allows the alias definition to &#8220;preprocess&#8221; the
154context of the probe before passing control to the user-specified handler. This has several possible uses:
155<!--tex4ht:inline--><div class="tabular"> <table id="TBL-11" class="tabular"
156
157><colgroup id="TBL-11-1g"><col
158id="TBL-11-1"><col
159id="TBL-11-2"></colgroup><tr
160 style="vertical-align:baseline;" id="TBL-11-1-"><td style="white-space:nowrap; text-align:right;" id="TBL-11-1-1"
161class="td11"><span class="obeylines-h"><span class="verb"><span
162class="cmtt-10">if</span><span
163class="cmtt-10">&#x00A0;($flag1</span><span
164class="cmtt-10">&#x00A0;!=</span><span
165class="cmtt-10">&#x00A0;$flag2)</span><span
166class="cmtt-10">&#x00A0;next</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-1-2"
167class="td11">skip probe unless given condition is met </td>
168</tr><tr
169 style="vertical-align:baseline;" id="TBL-11-2-"><td style="white-space:nowrap; text-align:right;" id="TBL-11-2-1"
170class="td11"> <span class="obeylines-h"><span class="verb"><span
171class="cmtt-10">name</span><span
172class="cmtt-10">&#x00A0;=</span><span
173class="cmtt-10">&#x00A0;"foo"</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-2-2"
174class="td11">supply probe-describing values </td>
175</tr><tr
176 style="vertical-align:baseline;" id="TBL-11-3-"><td style="white-space:nowrap; text-align:right;" id="TBL-11-3-1"
177class="td11"> <span class="obeylines-h"><span class="verb"><span
178class="cmtt-10">var</span><span
179class="cmtt-10">&#x00A0;=</span><span
180class="cmtt-10">&#x00A0;$var</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-3-2"
181class="td11">extract target variable to plain local variable</td>
182</tr><tr
183 style="vertical-align:baseline;" id="TBL-11-4-"><td style="white-space:nowrap; text-align:right;" id="TBL-11-4-1"
184class="td11"> </td>
185</tr></table> </div>
186<!--l. 885--><p class="noindent" >Figure&#x00A0;<a
187href="#x10-170019">9<!--tex4ht:ref: fig:probe-alias --></a> demonstrates a probe point alias definition as well as its use. It demonstrates how a single probe point alias
188can expand to multiple probe points, even to other aliases. It also includes probe point wildcarding. These functions
189are designed to compose sensibly.
190<!--l. 891--><p class="noindent" ><hr class="figure"><div class="figure"
191>
192
193
194<a
195 id="x10-170019"></a>
196
197
198<div class="center"
199>
200<!--l. 892--><p class="noindent" >
201
202<div class="fbox"><div class="minipage"><pre class="verbatim" id="verbatim-11">
203
204#&#x00A0;cat&#x00A0;probe-alias.stp
205probe&#x00A0;syscallgroup.io&#x00A0;=&#x00A0;syscall.open,&#x00A0;syscall.close,
206&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;syscall.read,&#x00A0;syscall.write
207{&#x00A0;groupname&#x00A0;=&#x00A0;"io"&#x00A0;}
208
209probe&#x00A0;syscallgroup.process&#x00A0;=&#x00A0;syscall.fork,&#x00A0;syscall.execve
210{&#x00A0;groupname&#x00A0;=&#x00A0;"process"&#x00A0;}
211
212probe&#x00A0;syscallgroup.*
213{&#x00A0;groups&#x00A0;[execname()&#x00A0;.&#x00A0;"/"&#x00A0;.&#x00A0;groupname]&#x00A0;++&#x00A0;}
214
215probe&#x00A0;end
216{
217&#x00A0;&#x00A0;foreach&#x00A0;(eg+&#x00A0;in&#x00A0;groups)
218&#x00A0;&#x00A0;&#x00A0;&#x00A0;printf&#x00A0;("%s:&#x00A0;%d\n",&#x00A0;eg,&#x00A0;groups[eg])
219}
220
221global&#x00A0;groups
222
223#&#x00A0;stap&#x00A0;probe-alias.stp
22405-wait_for_sys/io:&#x00A0;19
22510-udev.hotplug/io:&#x00A0;17
22620-hal.hotplug/io:&#x00A0;12
227X/io:&#x00A0;73
228apcsmart/io:&#x00A0;59
229[...]
230make/io:&#x00A0;515
231make/process:&#x00A0;16
232[...]
233xfce-mcs-manage/io:&#x00A0;3
234xfdesktop/io:&#x00A0;5
235[...]
236xmms/io:&#x00A0;7070
237zsh/io:&#x00A0;78
238zsh/process:&#x00A0;5
239</pre>
240<!--l. 929--><p class="nopar" > </div></div>
241</div>
242<br /> <div class="caption"
243><span class="id">Figure&#x00A0;9: </span><span
244class="content">Classified system call activity.</span></div><!--tex4ht:label?: x10-170019 -->
245
246
247<!--l. 933--><p class="noindent" ></div><hr class="endfigure">
248<h4 class="subsectionHead"><span class="titlemark">4.3 </span> <a
249 id="x10-180004.3"></a>Embedded C</h4>
250<!--l. 938--><p class="noindent" >Sometimes, a tapset needs provide data values from the kernel that cannot be extracted using ordinary target
251variables (<span class="obeylines-h"><span class="verb"><span
252class="cmtt-10">$var</span></span></span>). This may be because the values are in complicated data structures, may require lock
253awareness, or are defined by layers of macros. Systemtap provides an &#8220;escape hatch&#8221; to go beyond what the
254language can safely offer. In certain contexts, you may embed plain raw C in tapsets, exchanging power
255for the safety guarantees listed in section&#x00A0;<a
256href="tutorialse3.html#x6-130003.6">3.6<!--tex4ht:ref: sec:safety --></a>. End-user scripts <span
257class="bchri7t-">may not </span>include embedded C code,
258unless systemtap is run with the <span class="obeylines-h"><span class="verb"><span
259class="cmtt-10">-g</span></span></span> (&#8220;guru&#8221; mode) option. Tapset scripts get guru mode privileges
260automatically.
261<!--l. 951--><p class="noindent" >Embedded C can be the body of a script function. Instead enclosing the function body statements in <span class="obeylines-h"><span class="verb"><span
262class="cmtt-10">{</span></span></span> and <span class="obeylines-h"><span class="verb"><span
263class="cmtt-10">}</span></span></span>, use <span class="obeylines-h"><span class="verb"><span
264class="cmtt-10">%{</span></span></span>
265and <span class="obeylines-h"><span class="verb"><span
266class="cmtt-10">%}</span></span></span>. Any enclosed C code is literally transcribed into the kernel module: it is up to you to make it safe and correct.
267In order to take parameters and return a value, macros <span class="obeylines-h"><span class="verb"><span
268class="cmtt-10">STAP_ARG_*</span></span></span> and <span class="obeylines-h"><span class="verb"><span
269class="cmtt-10">STAP_RETVALUE</span></span></span> are made available. The
270familiar data-gathering functions <span class="obeylines-h"><span class="verb"><span
271class="cmtt-10">pid()</span></span></span>, <span class="obeylines-h"><span class="verb"><span
272class="cmtt-10">execname()</span></span></span>, and their neighbours are all embedded C functions. Figure&#x00A0;<a
273href="#x10-1801110">10<!--tex4ht:ref: fig:embedded-C --></a>
274contains another example.
275<!--l. 961--><p class="noindent" >Since systemtap cannot examine the C code to infer these types, an
276optional<span class="footnote-mark"><a
277href="tutorial11.html#fn5x0"><sup class="textsuperscript">5</sup></a></span><a
278 id="x10-18001f5"></a>
279annotation syntax is available to assist the type inference process. Simply suffix parameter names and/or
280the function name with <span class="obeylines-h"><span class="verb"><span
281class="cmtt-10">:string</span></span></span> or <span class="obeylines-h"><span class="verb"><span
282class="cmtt-10">:long</span></span></span> to designate the string or numeric type. In addition, the
283script may include a <span class="obeylines-h"><span class="verb"><span
284class="cmtt-10">%{</span></span></span> <span class="obeylines-h"><span class="verb"><span
285class="cmtt-10">%}</span></span></span> block at the outermost level of the script, in order to transcribe declarative
286code like <span class="obeylines-h"><span class="verb"><span
287class="cmtt-10">#include</span><span
288class="cmtt-10">&#x00A0;&#x003C;linux/foo.h&#x003E;</span></span></span>. These enable the embedded C functions to refer to general kernel
289types.
290<!--l. 972--><p class="noindent" >There are a number of safety-related constraints that should be observed by developers of embedded C
291code.
292 <ol class="enumerate1" >
293<li
294 class="enumerate" id="x10-18004x1">
295 <!--l. 975--><p class="noindent" >Do not dereference pointers that are not known or testable valid.
296 </li>
297<li
298 class="enumerate" id="x10-18006x2">
299 <!--l. 976--><p class="noindent" >Do not call any kernel routine that may cause a sleep or fault.
300 </li>
301<li
302 class="enumerate" id="x10-18008x3">
303 <!--l. 977--><p class="noindent" >Consider possible undesirable recursion, where your embedded C function calls a routine that may be
304 the subject of a probe. If that probe handler calls your embedded C function, you may suffer infinite
305 regress. Similar problems may arise with respect to non-reentrant locks.
306 </li>
307
308
309<li
310 class="enumerate" id="x10-18010x4">
311 <!--l. 982--><p class="noindent" >If locking of a data structure is necessary, use a <span class="obeylines-h"><span class="verb"><span
312class="cmtt-10">trylock</span></span></span> type call to attempt to take the lock. If that
313 fails, give up, do not block.</li></ol>
314<!--l. 987--><p class="noindent" ><hr class="figure"><div class="figure"
315>
316
317
318<a
319 id="x10-1801110"></a>
320
321
322<div class="center"
323>
324<!--l. 988--><p class="noindent" >
325
326<div class="fbox"><div class="minipage"><pre class="verbatim" id="verbatim-12">
327
328#&#x00A0;cat&#x00A0;embedded-C.stp
329%{
330#include&#x00A0;&#x003C;linux/sched.h&#x003E;
331#include&#x00A0;&#x003C;linux/list.h&#x003E;
332%}
333
334function&#x00A0;task_execname_by_pid:string&#x00A0;(pid:long)&#x00A0;%{
335&#x00A0;&#x00A0;struct&#x00A0;task_struct&#x00A0;*p;
336&#x00A0;&#x00A0;struct&#x00A0;list_head&#x00A0;*_p,&#x00A0;*_n;
337&#x00A0;&#x00A0;list_for_each_safe(_p,&#x00A0;_n,&#x00A0;&amp;current-&#x003E;tasks)&#x00A0;{
338&#x00A0;&#x00A0;&#x00A0;&#x00A0;p&#x00A0;=&#x00A0;list_entry(_p,&#x00A0;struct&#x00A0;task_struct,&#x00A0;tasks);
339&#x00A0;&#x00A0;&#x00A0;&#x00A0;if&#x00A0;(p-&#x003E;pid&#x00A0;==&#x00A0;(int)STAP_ARG_pid)
340&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;&#x00A0;snprintf(STAP_RETVALUE,&#x00A0;MAXSTRINGLEN,&#x00A0;"%s",&#x00A0;p-&#x003E;comm);
341&#x00A0;&#x00A0;}
342%}
343
344probe&#x00A0;begin
345{
346&#x00A0;&#x00A0;printf("%s(%d)\n",&#x00A0;task_execname_by_pid(target()),&#x00A0;target())
347&#x00A0;&#x00A0;exit()
348}
349
350#&#x00A0;pgrep&#x00A0;emacs
35116641
352#&#x00A0;stap&#x00A0;-g&#x00A0;embedded-C.stp&#x00A0;-x&#x00A0;16641
353emacs(16641)
354</pre>
355<!--l. 1016--><p class="nopar" > </div></div>
356</div>
357<br /> <div class="caption"
358><span class="id">Figure&#x00A0;10: </span><span
359class="content">Embedded C function.</span></div><!--tex4ht:label?: x10-1801110 -->
360
361
362<!--l. 1020--><p class="noindent" ></div><hr class="endfigure">
363<h4 class="subsectionHead"><span class="titlemark">4.4 </span> <a
364 id="x10-190004.4"></a>Naming conventions</h4>
365<!--l. 1024--><p class="noindent" >Using the tapset search mechanism just described, potentially many script files can become selected
366for inclusion in a single session. This raises the problem of name collisions, where different tapsets
367accidentally use the same names for functions/globals. This can result in errors at translate or run
368time.
369<!--l. 1030--><p class="noindent" >To control this problem, systemtap tapset developers are advised to follow naming conventions. Here is some of the
370guidance.
371 <ol class="enumerate1" >
372<li
373 class="enumerate" id="x10-19002x1">
374 <!--l. 1035--><p class="noindent" >Pick a unique name for your tapset, and substitute it for <span
375class="bchri7t-">TAPSET </span>below.
376 </li>
377<li
378 class="enumerate" id="x10-19004x2">
379 <!--l. 1037--><p class="noindent" >Separate identifiers meant to be used by tapset users from those that are internal implementation
380 artifacts.
381 </li>
382<li
383 class="enumerate" id="x10-19006x3">
384 <!--l. 1039--><p class="noindent" >Document the first set in the appropriate <span class="obeylines-h"><span class="verb"><span
385class="cmtt-10">man</span></span></span> pages.
386 </li>
387<li
388 class="enumerate" id="x10-19008x4">
389 <!--l. 1040--><p class="noindent" >Prefix the names of external identifiers with <span
390class="bchri7t-">TAPSET</span>_ if there is any likelihood of collision with other
391 tapsets or end-user scripts.
392 </li>
393<li
394 class="enumerate" id="x10-19010x5">
395 <!--l. 1043--><p class="noindent" >Prefix any probe point aliases with an appropriate prefix.
396 </li>
397<li
398 class="enumerate" id="x10-19012x6">
399 <!--l. 1044--><p class="noindent" >Prefix the names of internal identifiers with __<span
400class="bchri7t-">TAPSET</span>_.</li></ol>
401<!--l. 1047--><p class="noindent" >
402<h4 class="subsectionHead"><span class="titlemark">4.5 </span> <a
403 id="x10-200004.5"></a>Exercises</h4>
404<!--l. 1049--><p class="noindent" >
405
406
407 <ol class="enumerate1" >
408<li
409 class="enumerate" id="x10-20002x1">
410 <!--l. 1050--><p class="noindent" >Write a tapset that implements deferred and &#8220;cancelable&#8221; logging. Export a function that enqueues
411 a text string (into some private array), returning an id token. Include a timer-based probe that
412 periodically flushes the array to the standard log output. Export another function that, if the entry
413 was not already flushed, allows a text string to be cancelled from the queue. One might speculate that
414 similar functions and tapsets exist.
415 </li>
416<li
417 class="enumerate" id="x10-20004x2">
418 <!--l. 1058--><p class="noindent" >Create a &#8220;relative timestamp&#8221; tapset with functions return all the same values as the ones in the
419 timestamp tapset, except that they are made relative to the start time of the script.
420 </li>
421<li
422 class="enumerate" id="x10-20006x3">
423 <!--l. 1062--><p class="noindent" >Create a tapset that exports a global array that contains a mapping of recently seen process ID numbers
424 to process names. Intercept key system calls (<span class="obeylines-h"><span class="verb"><span
425class="cmtt-10">execve</span></span></span>?) to update the list incrementally.
426 </li>
427<li
428 class="enumerate" id="x10-20008x4">
429 <!--l. 1067--><p class="noindent" >Send your tapset ideas to the mailing list!</li></ol>
430
431
432<!--l. 1070--><div class="crosslinks"><p class="noindent">[<a
433href="tutorialse3.html" >prev</a>] [<a
434href="tutorialse3.html#tailtutorialse3.html" >prev-tail</a>] [<a
435href="tutorialse4.html" >front</a>] [<a
436href="tutorial.html# " >up</a>] </p></div>
437<!--l. 1070--><p class="noindent" ><a
438 id="tailtutorialse4.html"></a>
439</body></html>