diff options
| author | Frank Ch. Eigler <fche@redhat.com> | 2024-06-01 10:19:04 -0400 | 
|---|---|---|
| committer | Frank Ch. Eigler <fche@redhat.com> | 2024-06-01 10:19:04 -0400 | 
| commit | 4f6d86506bfb5c93ffb1ca161b0771256da3383b (patch) | |
| tree | ca0a4e4af255f17fb57d3e471fa0538c191d091f /tutorialse4.html | |
| parent | added new man pages (diff) | |
regen, replace some subdirs with in-place html (not sure why)
Diffstat (limited to 'tutorialse4.html')
| -rw-r--r-- | tutorialse4.html | 439 | 
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 | ||
| 14 | href="tutorialse3.html" >prev</a>] [<a | ||
| 15 | href="tutorialse3.html#tailtutorialse3.html" >prev-tail</a>] [<a | ||
| 16 | href="tutorialse3.html#tailtutorialse4.html">tail</a>] [<a | ||
| 17 | href="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 | ||
| 21 | want to use your scripts. Systemtap makes it possible to share in a controlled manner; to build libraries of scripts | ||
| 22 | that build on each other. In fact, all of the functions (<span class="obeylines-h"><span class="verb"><span | ||
| 23 | class="cmtt-10">pid()</span></span></span>, etc.) used in the scripts above come from | ||
| 24 | tapset scripts like that. A “tapset” is just a script that designed for reuse by installation into a special | ||
| 25 | directory. | ||
| 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 | ||
| 30 | the script by a systematic search through the tapset library for scripts that define those symbols. Tapset scripts | ||
| 31 | are installed under the default directory named <span class="obeylines-h"><span class="verb"><span | ||
| 32 | class="cmtt-10">/usr/share/systemtap/tapset</span></span></span>. A user may give | ||
| 33 | additional directories with the <span class="obeylines-h"><span class="verb"><span | ||
| 34 | class="cmtt-10">-I</span><span | ||
| 35 | class="cmtt-10"> DIR</span></span></span> option. Systemtap searches these directories for script (<span class="obeylines-h"><span class="verb"><span | ||
| 36 | class="cmtt-10">.stp</span></span></span>) | ||
| 37 | files. | ||
| 38 | <!--l. 776--><p class="noindent" >The search process includes subdirectories that are specialized for a particular kernel version and/or architecture, | ||
| 39 | and ones that name only larger kernel families. Naturally, the search is ordered from specific to general, as shown in | ||
| 40 | Figure <a | ||
| 41 | href="#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 | # stap -p1 -vv -e ’probe begin { }’ > /dev/null | ||
| 57 | Created temporary directory "/tmp/staplnEBh7" | ||
| 58 | Searched ’/usr/share/systemtap/tapset/2.6.15/i686/*.stp’, match count 0 | ||
| 59 | Searched ’/usr/share/systemtap/tapset/2.6.15/*.stp’, match count 0 | ||
| 60 | Searched ’/usr/share/systemtap/tapset/2.6/i686/*.stp’, match count 0 | ||
| 61 | Searched ’/usr/share/systemtap/tapset/2.6/*.stp’, match count 0 | ||
| 62 | Searched ’/usr/share/systemtap/tapset/i686/*.stp’, match count 1 | ||
| 63 | Searched ’/usr/share/systemtap/tapset/*.stp’, match count 12 | ||
| 64 | Pass 1: parsed user script and 13 library script(s) in 350usr/10sys/375real ms. | ||
| 65 | Running rm -rf /tmp/staplnEBh7 | ||
| 66 | </pre> | ||
| 67 | <!--l. 797--><p class="nopar" > </div></div> | ||
| 68 | </div> | ||
| 69 | <br /> <div class="caption" | ||
| 70 | ><span class="id">Figure 7: </span><span | ||
| 71 | class="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 | ||
| 76 | class="bchri7t-">defines </span>one of the undefined symbols, that <span | ||
| 77 | class="bchri7t-">entire file </span>is added to the probing session | ||
| 78 | being analyzed. This search is repeated until no more references can become satisfied. Systemtap signals an error if | ||
| 79 | any 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 | ||
| 81 | for applicable kernel version/architecture pairs, and cause an error if their use is attempted on an | ||
| 82 | inapplicable host. Similarly, the same symbol can be defined differently depending on kernels, in much | ||
| 83 | the same way that different kernel <span class="obeylines-h"><span class="verb"><span | ||
| 84 | class="cmtt-10">include/asm/ARCH/</span></span></span> files contain macros that provide a porting | ||
| 85 | layer. | ||
| 86 | <!--l. 816--><p class="noindent" >Another use is to separate the default parameters of a tapset routine from its implementation. For example, consider | ||
| 87 | a tapset that defines code for relating elapsed time intervals to process scheduling activities. The data collection code | ||
| 88 | can be generic with respect to which time unit (jiffies, wall-clock seconds, cycle counts) it can use. It should have a | ||
| 89 | default, but should not require additional run-time checks to let a user choose another. Figure <a | ||
| 90 | href="#x10-160028">8<!--tex4ht:ref: fig:tapset-default --></a> shows a | ||
| 91 | way. | ||
| 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 | # cat tapset/time-common.stp | ||
| 107 | global __time_vars | ||
| 108 | function timer_begin (name) { __time_vars[name] = __time_value () } | ||
| 109 | function timer_end (name) { return __time_value() - __time_vars[name] } | ||
| 110 | |||
| 111 | # cat tapset/time-default.stp | ||
| 112 | function __time_value () { return gettimeofday_us () } | ||
| 113 | |||
| 114 | # cat tapset-time-user.stp | ||
| 115 | probe begin | ||
| 116 | { | ||
| 117 |   timer_begin ("bench") | ||
| 118 |   for (i=0; i<100; i++) ; | ||
| 119 |   printf ("%d cycles\n", timer_end ("bench")) | ||
| 120 |   exit () | ||
| 121 | } | ||
| 122 | function __time_value () { return get_ticks () } # override for greater precision | ||
| 123 | |||
| 124 | </pre> | ||
| 125 | <!--l. 846--><p class="nopar" > </div></div> | ||
| 126 | </div> | ||
| 127 | <br /> <div class="caption" | ||
| 128 | ><span class="id">Figure 8: </span><span | ||
| 129 | class="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 | ||
| 134 | class="bchri7t-">data </span>may be as useful as ones that exports functions or probe point aliases (see below). | ||
| 135 | Such global data can be computed and kept up-to-date using probes internal to the tapset. Any outside reference to | ||
| 136 | the 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 | ||
| 140 | named to provide a higher level of abstraction. For example, the system-calls tapset defines probe point aliases of the | ||
| 141 | form <span class="obeylines-h"><span class="verb"><span | ||
| 142 | class="cmtt-10">syscall.open</span></span></span> etc., in terms of lower level ones like <span class="obeylines-h"><span class="verb"><span | ||
| 143 | class="cmtt-10">kernel.function("sys_open")</span></span></span>. Even if some future | ||
| 144 | kernel renames <span class="obeylines-h"><span class="verb"><span | ||
| 145 | class="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 | ||
| 147 | class="cmtt-10">probe</span></span></span> and have a probe handler | ||
| 148 | statement block at the end. But where a normal probe just lists its probe points, an alias creates a new name using | ||
| 149 | the assignment (<span class="obeylines-h"><span class="verb"><span | ||
| 150 | class="cmtt-10">=</span></span></span>) operator. Another probe that names the new probe point will create an actual probe, with the | ||
| 151 | handler of the alias <span | ||
| 152 | class="bchri7t-">prepended</span>. | ||
| 153 | <!--l. 876--><p class="noindent" >This prepending behavior serves several purposes. It allows the alias definition to “preprocess” the | ||
| 154 | context 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 | ||
| 158 | id="TBL-11-1"><col | ||
| 159 | id="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" | ||
| 161 | class="td11"><span class="obeylines-h"><span class="verb"><span | ||
| 162 | class="cmtt-10">if</span><span | ||
| 163 | class="cmtt-10"> ($flag1</span><span | ||
| 164 | class="cmtt-10"> !=</span><span | ||
| 165 | class="cmtt-10"> $flag2)</span><span | ||
| 166 | class="cmtt-10"> next</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-1-2" | ||
| 167 | class="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" | ||
| 170 | class="td11"> <span class="obeylines-h"><span class="verb"><span | ||
| 171 | class="cmtt-10">name</span><span | ||
| 172 | class="cmtt-10"> =</span><span | ||
| 173 | class="cmtt-10"> "foo"</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-2-2" | ||
| 174 | class="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" | ||
| 177 | class="td11"> <span class="obeylines-h"><span class="verb"><span | ||
| 178 | class="cmtt-10">var</span><span | ||
| 179 | class="cmtt-10"> =</span><span | ||
| 180 | class="cmtt-10"> $var</span></span></span></td><td style="white-space:nowrap; text-align:left;" id="TBL-11-3-2" | ||
| 181 | class="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" | ||
| 184 | class="td11"> </td> | ||
| 185 | </tr></table> </div> | ||
| 186 | <!--l. 885--><p class="noindent" >Figure <a | ||
| 187 | href="#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 | ||
| 188 | can expand to multiple probe points, even to other aliases. It also includes probe point wildcarding. These functions | ||
| 189 | are 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 | # cat probe-alias.stp | ||
| 205 | probe syscallgroup.io = syscall.open, syscall.close, | ||
| 206 |                         syscall.read, syscall.write | ||
| 207 | { groupname = "io" } | ||
| 208 | |||
| 209 | probe syscallgroup.process = syscall.fork, syscall.execve | ||
| 210 | { groupname = "process" } | ||
| 211 | |||
| 212 | probe syscallgroup.* | ||
| 213 | { groups [execname() . "/" . groupname] ++ } | ||
| 214 | |||
| 215 | probe end | ||
| 216 | { | ||
| 217 |   foreach (eg+ in groups) | ||
| 218 |     printf ("%s: %d\n", eg, groups[eg]) | ||
| 219 | } | ||
| 220 | |||
| 221 | global groups | ||
| 222 | |||
| 223 | # stap probe-alias.stp | ||
| 224 | 05-wait_for_sys/io: 19 | ||
| 225 | 10-udev.hotplug/io: 17 | ||
| 226 | 20-hal.hotplug/io: 12 | ||
| 227 | X/io: 73 | ||
| 228 | apcsmart/io: 59 | ||
| 229 | [...] | ||
| 230 | make/io: 515 | ||
| 231 | make/process: 16 | ||
| 232 | [...] | ||
| 233 | xfce-mcs-manage/io: 3 | ||
| 234 | xfdesktop/io: 5 | ||
| 235 | [...] | ||
| 236 | xmms/io: 7070 | ||
| 237 | zsh/io: 78 | ||
| 238 | zsh/process: 5 | ||
| 239 | </pre> | ||
| 240 | <!--l. 929--><p class="nopar" > </div></div> | ||
| 241 | </div> | ||
| 242 | <br /> <div class="caption" | ||
| 243 | ><span class="id">Figure 9: </span><span | ||
| 244 | class="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 | ||
| 251 | variables (<span class="obeylines-h"><span class="verb"><span | ||
| 252 | class="cmtt-10">$var</span></span></span>). This may be because the values are in complicated data structures, may require lock | ||
| 253 | awareness, or are defined by layers of macros. Systemtap provides an “escape hatch” to go beyond what the | ||
| 254 | language can safely offer. In certain contexts, you may embed plain raw C in tapsets, exchanging power | ||
| 255 | for the safety guarantees listed in section <a | ||
| 256 | href="tutorialse3.html#x6-130003.6">3.6<!--tex4ht:ref: sec:safety --></a>. End-user scripts <span | ||
| 257 | class="bchri7t-">may not </span>include embedded C code, | ||
| 258 | unless systemtap is run with the <span class="obeylines-h"><span class="verb"><span | ||
| 259 | class="cmtt-10">-g</span></span></span> (“guru” mode) option. Tapset scripts get guru mode privileges | ||
| 260 | automatically. | ||
| 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 | ||
| 262 | class="cmtt-10">{</span></span></span> and <span class="obeylines-h"><span class="verb"><span | ||
| 263 | class="cmtt-10">}</span></span></span>, use <span class="obeylines-h"><span class="verb"><span | ||
| 264 | class="cmtt-10">%{</span></span></span> | ||
| 265 | and <span class="obeylines-h"><span class="verb"><span | ||
| 266 | class="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. | ||
| 267 | In order to take parameters and return a value, macros <span class="obeylines-h"><span class="verb"><span | ||
| 268 | class="cmtt-10">STAP_ARG_*</span></span></span> and <span class="obeylines-h"><span class="verb"><span | ||
| 269 | class="cmtt-10">STAP_RETVALUE</span></span></span> are made available. The | ||
| 270 | familiar data-gathering functions <span class="obeylines-h"><span class="verb"><span | ||
| 271 | class="cmtt-10">pid()</span></span></span>, <span class="obeylines-h"><span class="verb"><span | ||
| 272 | class="cmtt-10">execname()</span></span></span>, and their neighbours are all embedded C functions. Figure <a | ||
| 273 | href="#x10-1801110">10<!--tex4ht:ref: fig:embedded-C --></a> | ||
| 274 | contains another example. | ||
| 275 | <!--l. 961--><p class="noindent" >Since systemtap cannot examine the C code to infer these types, an | ||
| 276 | optional<span class="footnote-mark"><a | ||
| 277 | href="tutorial11.html#fn5x0"><sup class="textsuperscript">5</sup></a></span><a | ||
| 278 | id="x10-18001f5"></a> | ||
| 279 | annotation syntax is available to assist the type inference process. Simply suffix parameter names and/or | ||
| 280 | the function name with <span class="obeylines-h"><span class="verb"><span | ||
| 281 | class="cmtt-10">:string</span></span></span> or <span class="obeylines-h"><span class="verb"><span | ||
| 282 | class="cmtt-10">:long</span></span></span> to designate the string or numeric type. In addition, the | ||
| 283 | script may include a <span class="obeylines-h"><span class="verb"><span | ||
| 284 | class="cmtt-10">%{</span></span></span> <span class="obeylines-h"><span class="verb"><span | ||
| 285 | class="cmtt-10">%}</span></span></span> block at the outermost level of the script, in order to transcribe declarative | ||
| 286 | code like <span class="obeylines-h"><span class="verb"><span | ||
| 287 | class="cmtt-10">#include</span><span | ||
| 288 | class="cmtt-10"> <linux/foo.h></span></span></span>. These enable the embedded C functions to refer to general kernel | ||
| 289 | types. | ||
| 290 | <!--l. 972--><p class="noindent" >There are a number of safety-related constraints that should be observed by developers of embedded C | ||
| 291 | code. | ||
| 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 | ||
| 312 | class="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 | # cat embedded-C.stp | ||
| 329 | %{ | ||
| 330 | #include <linux/sched.h> | ||
| 331 | #include <linux/list.h> | ||
| 332 | %} | ||
| 333 | |||
| 334 | function task_execname_by_pid:string (pid:long) %{ | ||
| 335 |   struct task_struct *p; | ||
| 336 |   struct list_head *_p, *_n; | ||
| 337 |   list_for_each_safe(_p, _n, &current->tasks) { | ||
| 338 |     p = list_entry(_p, struct task_struct, tasks); | ||
| 339 |     if (p->pid == (int)STAP_ARG_pid) | ||
| 340 |       snprintf(STAP_RETVALUE, MAXSTRINGLEN, "%s", p->comm); | ||
| 341 |   } | ||
| 342 | %} | ||
| 343 | |||
| 344 | probe begin | ||
| 345 | { | ||
| 346 |   printf("%s(%d)\n", task_execname_by_pid(target()), target()) | ||
| 347 |   exit() | ||
| 348 | } | ||
| 349 | |||
| 350 | # pgrep emacs | ||
| 351 | 16641 | ||
| 352 | # stap -g embedded-C.stp -x 16641 | ||
| 353 | emacs(16641) | ||
| 354 | </pre> | ||
| 355 | <!--l. 1016--><p class="nopar" > </div></div> | ||
| 356 | </div> | ||
| 357 | <br /> <div class="caption" | ||
| 358 | ><span class="id">Figure 10: </span><span | ||
| 359 | class="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 | ||
| 366 | for inclusion in a single session. This raises the problem of name collisions, where different tapsets | ||
| 367 | accidentally use the same names for functions/globals. This can result in errors at translate or run | ||
| 368 | time. | ||
| 369 | <!--l. 1030--><p class="noindent" >To control this problem, systemtap tapset developers are advised to follow naming conventions. Here is some of the | ||
| 370 | guidance. | ||
| 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 | ||
| 375 | class="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 | ||
| 385 | class="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 | ||
| 390 | class="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 | ||
| 400 | class="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 “cancelable” 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 “relative timestamp” 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 | ||
| 425 | class="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 | ||
| 433 | href="tutorialse3.html" >prev</a>] [<a | ||
| 434 | href="tutorialse3.html#tailtutorialse3.html" >prev-tail</a>] [<a | ||
| 435 | href="tutorialse4.html" >front</a>] [<a | ||
| 436 | href="tutorial.html# " >up</a>] </p></div> | ||
| 437 | <!--l. 1070--><p class="noindent" ><a | ||
| 438 | id="tailtutorialse4.html"></a> | ||
| 439 | </body></html> | ||
