summaryrefslogtreecommitdiffstats
path: root/doc/html/tracing.html
blob: 8d3c6774a38f3ccf891bc1353691ca1ea6975018 (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
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
  <head>
    <title>API Tracing</title>
  </head>

  <body>
    <h1>API Tracing</h1>

    <h2>Introduction</h2>

    <p>The HDF5 library is now able to trace API calls by printing the
      function name, the argument names and their values, and the
      return value. Some people like to see lots of output during
      program execution instead of using a good symbolic debugger, and
      this feature is intended for their consumption.  For example,
      the output from <code>h5ls foo</code> after turning on tracing,
      includes:

    <p>
      <center>
	<table border align=center width="100%">
	  <caption align=top><b>Sample Output</b></caption>
	  <tr>
	    <td>
	      <code><pre>
H5Tcopy(type=184549388) = 184549419 (type);
H5Tcopy(type=184549392) = 184549424 (type);
H5Tlock(type=184549424) = SUCCEED;
H5Tcopy(type=184549393) = 184549425 (type);
H5Tlock(type=184549425) = SUCCEED;
H5Fopen(filename="foo", flags=0, access=H5P_DEFAULT) = FAIL;
HDF5-DIAG: Error detected in thread 0.  Back trace follows.
  #000: H5F.c line 1245 in H5Fopen(): unable to open file
    major(04): File interface
    minor(10): Unable to open file
  #001: H5F.c line 846 in H5F_open(): file does not exist
    major(04): File interface
    minor(10): Unable to open file
	      </pre></code>
	    </td>
	  </tr>
	</table>
      </center>

    <h2>Configuation</h2>

    <p>This all happens with some magic in the configuration script,
      the makefiles, and macros.  First, from the end-user point of
      view, the library must be configured with the
      <code>--enable-trace</code> switch (the default;
      `--disable-trace' is the alternative). This causes the library
      to include the support necessary for API tracing.

    <p>
      <center>
	<table border align=center width="100%">
	  <caption align=top><b>Configuration</b></caption>
	  <tr>
	    <td>
	      <code><pre>
$ make distclean
$ sh configure --enable-trace
$ make
	      </pre></code>
	    </td>
	  </tr>
	</table>
      </center>

    <h2>Execution</h2>

    <p>In order to actually get tracing output one must turn tracing
      on and specify a file descriptor where the tracing output should 
      be written. This is done by assigning a file descriptor number
      to the <code>HDF5_TRACE</code> environment variable.

    <p>
      <center>
	<table border align=center width="100%">
	  <caption align=top><b>Execution Examples</b></caption>
	  <tr>
	    <td>To display the trace on the standard error stream:
	      <code><pre>
$ export HDF5_TRACE=2
$ a.out
	      </pre></code>
	    </td>
	  </tr>
	  <tr>
	    <td>To send the trace to a file:
	      <code><pre>
$ export HDF5_TRACE=255
$ a.out 255>trace-output
	      </pre></code>
	    </td>
	  </tr>
	</table>
      </center>

    <h2>Performance</h2>

    <p>If the library was not configured for tracing then there is no
      unnecessary overhead since all tracing code is
      excluded.

    <p>However, if tracing is enabled but not used there is a
      small penalty. First, code size is larger because of extra
      statically-declared character strings used to store argument
      types and names and extra auto variable pointer in each
      function.  Also, execution is slower because each function sets
      and tests a local variable and each API function calls the
      <code>H5_trace()</code> function.

    <p>If tracing is enabled and turned on then the penalties from the 
      previous paragraph apply plus the time required to format each
      line of tracing information.  There is also an extra call to
      H5_trace() for each API function to print the return value.

    <h2>Safety</h2>

    <p>The tracing mechanism is invoked for each API function before
      arguments are checked for validity.  If bad arguments are passed 
      to an API function it could result in a segmentation fault.
      However, the tracing output is line-buffered so all previous
      output will appear.

    <h2>Completeness</h2>

    <p>There are two API functions that don't participate in
      tracing. They are <code>H5Eprint()</code> and
      <code>H5Eprint_cb()</code> because their participation would
      mess up output during automatic error reporting.

    <p>On the other hand, a number of API functions are called during
      library initialization and they print tracing information.

    <h2>Implementation</h2>

    <p>For those interested in the implementation here is a
      description.  Each API function should have a call to one of the 
      <code>H5TRACE()</code> macros immediately after the
      <code>FUNC_ENTER()</code> macro.  The first argument is the
      return type encoded as a string.  The second argument is the
      types of all the function arguments encoded as a string.  The
      remaining arguments are the function arguments.  This macro was
      designed to be as terse and unobtrousive as possible.

    <p>In order to keep the <code>H5TRACE()</code> calls synchronized
      with the source code we've written a perl script which gets
      called automatically just before Makefile dependencies are
      calculated for the file.  However, this only works when one is
      using GNU make.  To reinstrument the tracing explicitly, invoke
      the <code>trace</code> program from the hdf5 bin directory with
      the names of the source files that need to be updated.  If any
      file needs to be modified then a backup is created by appending
      a tilde to the file name.

    <p>
      <center>
	<table border align=center width="100%">
	  <caption align=top><b>Explicit Instrumentation</b></caption>
	  <tr>
	    <td>
	      <code><pre>
$ ../bin/trace *.c
H5E.c: in function `H5Ewalk_cb':
H5E.c:336: warning: trace info was not inserted
	      </pre></code>
	    </td>
	  </tr>
	</table>
      </center>

    <p>Note: The warning message is the result of a comment of the
      form <code>/*NO TRACE*/</code> somewhere in the function
      body. Tracing information will not be updated or inserted if
      such a comment exists.

    <p>Error messages have the same format as a compiler so that they
      can be parsed from program development environments like
      Emacs. Any function which generates an error will not be
      modified.


    <hr>
    <address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address>
<!-- Created: Wed Jun 17 12:29:12 EDT 1998 -->
<!-- hhmts start -->
Last modified: Wed Jul  8 14:07:23 EDT 1998
<!-- hhmts end -->
  </body>
</html>