Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
263 dpurdie 1
SHERLOCK
2
C Programming Tool
3
 
4
 
5
February 1, 1990
6
Version 1.5
7
 
8
 
9
Edward K. Ream
10
1617 Monroe Street.
11
Madison, WI 53711
12
 
13
 
14
 
15
CHAPTER 1  INTRODUCING SHERLOCK
16
 
17
 
18
Welcome to Sherlock!  Sherlock is not an ordinary programming tool and
19
you may have some questions about it: what is it, what features does it
20
have, how does it operate, how will it benefit you, how do you use it, how
21
does it compare with other tools and techniques, how easy will it be to use,
22
how can you customize it?  This chapter poses and answers these kinds of
23
questions and along the way provides examples showing how to use
24
Sherlock.
25
 
26
 
27
What is Sherlock, anyway?
28
 
29
Sherlock is a debugging, tracing and profiling tool for the C programming
30
language.  That is, Sherlock allows you to test and debug C programs by
31
examining various traces.  As an added benefit, Sherlock offers detailed
32
statistics about your program.  Sherlock consists of C language macros
33
and support routines called by those macros.
34
 
35
 
36
Why should I use Sherlock?
37
 
38
Sherlock allows you to build, study, enhance and maintain more complex
39
programs in less time.  It gives you a better view of your program than
40
other kinds of debuggersDyou get more useful information and less
41
useless data.  Sherlock reveals your program at any level you wish, from a
42
global, overall, landscape view to a very detailed view.  And you get to choose the exact format in which the information is presented.  Sherlock
43
is very flexible and can be used with very large and complex programs,
44
including programs that use overlays and re-entrant programs.
45
 
46
 
47
How does Sherlock work?
48
 
49
The basic idea behind Sherlock is simple: you can create individual tracing
50
instructions, written in the C language, which lie dormant in your program
51
until enabled while your program is executing.
52
 
53
 
54
That sounds very simple.  What's the big deal?
55
 
56
The ability to add hide latent instructions inside a program and to enable
57
them while the program is running turns out to be very powerful.
58
Typically these dormant instructions are tracing statements such as print
59
statements.  By enabling various sets of these tracing instructions you can
60
produce literally thousands of different traces from your program without
61
changing it or recompiling it.  This is a very fast and handy way of
62
pinpointing the location of bugs, especially pointer bugs.
63
 
64
 
65
Isn't using Sherlock like putting print statements throughout a program?
66
 
67
Not really.  If you just insert print statements throughout your program
68
you are buried in useless output.  The sheer volume of the output hides the
69
information that would make a difference to you.  The only way to make
70
sense of the output is to get rid of most of it.  Alas, removing the print
71
statements and recompiling takes a lot of time.  Also, once print statements
72
have been removed they are not available later until they have been re-
73
inserted and and the program recompiled and relinked.  You just can't be
74
very flexible this way.
75
 
76
With Sherlock, you enable tracing statements without changing your
77
program in any way.  Generating different traces is done in a matter of
78
seconds, not minutes.  And since your program remains unchanged, bugs
79
remain stable;  their symptoms do not change as they would if you added
80
or deleted print statements.
81
 
82
 
83
How is it possible to enable or disable a single C instruction?
84
 
85
It's done with macros.  The instruction or instructions are entered as the
86
arguments to special tracing macros.  For instance, suppose you want to
87
disable the following print statement:
88
 
89
	printf("The value of i is %d\n", i);
90
 
91
The TRACE macro is one of several that you might use.  It takes two
92
arguments.  The first is the name that will be given to the disabled
93
statement, say "abc".  The second is the statement or statements we want to
94
disable.  The complete TRACE macro would look like this:
95
 
96
	TRACE("abc", printf("The value of i is %d\n", i));
97
 
98
Let's look at this carefully.  The name given to the print statement is
99
represented by the C string "abc".  The comma after the "abc" separates the
100
two arguments.  Next comes the printf statement and two right
101
parentheses, one for the printf statement and one for the TRACE macro.
102
Notice that the semicolon that ends the printf statement has been omitted.
103
It would also be all right to leave it in, like this:
104
 
105
	TRACE("abc", printf("The value of i is %d\n", i););
106
 
107
The effect of this macro is as follows: the print statement is executed when
108
control reaches the macro only if the symbol "abc" has already been
109
enabled.
110
 
111
Please note: the operation of the TRACE macro varies drastically from the
112
more traditional kind of debugging macros often used in programming
113
projects.  Sherlock macros enable or disable tracing code during the
114
execution of the program..  Traditional debugging macros require that the
115
program be recompiled in order to enable or disable the code in the macros
116
  The effect of this difference is enormous.
117
 
118
 
119
Can other kinds of statements besides print statements be used?
120
 
121
Yes.  You can disable any executable C statement or sequence of
122
statements, including blocks.  For instance, a very useful kind of tracing
123
statement might be a function call which would print out a complicated data
124
structure.
125
 
126
 
127
How do you tell Sherlock which macros you want to enable or disable?
128
 
129
The most common way is to add special arguments to the command line.
130
For instance, to enable any macro whose name is "abc" you would add the
131
following argument to the command line:
132
 
133
	++abc
134
 
135
You can also enable macros while your program is running using other
136
Sherlock macros.
137
 
138
Won't the extra command line arguments interfere with my program?
139
 
140
No.  Sherlock removes these special arguments from the command line so
141
they will be completely invisible to your program.  They will not interfere
142
with the argument processing logic of your program in any way.
143
 
144
 
145
How does Sherlock know which arguments to delete from the command line?
146
 
147
All Sherlock arguments are preceded by one of two prefixes: an "on
148
prefix" that enables macros and an "off-prefix" that disables macros.  You
149
should choose each prefix to be something that will distinguish Sherlock
150
arguments from all other arguments to your program.  In the example
151
above, the prefix is ++.
152
 
153
 
154
Putting these macros into my programs seems like a lot of work to me.
155
 
156
Sherlock includes a utility program called SPP, for Sherlock Pre-Processor,
157
which will put macros at the entry and exit of all your functions
158
automatically, which is where you most often want them.
159
 
160
 
161
You mentioned that Sherlock is also a profiling tool.  What does that mean?
162
 
163
Sherlock gathers statistics automatically.  Sherlock counts how many times
164
each macro was encountered and also computes timing statistics using an
165
interrupt handler.  Sherlock associates these statistics with the names
166
defined by the macros.  All the details are handled by the macros.  You
167
may print a report of the statistics at any time.
168
 
169
 
170
How many Sherlock macros are there?
171
 
172
Over 30.
173
 
174
 
175
Why so many?
176
 
177
Many macros do the same basic thing with minor variations.  For instance,
178
 there is a TRACEP macro which is acts the same as TRACE except that
179
TRACEP prints its first argument, i.e., the name associated with the
180
macro, before executing the disabled instruction.  This saves some space in 
181
your program.  There are also macros used to initialize the Sherlock
182
system, to enable or disable macros, and to print a report of statistics.
183
 
184
 
185
Must I remove all the macros when I am done debugging?
186
 
187
No.  You can simply undefine a single compile-time variable, recompile
188
and relink.  All the code generated by the macros will disappear and the 
189
executable portion of your program will contain absolutely no evidence that 
190
Sherlock macros exist in the source code. Thus, there is no need to 
191
physically eliminate the macros from your source files.  There is a utility 
192
program, called SDEL, which will remove Sherlock macros from a source 
193
file if you want.
194
 
195
 
196
Can I choose different names for the Sherlock macros?
197
 
198
Yes.  All you have to do is to change names defined in a standard header 
199
file.  You will still be able to use SPP and SDEL.  Both tools allow you to 
200
specify alternate macro names to be used instead of the standard macro 
201
names.
202
 
203
 
204
What if I want to change how the macros work?
205
 
206
Full source code is provided for all macros, support routines and utility 
207
programs except SPP. To use the Sherlock system on another machine you 
208
need only recompile the support routines on the new machines.  You will 
209
need to rewrite the interrupt handler only if you wish to gather timing 
210
statistics on the new machineDSherlock will work without the interrupt 
211
handler.
212
 
213
 
214
 
215
CHAPTER 2  BEFORE USING SHERLOCK
216
 
217
 
218
This chapter provides information you should know before using 
219
Sherlock.  It lists the hardware and software required, it reminds you to 
220
create a backup copy of the distribution disk containing Sherlock, and it 
221
lists the files that are distributed with the Sherlock system.
222
 
223
 
224
System Requirements
225
 
226
o An IBM PC/XT/AT computer or compatible with two floppy disks or a 
227
hard disk.
228
 
229
o The MS-DOS operating system.
230
 
231
o Either the Microsoft C compiler or the Turbo C compiler.  Minor 
232
modifications in Sherlock's source code will allow Sherlock to compile 
233
using other C compilers.
234
 
235
o The Microsoft MASM macro assembler.  (Used only when changing the 
236
interrupt handler.)
237
 
238
 
239
Backing Up Your Disks
240
 
241
Please back up the distribution disks before using Sherlock.  Use the DOS 
242
COPY command to copy all the files on the distribution disks to backup 
243
disks.  Your backup disks will be used as working disks.
244
 
245
 
246
Files on Your Disk
247
 
248
File		Description
249
 
250
read.me		Late breaking news and information.  Please read 
251
		this file first.
252
*.mak		Make files for the Turbo C compiler version 1.5.
253
*.mmk		Make files for the Microsoft C compiler version 
254
		5.00 or later.
255
*.lnk		Link files for the Turbo C linker.
256
*.ml		Link files for the Microsoft linker.
257
cpp.exe		C Preprocessor whose source code illustrates the 
258
		use of Sherlock's macros.
259
\cpp\*.c	Source code for CPP.
260
\cpp\*.h	Header file for CPP.
261
dumpregs.c	C Language source code for a program illustrating 
262
		the use of regs.asm.
263
prf.asm		Assembly language source code for the interrupt 
264
		handler.
265
prfnear.obj	Object code for interrupt handlerDfor memory 
266
		models with small code spaces.
267
prffar.obj	Object code for interrupt handlerDfor memory 
268
		models with large code spaces.
269
regs.asm	Assembly language source code for the register 
270
		dumper.
271
regsnear.obj	Object code for the register dumperDfor memory 
272
		models with small code spaces.
273
regsfar.obj	Object code for the register dumperDfor memory 
274
		models with large code spaces.
275
sdel.exe	Utility program which deletes all Sherlock macros 
276
		from a single source file.
277
sdel.c		C language source code for SDEL illustrating the 
278
		use of Sherlock's macros.
279
sdif.exe	Special purpose file comparison program.
280
sdif.c		The C language source code for SDIF.
281
sherlock.c	C language source code for support routines.
282
sl.h		Preferred definitions of macros.
283
sl1.h		Alternate definitions of macros.
284
spp.exe		Utility program which inserts Sherlock macros 
285
		into a single source file.
286
 
287
 
288
Quick Start
289
 
290
This is the super-condensed version of the installation procedure.
291
 
292
1. Insert Sherlock macros into functions that you want to trace.  Sherlock 
293
comes with a stand alone tool, called SPP, which will do this automatically 
294
for you.  See the section called SPP of the User's Manual for details.
295
 
296
2. Insert the SL_INIT and SL_PARSE macros into your main() function as 
297
the first executable statements.  Again, SPP will do this automatically for 
298
you.
299
 
300
3.  Insert the line     #include "sl.h"   in each source file containing a 
301
Sherlock macro.  This can be done automatically using the -i option of 
302
SPP.  Alternatively, if you have a single header file which is inserted in all 
303
your source files, insert the line  #include "sl.h" in that header file.
304
 
305
4. Recompile all files which contain Sherlock macros.  Make sure to 
306
#define the compile time symbol called SHERLOCK.  The easiest and best 
307
way to do this is with a command line option to the compiler.
308
 
309
5. Compile the source code for the Sherlock support routines, located in 
310
sherlock.c.  Make sure the memory model used when compiling the 
311
support routines is the same as the memory model used when compiling 
312
the rest of the files of your program.  Sample make and link files to 
313
accomplish this step are included in the directory called sherlock.
314
 
315
6. Link the following files together to produce an executable version of 
316
your program:
317
 
318
o All the .obj files produced by compiling the files of your program.
319
o The .obj file produced by compiling sherlock.c.
320
o One (and only one) of the following two files:  prffar.obj or prfnear.obj.
321
 
322
Note:  Use prffar.obj when using memory models that have a code space 
323
larger than 64K.  Use prfnear when using memory models that have a code 
324
space limited to 64K or less.
325
 
326
7. Run your program.  To enable traces, add Sherlock command line 
327
arguments to your program's command line. For example, to enable 
328
tracing of a function called f(), add the argument ++f to the command line.  
329
 
330
8. When you are done debugging, recompile all your files which contain 
331
Sherlock macros with the compile time constant SHERLOCK not 
332
#define'd.  The code produced by the Sherlock macros will disappear.  
333
Relink all those files to produce a production version of your program.  Do 
334
not link in the .obj file produced by compiling sherlock.c.  Do not link in 
335
either prffar.obj or prfnear.obj.
336
 
337
 
338
 
339
CHAPTER 3  USING SHERLOCK
340
 
341
 
342
This chapter contains a tutorial introduction to Sherlock.  It tells you 
343
everything you need to know to start using Sherlock.  After an initial 
344
overview, the various macros comprising Sherlock will be discussed in 
345
detail, with numerous examples along the way.  The last section discusses 
346
how to enable macros using command line arguments.  For some tips 
347
about debugging C programs, see the next chapter.  For the most complete 
348
information about any aspect of the Sherlock system, see chapter five.
349
 
350
 
351
Overview
352
 
353
The Sherlock system consists of three main parts: tracing macros, other 
354
macros including initialization and statistics reporting macros and support 
355
routines called by the macros.  The support routines form the "hidden 
356
machinery" of the Sherlock system and will not be discussed further in this 
357
overview.
358
 
359
Sherlock's tracing macros are the most visible and important part of the 
360
Sherlock system.  These tracing macros allow you to create tracing 
361
statements embedded throughout your program which can be enabled or 
362
disabled without recompiling your program or changing the executable 
363
image of your program in any way.  Tracing macros also provide a 
364
framework for gathering statistics about your program.
365
 
366
Each tracing macro defines a tracepoint, a tracepoint name and a list of 
367
tracepoint actions.  A tracepoint is simply the location of the macro, the 
368
tracepoint name is a C language string which names the tracepoint and the 
369
tracepoint actions consist of one or more executable C language statements 
370
which are executed only if the tracepoint has been enabled.
371
 
372
Let's look at one kind of tracing macro, called TRACE.  The format of this 
373
macro is:
374
 
375
	TRACE(tracepoint_name, tracepoint_actions);
376
 
377
In other words, this macro takes two arguments, a tracepoint name and a 
378
list of tracepoint actions.  For example:
379
 
380
	TRACE("print_abc", printf("The value of abc is %d/n", abc));
381
 
382
Notice the two closing parentheses.  The first ends the printf statement and 
383
the second ends the TRACE macro.  In this example, the tracepoint name is 
384
a string
385
 
386
literal, namely "print_abc", and the tracepoint actions consists of the single 
387
statement:
388
 
389
	printf("The value of abc is %d/n", abc);
390
 
391
The operation of this TRACE macro is straightforward: the print statement 
392
will be executed only if the tracepoint named print_abc has been enabled.
393
 
394
Please note: the operation of the TRACE macro varies drastically from the 
395
more traditional kind of debugging macros often used in programming 
396
projects.  Sherlock macros enable or disable tracing code during the 
397
execution of the program. Traditional debugging macros require that the 
398
program be recompiled in order to enable or disable the code in the macros.  
399
The effect of this difference is enormous.  With Sherlock, you can scatter 
400
tracing macros throughout your program with no ill effects. With 
401
traditional debugging macros, this strategy is simply not possible because 
402
you would be buried in tracing output.
403
 
404
How are tracepoints enabled?  There are two ways: from the command line 
405
using special Sherlock arguments or from within your program using 
406
Sherlock macros.  In practice, the command line is most often used.  
407
Sherlock arguments consist of a prefix followed by a tracepoint name.  
408
There are two possible prefixes: an on_prefix which enables the following 
409
tracepoint name and an off_prefix which disables the following tracepoint 
410
name.  These prefixes are defined by an initialization macro called 
411
SL_PARSE and should be chosen so that Sherlock arguments can be 
412
distinguished from all other command line arguments.  The SL_PARSE 
413
macro processes all Sherlock arguments and then deletes them from the 
414
command line so that they will not interfere with the argument processing 
415
logic of your program. 
416
 
417
Any string may be used for these prefixes, and in this manual we will 
418
assume that the on prefix is ++ and the off prefix is - -.  For example, to 
419
enable tracing for the tracepoint named print_abc, the following command 
420
line argument could be used:
421
 
422
	++print_abc
423
 
424
Wildcard characters and other construction may be used in Sherlock 
425
arguments.  See the section on command line arguments for more details.
426
 
427
To summarize, here are the steps to use Sherlock:
428
 
429
1. Insert Sherlock macros throughout your program.  This is easy because 
430
Sherlock comes with a utility program called the Sherlock Preprocessor 
431
(SPP)  which will insert tracing macros automatically at the beginning and 
432
end of every function in a file.  The tracing macros created by SPP will 
433
print the values of all arguments to functions as well as the value returned 
434
from all functions.
435
 
436
2. The Sherlock macros are defined in a header file called sl.h.  Insert the 
437
following statement in every file that contains a Sherlock macro:
438
 
439
	#include <sl.h>
440
 
441
The SPP program will insert this statement for you if you desire.
442
 
443
3. Compile the files containing the Sherlock macros as usual and link in the 
444
support routines to create an executable version of your program.
445
 
446
4. Run your program and enable various tracepoints using Sherlock 
447
command line arguments.  On successive runs, focus on important details 
448
by enabling different tracepoints.
449
 
450
5. After debugging is complete, remove the code generated by Sherlock 
451
macros.  You can do this without removing the macros themselves by 
452
undefining the compile time constant called SHERLOCK and recompiling.  
453
Absolutely no overhead from the Sherlock macros will remain in your 
454
program.
455
 
456
6. Most people will want to leave Sherlock macros inside their source file 
457
so that they may be reactivated later by redefining the SHERLOCK 
458
constant and recompiling.  However, a utility called SDEL will remove all 
459
Sherlock macros from a source file if you desire.
460
 
461
This concludes the overview of the Sherlock system.  The next sections 
462
introduce you to all of the Sherlock macros and will discuss details 
463
concerning Sherlock command line arguments, header files and statistics.
464
 
465
 
466
Initialization: SL_INIT, SL_PARSE, SL_ON, and SL_OFF
467
 
468
Right at the start of your program, Sherlock's support routines must be 
469
initialized and the Sherlock arguments on the command line must be 
470
processed and removed.
471
 
472
The SL_INIT macro initializes Sherlock's support routines.  This macro 
473
must be executed before any other macro.  The best place for the SL_INIT 
474
macro is the very first executable statement of the main() routine.  The SPP 
475
program will insert the SL_INIT macro at that spot for you.  Note that the 
476
name is all UPPER CASE, as are the names of all Sherlock macros.
477
 
478
In the language of the draft C standard, the SL_INIT macro, like all of the 
479
Sherlock macros, is a "function-like" macro, which means that parentheses 
480
are required after it even though the macro takes no arguments.  Like this:  
481
SL_INIT();
482
 
483
The SL_PARSE macro enables or disables tracepoints by processing an 
484
argument list vector.  Most often, the vector is simply the argv vector 
485
passed by the operating system to the main() routine, but it doesn't have to 
486
beDyou can set up your own if you want.  The SL_PARSE macro may be 
487
called more than once, so you can enable or disable tracepoints from inside 
488
your program as well as from the command line.  Typically, the 
489
SL_PARSE macro should be placed immediately following the SL_INIT 
490
macro in the main() routine.  Again, the SPP program will insert the 
491
SL_PARSE macro for you there.
492
 
493
SL_PARSE takes four arguments.  The format is:
494
 
495
	SL_PARSE(argc, argv, on_prefix, off_prefix);
496
	int argc; char *argv[], *on_prefix, *off_prefix;
497
 
498
The first two arguments describe an argument list vector just like the argc 
499
and argv arguments passed to main().  In other words, argv is a pointer to 
500
a list of strings and argc is one more than the number of arguments in 
501
argv[].  The argv vector is terminated by a NULL string so that  argv[argc] 
502
is NULL.  
503
 
504
The on_prefix and off_prefix arguments must be C strings, either string 
505
literals or pointers to arrays of characters.  All arguments (i.e., all strings in 
506
the argv vector) whose prefix is either on_prefix or off_prefix are 
507
processed as Sherlock arguments and removed from the argv vector.  The 
508
argc count is decremented by one for every deleted argument.  Arguments 
509
that do not start with either the on_prefix or the off_prefix are not changed 
510
by SL_PARSE.
511
 
512
Here is an example of a typical main routine:
513
 
514
	main(int argc, char ** argv)
515
	{
516
		declarations of local variables.
517
 
518
		SL_INIT();
519
		SL_PARSE(argc, argv, "++", "- -");
520
 
521
		executable statements...
522
	}
523
 
524
All examples in this manual will assume that the prefixes are ++ and - -.  
525
However, any C string may be used for the off prefix or on prefix.  For 
526
example, to set the on_prefix to !+ and the off_prefix to !-, you would use 
527
the following call to SL_PARSE:
528
 
529
	SL_PARSE(argc, argv, "!+", "!-");
530
 
531
Here is a program that simply prints its command line arguments.  Note 
532
that it will not print any Sherlock argument, i.e., any argument starting 
533
with ++ or - -.
534
 
535
	/* Echo command line arguments. */
536
	main(argc, argv)
537
	int argc;
538
	char **argv;
539
	{
540
		int i;
541
 
542
		/* Process and remove Sherlock arguments. */
543
		SL_INIT();
544
		SL_PARSE(argc, argv, "++", "- -");
545
 
546
		/* Print non-Sherlock arguments. */
547
		argc- -;
548
		argv++;
549
		for (i = 1; i < argc; i++) {
550
			printf("argv[%d] = %s\n", i, *argv);
551
			argv++;
552
		}
553
	}
554
 
555
The SL_ON and SL_OFF macros also enable or disable tracepoints from 
556
within your program and are easier to use than SL_PARSE.  Each macro 
557
takes one argument, the name of the tracepoint to be enabled or disabled.  
558
SL_ON enables the tracepoint while SL_OFF disables the tracepoint.  The 
559
name of the tracepoint is not preceded by either the on_prefix or the 
560
off_prefix.  
561
The following example shows how to enable tracing for a selected range of 
562
loop iterations:
563
 
564
	for (i = 0; i < 100; i++) {
565
		if (i = = 20) {
566
			SL_ON("complicated_function");
567
		}
568
		complicated_function(i);
569
		if (i = = 30) {
570
			SL_OFF("complicated_function");
571
		}
572
	}
573
 
574
The following sections discuss tracing macros, the heart of the Sherlock 
575
system.
576
 
577
 
578
Tracepoint Names and Statistics: STAT, STATB and STATX
579
 
580
STAT is the simplest tracing macro.  It takes one argument, a tracepoint 
581
name.  For example:
582
 
583
	STAT("rose");
584
 
585
Although closely related to the other tracing macros, STAT produces no 
586
output.  STAT's only function is to provide a label for a count statistic, 
587
which is simply the number of times control reaches the tracepoint defined 
588
by STAT.  All tracing macros have a count statistic associated with their 
589
tracepoint name.  Count statistics are always updated regardless of whether 
590
tracing for a particular tracepoint has been enabled or not.
591
 
592
In order to provide better error checking, there are restrictions on the kinds 
593
of characters that may appear in tracepoint names;  tracepoint names may 
594
contain lower case letters, numerals and the underscore character, but not  
595
blanks or special characters such as ( ) { } + etc.  The following are valid 
596
tracepoint names:
597
 
598
	STAT("rose_is_a_rose");
599
	STAT("rose25");
600
 
601
The following are NOT valid tracepoint names:
602
 
603
	STAT("rose water"); 		blank character
604
	STAT("wine&roses");		& special character
605
 
606
There are two additional members of the STAT family, STATB and 
607
STATX.  These two macros are used to gather timing statistics.  Timing 
608
statistics are generally more useful than count statistics since they relate 
609
directly to program speed.  On the other hand, timing statistics are a little 
610
more difficult to gather than count statistics.  Timing statistics measure the 
611
time spent in timing code.
612
 
613
The STATB macro works just like the STAT macro, except that the STATB 
614
macro is an entry macro, that is, STATB defines the start of a section of 
615
timing code.  Similarly, the STATX macro is an exit macro, that is, STATX 
616
defines the end of a section of timing code.  In general, the suffix 'B' in the 
617
name of a tracing macro indicates that the macro is an entry macro, while 
618
the suffix 'X' in the name of a tracing macro indicates the macro is an exit 
619
macro.  Count statistics are updated for STATB but not STATX.
620
 
621
Most often, timing code consists of an entire function, though that is not 
622
required.  For example, to measure the time spent in a function without 
623
generating any tracing message you would do something like:
624
 
625
int f()
626
{
627
	STATB("f");
628
	body of f;
629
	STATX("f");
630
}
631
 
632
The support routines keep track of statistics using an internal timing stack.  
633
At run time, each entry macro must be paired eventually with an exit 
634
macro.  For example, if you put an entry macro at the beginning of a 
635
function then every exit from the macro must contain an exit macro.  When 
636
an exit macro is executed, Sherlock verifies that its tracepoint name 
637
matches the tracepoint name of the last entry macro, i.e., the macro on the 
638
top of the timing stack.  A warning message occurs if there is a mismatch. 
639
Such a warning indicates that timing statistics are not accurate.
640
 
641
The current nesting level is the number of entry macros that have been 
642
executed for which an exit macro has not been executed.  The output from 
643
all tracing macros is preceded by level dots, i.e., one period for each level 
644
of nesting.
645
 
646
Sherlock provides two kinds of timing statistics: cumulative and non-
647
cumulative.  Cumulative timing statistics measure the total time spent in 
648
timing code, including any time spent in nested timing code.  Non-
649
cumulative timing statistics excludes time spent in nested timing code.  In 
650
other words, cumulative statistics are incremented at all levels of the timing 
651
stack, while non-cumulative statistics are updated only at the top of the 
652
timing stack.
653
 
654
The following paragraphs will be of interest only to advanced users of 
655
Sherlock who wish to gather the best timing statistics possible.  Thanks go 
656
to James E.G. Morris of Atari Games Corporation for suggesting 
657
improvements in the way timing statistics are handled.  
658
 
659
Version 1.5 of the support routines provides ways to adjust the timing 
660
statistics gathered by Sherlock to factor out the overhead caused by calling 
661
and returning from the Sherlock macros.  The Sherlock support routine 
662
sl_dump() now  subtracts a "fudge factor," called TIME_ADJUST, from 
663
the timing statistics as the report of the statistics is being generated.  This 
664
fudge factor affects only the output of the SL_DUMP macroDthe actual 
665
gathering of timing statistics is not affected in any way by 
666
TIME_ADJUST.
667
 
668
The units of TIME_ADJUST are ticks per 1000 calls to Sherlock macros, 
669
and TIME_ADJUST is supplied as a compile-time constant on the 
670
command line when compiling sherlock.c.  If no value for 
671
TIME_ADJUST is supplied, it is set to zero, which is what you get by 
672
default.
673
 
674
The proper value of TIME_ADJUST depends on several factors: the speed 
675
of your machine, its "tick" rate, the "speed up rate,"  i.e., the value of 
676
sl_speed used in sherlock.c, which version of Sherlock macros is used, 
677
preferred or alternate, and which memory model is used to compile your 
678
program.  A new utility program, called measure.c, measures the time 
679
overhead involved in calling Sherlock macros, and suggests appropriate 
680
values for TIME_ADJUST.
681
 
682
 
683
Here I am Messages: TICK, TICKB, TICKN and TICKX
684
 
685
The simplest kind of tracing output is a "here I am" message.  The TICK 
686
family of macros provide such messages.  The TICK macro takes exactly 
687
one argument, a tracepoint name.  Examples:
688
 
689
	char name[] = "petunia";
690
	TICK(name);
691
	TICK("marigold");
692
 
693
If enabled, TICK simply prints the name of the tracepoint followed by a 
694
colon.  The output created from the examples above would look like:
695
 
696
	petunia:
697
	marigold:
698
 
699
The only difference between TICK and TICKN is that TICK updates the 
700
count statistic associated with the tracepoint name and TICKN does not.  In 
701
general, the suffix 'N' in the name of a tracing macro indicates that count 
702
statistics are not updated by the macro.
703
 
704
Why suppress the gathering of count statistics?   You might use TICKN 
705
rather than TICK in order not to count the same section of code twice.  For 
706
example:
707
 
708
	do {
709
		TICK("loop");
710
		...
711
		TICKN("loop");
712
	} while (waiting);
713
 
714
Since only one TICK macro was used in the loop, the count statistic for 
715
"loop" will reflect how many times the loop was executed.
716
 
717
As you would expect, the TICKB and TICKX macros are entry and exit 
718
macros that otherwise work just like TICK.  Count statistics are updated 
719
for TICKB but not TICKX.
720
 
721
 
722
Tracepoints Actions: TRACE, TRACEB, TRACEN and TRACEX
723
 
724
The TRACE family of tracing macros create code that lies dormant until the 
725
appropriate tracepoint is enabled.
726
 
727
The members of the TRACE family take exactly two arguments.  As usual, 
728
the first is a tracepoint name.  The second is a list of tracepoint actions, 
729
consisting of one or more C language statements or blocks.  Statements in 
730
the list of tracepoint actions are separated by semicolons as usual.  The list 
731
may be terminated by a semicolon, but it doesn't have to be.   For example:
732
 
733
	TRACE("violet", printf("variable v = %d at xyz\n", v));
734
 
735
The tracepoint actions consist of a single print statement, namely:
736
 
737
	printf("variable v = %d at xyz\n", v);
738
 
739
The print statement will be executed only if the tracepoint named "violet" 
740
has been enabled.
741
 
742
Any number of C statements may appear in the list of tracepoint actions.  
743
For example:
744
 
745
	TRACE("peach",
746
		arg = xyz;
747
		p=f(arg);
748
		printf("f(xyz) is %lx at xyz\n", p));
749
 
750
The tracepoint actions consist of the three C statements:
751
 
752
	arg = xyz;
753
	p=f(arg);
754
	printf("f(xyz) is %lx at xyz\n", p);
755
 
756
Note that commas within an instruction in the list of tracepoint actions do 
757
not change the number of arguments to TRACE.  You can write any C 
758
statements in the list of tracepoint actions.  Make sure, though, that you get 
759
enough parentheses at the end of the macro.  Without a trailing parenthesis, 
760
the C preprocessor will complain about the actual parameters to the macro 
761
being too long.
762
 
763
Statements in the list of tracepoint actions may even contain other macros. 
764
For example:
765
 
766
	TRACE("abc",TRACE("xyz",
767
		printf("abc and xyz both enabled\n")));
768
 
769
The TRACEB, TRACEN and TRACEX macros function similarly to the 
770
TRACE macroDthe TRACEN macro does not update count statistics, 
771
while the TRACEB macro is an entry macro and the TRACEX macro is an 
772
exit macro.
773
 
774
 
775
TRACEP, TRACEPB, TRACEPN and TRACEPX
776
 
777
The four members of the TRACEP family function just like the 
778
corresponding four members of the TRACE family except that the 
779
members of the TRACEP family print the name of the tracepoint, a colon 
780
and a space before executing the tracepoint actions.  This is often just what 
781
you want and it saves a little space in your program.  For example, the 
782
following two macros are exactly equivalent, except that the TRACEP 
783
macro takes less space:
784
 
785
	TRACE("daisy", printf("daisy: (arg: %d)\n", n));
786
	TRACEP("daisy", printf("(arg: %d\n", n));
787
 
788
In order to keep the names of the macros straight, it is useful to think of 
789
TRACE and TRACEP as separate families of macros.  In other words, the 
790
letter 'P' is  not  a suffix.  For example, there is a macro named TRACEPB 
791
but no macro named TRACEBP.
792
 
793
The SPP program uses TRACEPB macros to trace the arguments on entry 
794
to a function.  For example, SPP will insert a TRACEPB as shown:
795
 
796
	int example (char *s, int i, float f)
797
	{
798
		TRACEPB("example",
799
			printf("(%s, %d, %f)\n", s, i, f));
800
		...
801
	}
802
 
803
 
804
Other Tracepoint Actions
805
 
806
All the tracepoint actions shown so far have consisted of printf statements.  
807
While that is common, it is often useful to use other statements.  Sherlock 
808
is an open ended tool;  the following paragraphs discuss various kinds of 
809
statements that may be used inside macros.
810
 
811
fprintf statements: Useful for sending tracing output to someplace other 
812
than the console.  Note that output generated from macros is sent to the 
813
standard output stream so that if you redirect output using fprintf be sure to 
814
redirect the standard output stream as well.  For example:
815
 
816
	TRACE("mum", fprintf(out_file, "mum: (%s)\n", flower_name));
817
 
818
Function calls: Useful for printing the contents of complicated data 
819
structures.  This is an important benefitDyou can afford to create tracing 
820
tools that produce a lot of output, because they will be called only when 
821
needed.  You won't get swamped with unwanted output.
822
 
823
For example, suppose you have written a routine called print_vcs() which 
824
prints the contents of a complicated data structure.  You would want to 
825
control that routine by putting it in a Sherlock macro as follows:
826
 
827
	struct very_complicated_struct *vcsp;
828
	...
829
	TRACE("vcs2", print_vcs(vcsp));
830
 
831
Assignment statements: Useful for controlling debugging switches using 
832
command line arguments.  Use assignment statements with caution: they 
833
may produce unexpected results if you enable all tracepoints with a 
834
wildcard.  For example, suppose you have a variable called enable_pass2 
835
which controls whether your program will call a routine called pass2().  
836
You can disable that routine from the command line if you insert the 
837
following into your program:
838
 
839
	TRACE("no_pass2", enable_pass2 = FALSE);
840
 
841
Flow of control statements: These may sometimes be useful for altering the 
842
operation of your program while debugging.  Just as with assignment 
843
statements, use these kinds of statements with caution.  For example, you 
844
might want to set up a header for some kind of report as follows:
845
 
846
	TRACE("hdr", if(hdr= =NULL){hdr="Pre-Release Version";});
847
 
848
Other Sherlock macros: Sherlock macros may be nested.  This can be used 
849
to create levels of debugging.  Indeed, it is often helpful to have several 
850
tracepoints with the same name, e.g., v for verbose.  In the following 
851
example, the function named dump() is called only if both the verbose 
852
option and the dump_x option have been enabled.
853
 
854
	TRACEN("v", TRACE("dump_x", dump(x)));
855
 
856
 
857
The RETURN_xxx Family of Macros
858
 
859
There are eleven members of the RETURN_xxx family.  All are exit 
860
macros.  In addition to signaling the end of timing code, these macros take 
861
the place of return instructions.  There is one RETURN_xxx macro for 
862
each type that a function can return: char, double, float, int, long, unsigned 
863
int, unsigned long and void, and several additional macros for types that 
864
benefit from special formatting: bool, pointer and string.
865
 
866
The RETURN family consists of the following members: 
867
RETURN_BOOL, RETURN_CHAR, RETURN_DOUBLE, 
868
RETURN_FLOAT, RETURN_INT, RETURN_LONG, 
869
RETURN_UINT, RETURN_ULONG, RETURN_PTR, 
870
RETURN_STRING and RETURN_VOID.
871
 
872
All RETURN_xxx macros except RETURN_VOID take two arguments, 
873
the second of which is an expression of the type indicated by the macro.  
874
The expression is evaluated exactly once, regardless of whether the 
875
tracepoint is enabled.  If so, the macro prints out a message telling the 
876
value of the expression.  For example:
877
 
878
	RETURN_BOOL("begonia", 0);
879
 
880
 
881
The last example prints the following message if begonia is enabled:
882
 
883
	begonia: returns: FALSE
884
 
885
Here are some more examples:
886
 
887
	RETURN_VOID("void_function");
888
	RETURN_BOOL("boolean", pi = = 3);
889
	RETURN_CHAR("character", '@');
890
	RETURN_DOUBLE("double_precision", (double) sin(x));
891
	RETURN_FLOAT("floating_point", sin(pi/2.0));
892
	RETURN_INT("integer", floor(i));
893
	RETURN_UINT("unsigned_int", 0xffff);
894
	RETURN_ULONG("unsigned_long", 0xffff);
895
	RETURN_LONG("long", 0L);
896
	RETURN_PTR("pointer", malloc(255));
897
	RETURN_STRING("string", p -> name);
898
 
899
SPP will replace all return instructions by RETURN_xxx macros.  For 
900
example, the following instruction:
901
 
902
	return &array[25];
903
 
904
will be replaced by:
905
 
906
	RETURN_PTR(&array[25]);
907
 
908
SPP will generate RETURN_BOOL macros for all functions declared bool 
909
as long as the following typedef appears before the function:
910
 
911
	typedef int bool;
912
 
913
Be aware that SPP treats all pointers to char as being pointers to a valid 
914
string. This will cause problems in functions such as malloc() which return 
915
a pointer to char which may not be used as a string.  Change 
916
RETURN_STRING to RETURN_PTR in such cases.
917
 
918
 
919
Printing Statistics: SL_DUMP and SL_CLEAR
920
 
921
The SL_DUMP macro prints out a report of all statistics gathered so far. 
922
It takes no arguments and can be called at any time.  For example:
923
 
924
	SL_DUMP();
925
 
926
The report contains several columns. The tracepoints column is an 
927
alphabetized list of tracepoint names, the ticks column gives count statistics 
928
for each tracepoint name, the times1 column gives non-cumulative timing 
929
statistics, the times2 column gives cumulative timing statistics and the 
930
tracing column indicates whether the tracepoint was enabled at the time 
931
SL_DUMP was called.
932
 
933
The SL_CLEAR macro zeros all statistics.  Statistics are zeroed by 
934
SL_INIT so you normally don't need to use SL_CLEAR.  It might be 
935
useful, though, if your program were divided into phases and you wanted 
936
to keep separate statistics for each phase.
937
 
938
 
939
Command Line Arguments
940
 
941
Any command line argument which starts either with the on_prefix or the 
942
off_prefix is interpreted as a command to enable or disable a tracepoint or 
943
group of tracepoints.  For example, suppose the program you are testing, 
944
called z, is usually invoked with two arguments as follows:
945
 
946
	z in out
947
 
948
To enable the tracepoint called abc, precede its name with the on_prefix, 
949
i.e., ++.  Like this:
950
 
951
	z ++abc in out
952
 
953
A Sherlock argument may appear anywhere on the command lineDits 
954
position relative to non-Sherlock arguments does not matter because 
955
SL_PARSE eliminates all Sherlock arguments from the argv vector.  As far 
956
as the rest of your program is concerned, the command line is: 
957
 
958
	z in out
959
 
960
Use the asterisk wildcard and question mark wildcard to select groups of 
961
tracepoints.  The asterisk (*) matches zero or more characters and the 
962
question mark (?) matches exactly one character.  For example, the 
963
following enables all tracepoint names that start with "abc" :
964
 
965
	z ++abc* in out
966
 
967
The following enables all tracepoint names that start with abc and contain 
968
exactly five letters:
969
 
970
	z ++abc?? in out
971
 
972
Any argument which starts with the off_prefix, i.e., '- -', disables one or 
973
more tracepoints.  Sherlock evaluates arguments from left to right, so that 
974
their order is significant.  The following enables all tracepoint names 
975
starting with abc except abc1:
976
 
977
	z ++abc* - -abc1 in out 
978
 
979
The following enables all tracepoint names starting with abc except those 
980
containing exactly five characters, and in addition the tracepoint named 
981
abc12 is also enabled:
982
 
983
	z ++abc* - -abc?? ++abc12 in out
984
 
985
It is easy to use wildcards to enable or disable groups of tracepoints if you 
986
name your breakpoints in a systematic manner.  A good scheme is to prefix 
987
all tracepoint names in a function with the name of that function.
988
 
989
The tracepoint name called "trace" is treated as a special case.  Disabling 
990
that tracepoint name disables all tracepoints.  For example, the following 
991
two command lines will produce identical results, but the first will execute 
992
more quickly than the second:
993
 
994
	z - -trace in out 
995
	z in out
996
 
997
Tracepoints can be re-enabled using the SL_PARSE or SL_ON macros, 
998
but beware of putting those macros inside some other macro, such as 
999
TRACE.  In other words, the following will not work if all tracing has 
1000
been disabled:
1001
 
1002
	TRACE("any", SL_ON("*"));
1003
 
1004
You can temporarily disable a tracepoint by preceding its name with a 
1005
disable count.  For example, the following will suppress the execution of 
1006
the first 100 calls to the tracepoint called loop_trace, after which it will be 
1007
enabled.
1008
 
1009
	z in out ++100loop_trace
1010
 
1011
You can temporarily disable all tracepoints (except STAT macros) by giving 
1012
a global disable count, which is simply the on_prefix followed by a count.  
1013
For example, the following will suppress all tracepoints until 1000 macros 
1014
have been encountered, after which only abc will be enabled:
1015
 
1016
	z ++1000 ++abc in out
1017
 
1018
Beware of extra spaces in command line arguments.  Compare the 
1019
following lines: 
1020
 
1021
	++99abc
1022
	++99  abc
1023
 
1024
The first command line has an argument containing a disable count for abc.  
1025
The second command line contains two arguments: a global disable count 
1026
and a second argument which is not a Sherlock argument at all.
1027
 
1028
 
1029
Macro Definitions: Header Files and the SHERLOCK Constant
1030
 
1031
Sherlock's macros are defined in a header file called sl.h.  This header file 
1032
must be included in each source file that contains a macro.  A good way to 
1033
do this is to put the following line in a "master header file" which is 
1034
included in all source files of your program:
1035
 
1036
	#include "sl.h"
1037
 
1038
The expansion of macros is controlled by a compile time constant called 
1039
SHERLOCK.  Macros expand to code only if this variable is defined.  The 
1040
value of SHERLOCK is not important, only whether it has been defined or 
1041
not.  The constant SHERLOCK must be defined before the file sl.h is 
1042
included.  Thus, the following lines must appear in the order shown:
1043
 
1044
	#define SHERLOCK 1
1045
	#include "sl.h"
1046
 
1047
To completely remove the effects of all Sherlock macros from a file, 
1048
without removing the macros themselves, you need only undefine the 
1049
constant SHERLOCK as follows:
1050
 
1051
	#undef SHERLOCK
1052
	#include "sl.h"
1053
 
1054
If you want to disable a single Sherlock macro, just bracket it with #undef 
1055
SHERLOCK and #define SHERLOCK statements as follows:
1056
 
1057
	#undef SHERLOCK
1058
	sherlock macro
1059
	#define SHERLOCK 1
1060
 
1061
There may be times when you may want to bracket code with #ifdef 
1062
SHERLOCK and #endif.  For example, you might define two different 
1063
signon messages, depending on whether Sherlock macros are in effect:
1064
 
1065
	#ifdef SHERLOCK 
1066
	#define USAGE "usage: cb [++- -tracing routine] in [out]"
1067
	#else 
1068
	#define USAGE "usage: cb in [out]" 
1069
	#endif
1070
 
1071
The file s11.h contains a set of alternate macro definitions.  Most compilers 
1072
will have no problems with the macros defined in sl.h.  However, some 
1073
compilers complain about duplicate definitions of a variable called h when 
1074
compiling the macros defined in sl.h.  If that happens, use the file sl1.h 
1075
instead of sl.hDthat will fix the problem.  Make sure, though, that you use 
1076
sl1.h only as a last resort.  The macros defined in sl1.h work much more 
1077
slowly than the preferred macro definitions in sl.h.
1078
 
1079
 
1080
 
1081
CHAPTER 4  DEBUGGING WITH SHERLOCK
1082
 
1083
 
1084
This chapter offers tips on how to find and correct bugs more effectively.  
1085
Whether you are a student, a hobbyist or a professional programmer, you 
1086
would probably tackle any kind of programming task with confidence and 
1087
enthusiasm if you could be assured of finding all the bugs that might be 
1088
lurking in your code.   Debugging is a crucial step in the programming 
1089
processDit  separates working, successful programs from non-working 
1090
failures.  C programs are particularly challenging to debug because the C 
1091
language does not limit what you can do.  C does not attempt protect you 
1092
from your own mistakes.  The challenge of debugging C stems directly 
1093
from the flexibility and power which C provides.
1094
 
1095
 
1096
Pointer Bugs
1097
 
1098
The key to learning how to debug C programs is recognizing, 
1099
understanding and correcting pointer bugs.  Pointers pervade all of C and 
1100
they give the C language much of its power and flexibility.  However, 
1101
pointers are dangerous, as well as useful.
1102
 
1103
This section addresses the most common situations involving pointer bugs:
1104
 
1105
o Pointer bugs arise from uninitialized pointers, dangling pointers and 
1106
incorrect use of arguments to function.
1107
 
1108
o Pointer bugs often destroy the computer code.  The code destroyed by 
1109
pointer bugs may have been the code you wrote, code comprising run-time 
1110
functions such as printf(), or operating system code.
1111
 
1112
o To the new C programmer, pointer bugs produce symptoms that look like 
1113
hardware malfunctions or compiler bugs.  The experienced C programmer 
1114
recognizes these same symptoms as clear indications of the existence of 
1115
pointer bugs.
1116
 
1117
 
1118
Types of Pointer Bugs
1119
 
1120
Pointer bugs arise from uninitialized pointers, dangling pointers and 
1121
incorrect use of arguments to functions.  An uninitialized pointer is simply 
1122
a pointer variable which is used before it has been given a value.
1123
 
1124
For example,
1125
 
1126
	error1()
1127
	{
1128
		char *p;
1129
		*p = 'a';
1130
	}
1131
 
1132
In this example, p does not point to any specified location at the time that it 
1133
used to store the character 'a'.  The location in memory is not specified by 
1134
the code, and the results are unpredictable.  Possible symptoms will be 
1135
discussed later.
1136
 
1137
The second type of pointer bug is the dangling pointer.  A dangling pointer 
1138
refers to an area of memory which is no longer being used for its original 
1139
purpose.  For example,
1140
 
1141
	error2()
1142
	{
1143
		char *p, *malloc();
1144
		p = malloc(25);
1145
		free(p);
1146
	}
1147
 
1148
The call to malloc() makes p point to an area of memory containing room 
1149
for 25 characters.  The call to free() deallocates the space and causes p to 
1150
become a dangling pointer. However, there is no bug in this code.  Any 
1151
time you deallocate memory you create a dangling pointerDbugs arise from 
1152
using dangling pointers rather than just creating them.  
1153
 
1154
Again, the results of using a dangling pointer are unpredictable.  They are 
1155
not specified by the C program.  In this example, if the memory released by 
1156
the call to free() is later reallocated, using p will probably corrupt the newly 
1157
allocated memory.
1158
 
1159
A third kind of pointer bug is the mistaken parameter bug.  A good example 
1160
is the following:
1161
 
1162
	error3()
1163
	{
1164
		int i;
1165
		scanf("%d", i);
1166
	}
1167
 
1168
This will not work as expected.  The second argument to scanf() should 
1169
have been &i, not i.  The scanf() function expects a pointer to i and gets the 
1170
value of i instead.  Thus, the pointer that scanf() expects is incorrect.  Once 
1171
again this creates a hard-to-find bug.
1172
 
1173
This kind of error can corrupt the system stack.  This happens because the 
1174
called routines assume the stack has a different structure from the stack that 
1175
was actually created by the caller.  If the called program alters any stack 
1176
variable, it will be altering a part of the stack that may not actually 
1177
correspond to the location of the stack variable.
1178
 
1179
Note:  this kind of bug may largely be eliminated by using function 
1180
prototyping which will be part of the new ANSI C standard.
1181
 
1182
 
1183
Effects of Pointer Bugs
1184
 
1185
Having looked at three kinds of pointer bugs, we see that their effects can 
1186
be devastating.  Any pointer bug has the potential for destroying any part of 
1187
memoryDexecutable code, library functions such as printf(), the system 
1188
stack used to keep track of procedure calls and returns or even the operating 
1189
system itself.  Exactly which part of memory depends on the value the 
1190
pointer had at the time your program was loaded.
1191
 
1192
 
1193
Symptoms of Pointer Bugs
1194
 
1195
The symptoms of pointer bugs vary depending on just what kind of code or 
1196
data area are destroyed by the bug.  Such symptoms can not be taken at 
1197
face value. When confronted with behavior such as described below, 
1198
always think first of pointer bugs.
1199
 
1200
 
1201
Symptom 1:
1202
Your program crashes inside a function which you have 
1203
written and which you know to be debugged.
1204
 
1205
Cause:
1206
A pointer bug has destroyed your carefully debugged function.
1207
 
1208
Symptom 2:
1209
A library function suddenly ceases to work correctly.
1210
 
1211
Cause:
1212
A pointer bug has destroyed the library function instead of your own code.
1213
 
1214
Symptom 3:
1215
A bug is solid, i.e., it manifests itself in the same way when you run
1216
the program several times.  However, the bug goes away when you insert print
1217
statements into the code to get more information about it.
1218
 
1219
Cause:
1220
Inserting the print statements changed the location of various parts 
1221
of your code.  Before the print statements were inserted, the pointer bug 
1222
destroyed code that was still to be executed.  After inserting the print 
1223
statements, the pointer bug destroyed a part of the program which was no 
1224
longer executed after the pointer bug occurred.
1225
 
1226
Symptom 4:
1227
The symptoms of a bug change after you insert print statements.
1228
 
1229
Cause:
1230
Inserting print statements changed the code destroyed by the pointer bug.
1231
 
1232
Symptom 5:
1233
By inserting print statements you can determine that control reaches a
1234
particular statement but not the statement immediately following.
1235
 
1236
Cause:
1237
A pointer bug has destroyed one or both of the statements.
1238
 
1239
Symptom 6:
1240
Your program calls a function, but control never reaches the function.
1241
 
1242
Cause:
1243
A pointer bug has destroyed either the system stack or the function itself.
1244
 
1245
Symptom 7:
1246
Control never returns to the caller of a function after the called function
1247
returns.
1248
 
1249
Cause:
1250
A pointer bug has destroyed either the run-time stack or the function itself.
1251
 
1252
Symptom 8:
1253
Your program sometimes works and sometimes crashes.
1254
 
1255
Cause:
1256
An uninitialized variable is destroying random parts of your program depending
1257
on the contents of certain memory locations before your program was invoked.
1258
The pointer bug is destroying different memory locations each time your program
1259
is being run.  Sometimes the destroyed locations do not affect your program and
1260
sometimes they do.
1261
 
1262
Symptom 9:
1263
Your program always works once, but fails the second time it is run.
1264
 
1265
Cause:
1266
Your program contains an uninitialized variable.  The first time your 
1267
program runs the variable is initialized in a uniform way which does not 
1268
cause any apparent harm.  The second time your program runs, the variable 
1269
has a new initial value which depends on the program's first run.  This 
1270
second initial value causes the symptoms the second time the program is 
1271
run.
1272
 
1273
 
1274
Using Sherlock to Find Bugs
1275
 
1276
Using Sherlock to locate bugs is a two-step process.  The process requires 
1277
that the bug happen consistently and that you make a plausible guess about 
1278
its cause.
1279
 
1280
 
1281
Step 1:  Stabilize the Symptoms.
1282
 
1283
The first step in finding the cause of any bug is to make the bug "stand 
1284
still" so that you can study it.  You can do this in the following ways:
1285
 
1286
1. Fill memory with a constant value before you run your program.  This 
1287
will insure that uninitialized pointers get the same (though probably still 
1288
incorrect) value from run to run.  If filling memory with a constant value 
1289
makes the symptoms of your bug go away, you can be reasonably sure that 
1290
some kind of initialization problem is causing the bug.
1291
 
1292
2. Eliminate the effects (including symptoms) of most dangling pointers by 
1293
disabling any routine which frees a dynamically allocated data structure.  
1294
You can do that by providing an alternative deallocation routine which is a 
1295
dummy routine. When you do that, dangling pointers no longer dangle, 
1296
i.e., they no longer point to deallocated memory.  If disabling a routine 
1297
such as free() makes the symptoms of your bug go away, you can be 
1298
reasonably sure that a dangling pointer is at hand.
1299
 
1300
3. Keep precise records about how you invoked your program.  An easy 
1301
way to do this is by invoking the program from a batch file, also known as 
1302
a submit file or shell file. That way the batch file serves as a record for 
1303
exactly what you have done.  A tip:  when you change the arguments to 
1304
your program, comment out the old line and save it in the batch file as a 
1305
record of the your previous runs.  This is especially handy when using 
1306
numerous Sherlock tracepoints to change the behavior of your program 
1307
during testing.
1308
 
1309
4. Keep your program unchanged.  Since pointer bugs destroy code, even 
1310
the smallest change in your program, or even a change in the order in 
1311
which functions are linked together, may cause the symptoms of pointer 
1312
bugs to change or even go away.  Sherlock is a huge help here.  Enabling 
1313
or disabling different tracepoints does not change the location of any code 
1314
in your program.  You can run test after test on your program, getting very 
1315
different information each time, and the symptoms of pointer bugs will not 
1316
change.
1317
 
1318
 
1319
Step 2:  Make a Reasonable Guess about the Cause.
1320
 
1321
The next step in finding a bug is to make a guess about what is causing it.  
1322
If any of the symptoms mentioned above appear, you probably should 
1323
assume that a pointer bug is causing your problems.  Use Sherlock to look 
1324
for bad pointers by tracing the parameters passed to all your functions.  
1325
 
1326
If a supposed pointer has a small negative number as its value (.e.g., 
1327
FFFFE hex), you can be sure that the pointer has already been corrupted.  
1328
You may also notice that a pointer does not have a reasonable value in some 
1329
other way.  Now ask yourself, "Which routines could have passed that 
1330
pointer on to the called routine?"  Rerun your program with different 
1331
tracepoints enabled which will trace the likely culprits.  Once you find the 
1332
source of a bad pointer, ask whether the code which created the bad pointer 
1333
was ultimately at fault or whether some other error resulted in the bad 
1334
pointer as a by-product.
1335
 
1336
Again, Sherlock stands out in being able to try numerous tracing runs on a 
1337
program without having to change the program in any way.  You will find 
1338
that patterns jump out at you as you look at traces and dumps produced by 
1339
Sherlock.  When you get a hint of something in a trace being "not quite 
1340
right," you can immediately start a new trace to zero in on those parts of the 
1341
program that are related to what caught your attention.  By varying your 
1342
traces to home in on suspects, you are eliminating vast amounts of 
1343
extraneous information in the debugging output.
1344
 
1345
 
1346
 
1347
CHAPTER 5  SHERLOCK REFERENCE
1348
 
1349
 
1350
This chapter provides reference information about all aspects of the 
1351
Sherlock systemDit contains the most detailed and complete information 
1352
on any particular topic.  The first sections discuss the following subjects: 
1353
Header Files, Command Line Arguments, Entry and Exit Macros and the 
1354
Timing Stack, The Interrupt Handler, Compiling Support Routines, 
1355
Tracepoint Names and Tracepoint Actions.  The conclusion of this chapter 
1356
discusses each macro, symbol and support routine in alphabetical order.
1357
 
1358
 
1359
Header Files
1360
 
1361
There are two sets of definitions of the Sherlock macros, the preferred 
1362
definitions in sl.h and the alternate definitions in sl1.h.The support routines 
1363
called by the alternate macros search an internal symbol table for their 
1364
tracepoint name every time they are called.  The preferred macros define a 
1365
static variable named h which is used to avoid searching the symbol table 
1366
after an initial search.  As a consequence, preferred macros are much faster 
1367
than the alternate macros.
1368
 
1369
Alas, some compilers do not allow multiple static variables with the same 
1370
name, even if the variables are declared in different blocks.  Use the 
1371
preferred macro definitions unless your compiler objects to constructions 
1372
such as: 
1373
 
1374
	void test()
1375
	{
1376
		{static char *h = 0;}
1377
		{static char *h = 0;}
1378
	}
1379
 
1380
 
1381
Command Line Arguments
1382
 
1383
A Sherlock argument is any command line argument whose prefix is either 
1384
the on_prefix or the off_prefix.  These prefixes are defined by the 
1385
SL_PARSE macro.  For example:
1386
 
1387
	SL_PARSE(argc, argv, "++", "- -");
1388
 
1389
All examples in this manual assume that the on_prefix is "++" and the 
1390
off_prefix is "- -", but any string of any length may be used for either 
1391
prefix.
1392
 
1393
The SL_PARSE macro processes all Sherlock arguments, deleting them 
1394
from the argv vector and adjusting the argc count appropriately.  Thus, any 
1395
code following the SL_PARSE macro will be completely unaware of the 
1396
existence of Sherlock arguments.
1397
 
1398
Two wildcard characters allow Sherlock arguments to specify classes of 
1399
tracepoints.  The asterisk (*) character matches zero or more characters.  
1400
For example, the argument
1401
 
1402
	++abc*
1403
 
1404
enables tracing for any tracepoint whose name begins with abc. The 
1405
asterisk, if present, should be the last character of a Sherlock argument.
1406
 
1407
The question mark (?) character matches exactly one character.  For 
1408
example, the argument
1409
 
1410
	- -abc??
1411
 
1412
disables tracing for abc12 and abc34 but not abc1 or abc123.
1413
 
1414
Sherlock arguments are processed left to right.  The order is significant.  
1415
For example, the following (partial) command line turns on tracing for 
1416
abc1
1417
 
1418
	- -abc* ++abc1
1419
 
1420
As another example, the effect of the first argument in the command line 
1421
below will always be immediately canceled by the second argument.
1422
 
1423
	++abc? - -abc*
1424
 
1425
If the on_prefix or off_prefix is immediately followed by a number, that 
1426
number is taken to be a disable count.  If a name follows the disable count, 
1427
tracing for that tracepoint is disabled until that tracepoint has been executed 
1428
n times, where n is the disable count.  For example,
1429
 
1430
	++100abc
1431
 
1432
disables tracing for the tracepoint named abc until abc has been reached 100 
1433
times.
1434
 
1435
If no string appears after the disable count, it is a global disable count 
1436
which applies to all tracepoints.  All tracing is disabled until n tracepoints 
1437
have been encountered.  For example:
1438
 
1439
	++1000
1440
 
1441
disables all tracing until 1000 tracepoints have been executed.
1442
 
1443
 
1444
Entry and Exit Macros and the Timing Stack
1445
 
1446
Timing statistics measure the time spent in timing code delimited by two 
1447
special kinds of macros.  Entry macros signal the beginning of timing 
1448
code, while exit macros signal the end of timing code.  The support 
1449
routines use an internal timing stack to gather timing statistics in nested 
1450
sections of timing code.
1451
 
1452
There are two kinds of timing statistics: cumulative and non-cumulative.  
1453
Cumulative statistics measure the total time spent in timing code, including 
1454
any time spent in nested timing code.  Non-cumulative statistics excludes 
1455
time spent in nested timing code.
1456
 
1457
At run time, each entry macro requires a corresponding exit macro.  If an 
1458
exit macro is omitted, a timing stack overflow will eventually result.  If an 
1459
extra exit macro is encountered, a timing stack underflow may follow.  A 
1460
timing stack overflow or underflow indicates that the timing statistics 
1461
gathered are not accurate.  Sherlock prints a warning message and a stack 
1462
traceback when either an overflow or an underflow is detected.  The global 
1463
variable, sl_level, indicates the current nesting depth of timing macrosDit 
1464
is incremented by entry macros and decremented by exit macros.  You can 
1465
use the sl_level variable to track down timing stack overflows or 
1466
underflows.
1467
 
1468
 
1469
The Interrupt Handler
1470
 
1471
An interrupt handler is used to gather timing statistics.  In concept, the 
1472
purpose of the handler is simple: to increment the global C variable called 
1473
sl_count each time a timing interrupt occurs.  However, the code for the 
1474
interrupt handler is tricky.
1475
 
1476
Warning: The interrupt handler is inherently machine dependent.  It will 
1477
work only on machines which are 100% compatible with the IBM PC, XT 
1478
or AT.  It will be necessary to rewrite the interrupt handler if you want to 
1479
gather timing statistics on other machines.
1480
 
1481
The interrupt handler consists of three parts: an initializer, a tick handler 
1482
and an exit handler.  The initializer changes the hardware interrupt trap 
1483
vectors to point to entry points inside the tick handler and the exit handler.  
1484
The initializer also increases the frequency of the hardware timer interrupt.  
1485
It does this by directly writing to one of the timer chips.  The speed up 
1486
factor is determined by the value of the global C variable called sl_speed, 
1487
which is defined in the file sherlock.c.  The default speed-up factor is 55, 
1488
which gives an interrupt rate of about 1 interrupt per millisecond, assuming 
1489
a basic tick frequency of 18.2 ticks per second.
1490
 
1491
 
1492
The tick handler receives control as the result of tick interrupts.  It 
1493
increments the global C variable called SL_COUNT.  It also passes on 
1494
selected ticks on to the default tick handler so that the nominal tick 
1495
frequency of 18.2 ticks per second is maintained.
1496
 
1497
The exit handler gets control from any DOS function call or interrupt that 
1498
results in an exit from the program.  This exit handler restores all the 
1499
interrupt vectors which were changed by the initializer.
1500
 
1501
 
1502
Compiling Support Routines
1503
 
1504
The source code for the support routines was developed on the Turbo C 
1505
compiler version 1.5 and will compile correctly with the Microsoft C 
1506
compiler version 5.0 or later.
1507
 
1508
The source code for the support routines uses function prototypes which 
1509
are a part of the draft ANSI C standard.  Not all current compilers support 
1510
function prototypes.  To compile
1511
Sherlock on compilers that do not, comment out the definition of the 
1512
compile time variable called HAS_PROTOTYPES at the start of the header 
1513
file sl.h.
1514
 
1515
 
1516
Tracepoint Names
1517
 
1518
Tracepoint names are strings which must contain only the following 
1519
characters: the letters a-z and A-Z, the numbers 0-9 and the underscore 
1520
character.  A warning message is printed if a macro is passed a tracepoint 
1521
name which contains any other character.
1522
 
1523
 
1524
Tracepoint Actions
1525
 
1526
Tracepoint actions consist of a statement list consisting of zero, one or 
1527
more C language statements.  Statements must be separated by semicolons 
1528
as usual.  The statement list may be terminated by a semicolon, but need 
1529
not be.
1530
 
1531
 
1532
Macros, Global Variables and Support Routines
1533
 
1534
The following sections discuss each Sherlock macro and variable and a few 
1535
globally visible support routines.  All entries appear in alphabetical order.
1536
 
1537
 
1538
Macros:
1539
	RETURN_BOOL  (tracepoint_name, boolean_expression)
1540
	RETURN_CHAR  (tracepoint_name, char_expression)
1541
	RETURN_DOUBLE(tracepoint_name, double_expression)
1542
	RETURN_FLOAT (tracepoint_name, float_expression)
1543
	RETURN_INT   (tracepoint_name, int_expression)
1544
	RETURN_LONG  (tracepoint_name, long_expression)
1545
	RETURN_PTR   (tracepoint_name, pointer_expression)
1546
	RETURN_STRING(tracepoint_name, string_expression)
1547
	RETURN_UINT  (tracepoint_name, unsigned_int_expression)
1548
	RETURN_ULONG (tracepoint_name, unsigned_long_expression)
1549
	RETURN_VOID  (tracepoint_name)
1550
 
1551
Synopsis:	Print tracepoint name.  Print and return the value of the 
1552
expression.
1553
 
1554
Examples:
1555
	RETURN_BOOL  ("abc", a ? 0 : 1);
1556
	RETURN_CHAR  ("abc", "\n");
1557
	RETURN_DOUBLE("abc", 0.6666666666666666);
1558
	RETURN_FLOAT ("abc", 3.14159);
1559
	RETURN_INT   ("abc", a - 15);
1560
	RETURN_LONG  ("abc", 1L);
1561
	RETURN_PTR   ("abc", &abc);
1562
	RETURN_STRING("abc", "this is a test");
1563
	RETURN_UINT  ("abc", (unsigned) 0xffff);
1564
	RETURN_ULONG ("abc", (unsigned) 0xffff0000);
1565
	RETURN_VOID  ("abc");
1566
 
1567
These macros are all exit macros.  Each macro prints the tracepoint name, a 
1568
colon, a space, "returns", a colon, a space, followed by the value of the 
1569
expression.  The RETURN_VOID macro prints "void" in place of the 
1570
value of the expression.  Each macro completes and records the timing 
1571
statistics associated with the timing section begun by the corresponding 
1572
entry macro.  Each macro then returns from a function of the indicated 
1573
type.
1574
 
1575
At run time, each of these macros must be matched with an entry macro.  If 
1576
an exit macro is encountered without a corresponding entry macro, a timing 
1577
stack underflow will eventually occur.
1578
 
1579
The SPP utility program will generate RETURN_BOOL macros for all 
1580
functions declared bool as long as the following typedef appears before the 
1581
function:
1582
 
1583
	typedef int bool;
1584
 
1585
Be aware that SPP treats all pointers to char as being pointers to a valid 
1586
string. This will cause problems in functions such as malloc() which return 
1587
a pointer to char which may not be used as a string.  Change 
1588
RETURN_STRING to RETURN_PTR in such cases.
1589
 
1590
 
1591
Compile time symbol:	SHERLOCK
1592
 
1593
Synopsis:	Enable or disable expansion of all Sherlock macros.
1594
 
1595
Example:	#define SHERLOCK 1
1596
		#include "sl.h"
1597
 
1598
Sherlock's macros expand into actual code only if this symbol is defined.  
1599
The value assigned to the variable SHERLOCK does not matter, only 
1600
whether it is defined or not.  If SHERLOCK is not defined, then all 
1601
Sherlock's macros expand to no code, or a return statement in the case of 
1602
RETURN_xxx macros.
1603
 
1604
Notice that the definition of SHERLOCK must precede the definitions of 
1605
the macros in sl.h.  The following will not work as expected:
1606
 
1607
	#include "sl.h"
1608
	#define SHERLOCK 1
1609
 
1610
Do this instead:
1611
 
1612
	#define SHERLOCK 1
1613
	#include "sl.h"
1614
 
1615
Actually, it is usually a good idea to enable the SHERLOCK constant from 
1616
the command line.  When using the Microsoft C compiler, use the /D 
1617
option, like this:
1618
 
1619
	/DSHERLOCK
1620
 
1621
When using the Turbo C compiler, use the -D option, as follows:
1622
 
1623
	-DSHERLOCK
1624
 
1625
 
1626
Support Routines:
1627
	typedef int bool;
1628
	void	sl_bout(bool b);
1629
	void	sl_cout(char c);
1630
	void	sl_dout(double d);
1631
	void	sl_iout(int i);
1632
	void	sl_lout(long l);
1633
	void	sl_pout(void * s);
1634
	void	sl_sout(char * p);
1635
	void	sl_uiout(unsigned int ui);
1636
	void	sl_ulout(unsigned long ul);
1637
 
1638
Synopsis:
1639
	sl_bout:	Print a boolean expression using sl_cout().
1640
	sl_cout:	Print a character using putchar().
1641
	sl_dout:	Print a double or float expression using sl_cout().
1642
	sl_iout:		Print an int expression using sl_cout().
1643
	sl_lout:		Print a long expression using sl_cout().
1644
	sl_pout:	Print a pointer expression using sl_cout().
1645
	sl_sout:	Print a string using sl_cout().
1646
	sl_uiout:	Print an unsigned int expression using sl_cout().
1647
	sl_ulout:	Print an unsigned long expression using sl_cout().
1648
 
1649
Example:
1650
	void sample(b, c, d, f, i, l, p, s, u, ul)
1651
	bool b; char c;
1652
	double d; float f;
1653
	int i; long l;
1654
	struct some_struct *p; char *s;
1655
	unsigned ui; unsigned long ul;
1656
	{
1657
		TICKB("sample",
1658
			sl_bout(b); sl_sout(", ");
1659
			sl_cout(c); sl_sout(", ");
1660
			sl_dout(d); sl_sout(", ");
1661
			sl_dout(f); sl_sout(", ");
1662
			sl_iout(i); sl_sout(", ");
1663
			sl_lout(l); sl_sout(", ");
1664
			sl_pout(p); sl_sout(", ");
1665
			sl_sout(s); sl_sout(", ");
1666
			sl_uiout(u); sl_sout(", ");
1667
			sl_ulout(ul));
1668
		...
1669
		TICKX("sample");
1670
	}
1671
 
1672
These support routines print a single expression of the indicated type.  The 
1673
sprintf() function is used to format the value into a character buffer, which 
1674
is then printed using sl_sout().  The sl_sout() routine calls sl_cout() so the 
1675
output of all these routines eventually is funneled through sl_cout().  
1676
Indeed, all output produced by the macros and the support routines 
1677
eventually is handled by sl_cout().
1678
 
1679
 
1680
Macro:		SL_CLEAR()
1681
 
1682
Synopsis:	Clear all statistics.
1683
 
1684
Example:	SL_CLEAR();
1685
 
1686
See also:	SL_DUMP
1687
 
1688
This macro clears all the statistics gathered so far.  The SL_INIT macro 
1689
also does this, so normally there is no need to use this macro.  You might 
1690
use this macro to begin gathering statistics about a selected portion of your 
1691
code.  Call SL_CLEAR at the start of the section and SL_DUMP at the end 
1692
of the section.
1693
 
1694
 
1695
Macro:		SL_DUMP()
1696
 
1697
Synopsis:	Write a report of statistics.
1698
 
1699
Example:	TRACE("dump", SL_DUMP());
1700
 
1701
See Also:	SL_CLEAR
1702
 
1703
This macro writes a report of all the statistics gathered for all tracepoints 
1704
encountered so far.  Output is written using the sl_cout() support routine.
1705
 
1706
The report contains five columns. The tracepoints column is an 
1707
alphabetized list of tracepoint names.  The ticks column gives count 
1708
statistics for each tracepoint name.  The times1 column gives non-
1709
cumulative timing statistics and the times2 column gives cumulative timing 
1710
statistics.  The tracing column indicates whether the tracepoint was enabled 
1711
when SL_DUMP was called.
1712
 
1713
Reports may be enabled from the command line by inserting the 
1714
SL_DUMP macro in another macro such as TRACE or TRACEN.
1715
 
1716
 
1717
Macro:		SL_INIT()
1718
 
1719
Synopsis:	Initialize Sherlock's support routines.
1720
 
1721
Example:
1722
	main(argc, argv)
1723
	int argc;
1724
	char **argv;
1725
	{
1726
		/* Local declarations. */
1727
		SL_INIT();
1728
		SL_PARSE(argc, arg, "++", "- -");
1729
 
1730
		/* Sherlock arguments not visible here. */
1731
		...
1732
	}
1733
 
1734
This macro initializes Sherlock's support routines.  It must be called before 
1735
any other Sherlock macro.
1736
 
1737
 
1738
Global Variable:
1739
	sl_level
1740
 
1741
Synopsis:
1742
	The current nesting level.
1743
 
1744
Example:
1745
	if (sl_level > 0) {
1746
			printf("unmatched entry macro.\n");
1747
	}
1748
 
1749
This global variable is incremented every time an entry macro is 
1750
encountered and is decremented every time an exit macro is encountered.  
1751
This variable can be used to find unpaired entry and exit macros.
1752
 
1753
 
1754
Macro:		SL_NAME(tracepoint_tag, tracepoint_name)
1755
 
1756
Synopsis:	Define a static char array which can be used as a tracepoint 
1757
		name.
1758
 
1759
Example:
1760
 
1761
	int
1762
	long_winded_function_name()
1763
	{
1764
		SL_NAME(func2_tag, "long_winded_function_name");
1765
		TICKB(func2_tag);
1766
		...
1767
		RETURN_VOID(func2_tag);
1768
	}
1769
 
1770
Use the SL_NAME macro to reduce the space required to store tracepoint 
1771
names.  In the example above, space for the string "func2" is allocated 
1772
once, rather than twice.
1773
 
1774
Note: The SDEL program will retain all SL_NAME macros if the -r option 
1775
is given to SDEL.  Use the -r option when using SDEL to delete Sherlock 
1776
macros just prior to reinserting them with SPP.
1777
 
1778
 
1779
Macros:
1780
	SL_OFF(tracepoint_name)
1781
	SL_ON(tracepoint_name)
1782
 
1783
Synopsis:
1784
	SL_OFF:	Disable one or more tracepoints.
1785
	SL_ON:	Enable one or more tracepoints.
1786
 
1787
Examples:
1788
	SL_OFF("abc");
1789
	SL_ON("200abc");
1790
 
1791
Special cases:
1792
	SL_OFF("trace");
1793
	SL_ON("trace");
1794
 
1795
See Also:		SL_PARSE
1796
 
1797
These macros enable or disable the tracing for a single tracepoint, just as if 
1798
the name of the tracepoint were appended to the end of the command line.  
1799
Neither the on_prefix nor the off_prefix is used.  Wildcard characters and 
1800
disable counts are allowed.  The name "trace" is a special case which 
1801
enables or disables the tracing of all tracepoints.
1802
 
1803
 
1804
Macro:
1805
	SL_PARSE(argc, argv, on_prefix, off_prefix)
1806
 
1807
Synopsis:
1808
	Enable or disable tracepoints indicated by an argument vector.
1809
 
1810
Example:
1811
	SL_INIT();
1812
	SL_PARSE(argc, argv, "++", "- -");
1813
 
1814
See also:	SL_ON, SL_OFF
1815
 
1816
This macro enables or disables tracepoints indicated by an argument vector 
1817
and removes all Sherlock arguments from the vector. 
1818
 
1819
The argc argument gives a count of the number of elements in the argv 
1820
argument, which is an array of pointers to strings.  The on_prefix and 
1821
off_prefix arguments are strings which denote Sherlock command line 
1822
arguments.  Arguments in argv starting with on_prefix enable tracing, 
1823
while arguments in argv starting with off_prefix disable tracing.
1824
 
1825
The argv vector is scanned for argc - 1 arguments starting with argv[1].  
1826
Argv[0] is ignored.  When arguments starting with either the on_prefix or 
1827
off_prefix are found, the indicated tracepoint is enabled or disabled, the 
1828
argument is removed from the argv vector and the argc count is 
1829
decremented.  On entry to SL_PARSE, argv[argc] must be NULL.
1830
 
1831
This macro may be called more than once and the argc and argv arguments 
1832
need not be the same as the argc and argv arguments passed to the main() 
1833
function by the operating system.  In other words, you are free to call this 
1834
macro with a "simulated command line."  For example:
1835
 
1836
	static int count = 4;
1837
	static char * vect [] =
1838
		{NULL, "++*", "- -sys*", "++sys_fopen", NULL};
1839
 
1840
	...
1841
 
1842
	SL_PARSE(count, vect, "++", "- -");
1843
 
1844
 
1845
Support Routine:
1846
	sl_regs()
1847
 
1848
Synopsis:
1849
	Put the contents of all machine registers into global variables.
1850
 
1851
Example:
1852
	TRACE("dump_regs", sl_regs());
1853
 
1854
This support routine does not have a corresponding macro.  It places the 
1855
contents of the PC's registers into global memory locations.  See regs.asm 
1856
for details.
1857
 
1858
 
1859
Macros:
1860
	STAT(tracepoint_name)
1861
	STATB(tracepoint_name)
1862
	STATX(tracepoint_name)
1863
 
1864
Synopsis:
1865
	STAT:	Update the count statistics for a tracepoint.
1866
	STATB:	Entry macro.  Otherwise same as STAT.
1867
	STATX:	Exit macro.  Otherwise same as STAT.
1868
 
1869
Example:
1870
	int f1()
1871
	{
1872
		int i, val;
1873
		STATB("f1");
1874
		for (i = 0; i < 5; i++) {
1875
			STAT("f1_loop");
1876
			val++;
1877
		}
1878
		STATX("f1");
1879
	}
1880
 
1881
These STAT family of macros update the count statistics associated with the 
1882
tracepoint name, regardless of whether the tracepoint name is enabled or 
1883
not.  This family of macros never produces output.  The STATB macro 
1884
begins timing code and the STATX macro ends timing code.
1885
 
1886
 
1887
Macros:
1888
	TICK(tracepoint_name)
1889
	TICKB(tracepoint_name)
1890
	TICKN(tracepoint_name)
1891
	TICKX(tracepoint_name)
1892
 
1893
Synopsis:
1894
	TICK:	Print the tracepoint name, a colon and a newline and update 
1895
		count statistic.
1896
	TICKB:	Entry macro.  Otherwise same as TICK.
1897
	TICKN:	Do not update count statistic.  Otherwise same as TICK.
1898
	TICKX:	Exit macro.  Otherwise same as TICK.
1899
 
1900
Example:
1901
	int f2(int i)
1902
	{
1903
		int val;
1904
 
1905
		TICKB("f2");
1906
		for (i = 0; i < 5; i++) {
1907
			TICK("f2_before");
1908
			val++;
1909
		}
1910
		TICKX("f2");
1911
 
1912
		return val+5;
1913
	}
1914
 
1915
If enabled, the TICK family of macros print the tracepoint name, a colon 
1916
and a newline using the sl_sout() support routine.
1917
 
1918
The TICK, TICKB and TICKX macros update the count statistics 
1919
associated with the tracepoint, whether enabled or disabled.  However, the 
1920
statistics are not updated if all tracing has been disabled as the result of 
1921
disabling the special tracepoint named "trace". The TICKN macro never 
1922
updates any statistics.
1923
 
1924
The TICKB macro begins timing code and the TICKX macro ends timing 
1925
code.
1926
 
1927
 
1928
Macros:
1929
	TRACE(tracepoint_name, code_list)
1930
	TRACEB(tracepoint_name, code_list)
1931
	TRACEN(tracepoint_name, code_list)
1932
	TRACEX(tracepoint_name, code_list)
1933
 
1934
Synopsis:
1935
	TRACE: 	Execute code list and update count statistics.
1936
	TRACEB:	Entry macro.  Otherwise same as TRACE.
1937
	TRACEN:	Do not update count statistics.  Otherwise same as TRACE.
1938
	TRACEX:	Exit macro.  Otherwise same as TRACE.
1939
 
1940
Example:
1941
	int f3(int i)
1942
	{
1943
		int val;
1944
 
1945
		TRACEB("f3", printf("f3 entry: %d\n", i));
1946
		for (i = 0; i < 5; i++) {
1947
			TRACE("f3_loop",
1948
				printf("f3: i = %d\n", i));
1949
			val++;
1950
		}
1951
		RETURN_INT("f3", val+5);
1952
	}
1953
 
1954
If enabled, the TRACE family of macros execute a code list containing 
1955
zero, one, or more executable C statements of any kind.
1956
 
1957
The TRACE, TRACEB and TRACEX macros update the count statistics 
1958
associated with the tracepoint, whether enabled or disabled.  However, the 
1959
statistics are not updated if all tracing has been disabled as the result of 
1960
disabling the special tracepoint named "trace".  The TRACEN macro never 
1961
updates any statistics.
1962
 
1963
The TRACEB macro begins timing code and the TRACEX macro ends 
1964
timing code.
1965
 
1966
 
1967
Macros:
1968
	TRACEP(tracepoint_name, code_list)
1969
	TRACEPB(tracepoint_name, code_list)
1970
	TRACEPN(tracepoint_name, code_list)
1971
	TRACEPX(tracepoint_name, code_list)
1972
 
1973
Synopsis:
1974
	TRACEP: 	Print the tracepoint name, execute code list and 
1975
			update count statistics.
1976
	TRACEPB:	Entry macro.  Otherwise same as TRACEP.
1977
	TRACEPN:	Do not update count statistics.  Otherwise same as 
1978
			TRACEP.
1979
	TRACEPX:	Exit macro.  Otherwise same as TRACEP.
1980
 
1981
Example:
1982
	int f4(int i)
1983
	{
1984
		int val;
1985
 
1986
		TRACEPB("f4", printf("(%d)\n", i));
1987
		for (i = 0; i < 5; i++) {
1988
			TRACEP("f4_loop", printf("i = %d\n", i));
1989
			val++;
1990
		}
1991
		RETURN_INT("f4", val+5);
1992
	}
1993
 
1994
If enabled, the TRACEP family of macros print the tracepoint name, a 
1995
colon and a blank, and then execute a code list containing zero, one, or 
1996
more executable C statements of any kind.  The tracepoint name, colon and 
1997
blank are printed using the sl_sout() support routine.
1998
 
1999
The TRACEP, TRACEPB and TRACEPX macros update the count 
2000
statistics associated with the tracepoint, whether enabled or disabled.  
2001
However, the statistics are not updated if all tracing has been disabled as 
2002
the result of disabling the special tracepoint named "trace".  The 
2003
TRACEPN macro never updates any statistics.
2004
 
2005
The TRACEPB macro begins timing code and the TRACEPX macro ends 
2006
timing code.
2007
 
2008
 
2009
 
2010
CHAPTER 6  SPP REFERENCE
2011
 
2012
SPP is a utility program that copies an input file to an output file, inserting 
2013
Sherlock macros that trace the entry and exit of all functions.  TICKB 
2014
macros or TRACEPB macros containing printf statements are inserted at 
2015
the start of functions, return instructions are replaced by RETURN_xxx 
2016
macros, and TICKX macros are inserted where control might "fall off the 
2017
end" of functions.  SPP also inserts SL_INIT and SL_PARSE macros at 
2018
the start of the main() function.  Several command line options vary the 
2019
kind and quantity of macros output inserted by SPP.  
2020
 
2021
SPP is essentially a source-to-source C compiler which understands the 
2022
type of all variables and functions.  SPP handles all styles of C syntax, 
2023
from K&R to the ANSI draft standard of January 11, 1988.  SPP is 
2024
robust: it flags all syntax errors and will place correct macros in the 
2025
appropriate locations in spite of most syntax errors.  It is recommended, 
2026
however, that  SPP be used only on files that contain no syntax errors, 
2027
i.e., on files that have been previously been compiled without generating 
2028
any error messages.
2029
 
2030
SPP generates RETURN_BOOL macros in functions declared bool as long 
2031
as the declaration:
2032
 
2033
	typedef int bool;
2034
 
2035
appears before the bool function.  SPP generates printf statements that 
2036
print boolean arguments as either "TRUE" or "FALSE" instead of 1 or 0.  
2037
This is done using calls to a support routine called sl_sbout().  The 
2038
RETURN_BOOL macro is not affected by this feature.For example, SPP 
2039
will insert the following macros:
2040
 
2041
	bool f(bool b)
2042
	{
2043
		TRACEPB("f", printf("(%s)\n", sl_sbout(b)));
2044
		...
2045
		RETURN_BOOL("f", 1);
2046
	}
2047
 
2048
SPP assumes that all pointers to characters are pointers to a valid string.  
2049
As a result, you should change the RETURN_STRING macros generated 
2050
by SPP to RETURN_PTR macros in functions such as malloc() which 
2051
return a pointer that can not be printed as a string. 
2052
 
2053
SPP warns about functions that do not return a value and are not explicitly 
2054
declared void.
2055
 
2056
SPP issues the warning, "Macro found where entry macro should be," if 
2057
SPP finds a macro call where the first executable statement of a function is 
2058
expected.  In such cases, SPP will skip the generation of an entry macro, 
2059
i.e., TICKB or TRACEPB.  Instead, SPP assumes the macro starts 
2060
executable code.
2061
 
2062
For example:
2063
 
2064
	int f(void)
2065
	{
2066
		int a;
2067
		MY_TRACE_MACRO(a);
2068
		return a;
2069
	}
2070
 
2071
SPP will generate the following code:
2072
 
2073
int f(void)
2074
	{
2075
		int a;
2076
		MY_TRACE_MACRO(a);
2077
		RETURN_INT("f",a);
2078
	}
2079
 
2080
SPP generates macros for a function only if the first executable statement 
2081
of that function is not already a Sherlock macro.  SPP will generate the 
2082
warning, "Sherlock macros generated for this function," if a Sherlock 
2083
macro is encountered while generating macros for a function.  That is, the 
2084
warning will be generated if the function contains Sherlock macros but the 
2085
first executable statement is not a Sherlock macro.  This new feature is 
2086
very handyDyou can now run your source files through SPP any time you 
2087
add any function and SPP will leave the functions already containing 
2088
Sherlock macros alone.
2089
 
2090
Two new macros, SL_ENABLE() and SL_DISABLE(), allow function-
2091
by-function control over SPP.  Both macros always expand to empty code. 
2092
Insert SL_DISABLE() as the first executable statement of a function in 
2093
which you want no more Sherlock macros to be inserted.  For example: 
2094
 
2095
	int f(void)
2096
	{
2097
		declarations;
2098
		SL_DISABLE();
2099
		No Sherlock macros will be generated in this function.
2100
	}
2101
 
2102
The SL_ENABLE() macro forces SPP to insert macros into a function.  
2103
Use this macro when a function starts with a Sherlock macro that you 
2104
inserted yourself.  For example:
2105
 
2106
	int do_command_line(int argc, char **argv)
2107
	{
2108
		declarations;
2109
		SL_ENABLE();
2110
		TRACEP("do_command_line",
2111
				for (i = 1; i < argc; i++) {
2112
					printf("argv[%d]: %s\n", argc, argv);
2113
				}
2114
		);
2115
		Sherlock macros will be generated as usual.
2116
	}
2117
 
2118
Be sure to delete the SL_ENABLE() macro after SPP processes the 
2119
function.
2120
 
2121
 
2122
Invoke SPP as follows:
2123
 
2124
	SPP input_file  output_file  [options]
2125
 
2126
SPP supports the INCLUDE environment variable, which is set with the 
2127
DOS set command.  For example, the DOS command:   
2128
 
2129
	set INCLUDE=c:\include;d:\sherlock
2130
 
2131
will cause SPP to search the c:\include and d:\sherlock directories for 
2132
#include files.  The directories specified by the INCLUDE environment 
2133
variable are searched after any directories specified by the -s SPP option.
2134
 
2135
Options are one of the following:
2136
 
2137
 
2138
-d <id>=<string>
2139
 
2140
Define <id> to be <string>, as if the statement #define <id> <string> 
2141
appeared at the start of the program.  A space must separate -d and <id>, 
2142
but no space may appear in <string> or around the equal sign.  The 
2143
<string> is optional, in which case the equal sign can be omitted.  
2144
Examples:
2145
 
2146
	-d STDC=1
2147
	-d SHERLOCK
2148
 
2149
 
2150
-f <file name>
2151
 
2152
Use alternate macro names.  The file named in <file name>  contains a list 
2153
of synonym lines.  Each line contains two macro names, a standard name 
2154
and a synonym.  SPP will output the synonyms instead of the standard 
2155
macro names.  The pound character (#) starts a comment which continues 
2156
to the end of the line.  An example synonym file:
2157
 
2158
	#synonym file:  May 20, 1988
2159
	#
2160
	TICKB		BEGIN_TIMING_CODE
2161
	TICKX		END_TIMING_CODE
2162
	SL_DUMP		REPORT_STATISTICS
2163
 
2164
 
2165
-i
2166
 
2167
Insert the line #include <sl.h> at the start of the output file.
2168
 
2169
 
2170
-n
2171
 
2172
Allow nested comments.  By default, comments do not nest.
2173
 
2174
 
2175
-o
2176
Output sl_cout() and related support routines instead of printf().  SPP 
2177
generates more compact code when using the -o option by generating calls 
2178
to three new support routines: sl_lpout(void), sl_rpout(void) and 
2179
sl_csout(void).  These routines are equivalent to sl_cout("("), sl_sout(")"), 
2180
and sl_sout(", ") respectively.
2181
 
2182
 
2183
-s <path>
2184
 
2185
Add <path> to the list of paths used to search for include files.  More than 
2186
one -s option may be used.  A space must separate -s and <path>.  Example:
2187
 
2188
	-s \usr\include  -s \sources  -s \sherlock
2189
 
2190
-t
2191
 
2192
Suppress the generation of entry or exit macros.  TICK and TRACEP macros are
2193
generated instead of TICKB and TRACEPB macros.  No RETURN_xxx macros are
2194
generated.
2195
 
2196
 
2197
-u <id>
2198
 
2199
Undefine <id>, as if the statement #undef <id> appeared at the start of the 
2200
program.  A space must separate -u and <id>.
2201
 
2202
-x
2203
 
2204
Do not recognize single-line comments.
2205
 
2206
By default, SPP recognizes single-line comments, which start with // and 
2207
continue to the end of the line.  As you would expect, the // sequence is 
2208
treated as ordinary characters in comments and inside strings.  Single-line 
2209
comments are not part of the Draft ANSI C standard, but are offered as 
2210
language extensions by several C compilers, including the Microsoft C 
2211
compiler.
2212
 
2213
A fine point:  each single-line comment is converted to a single blank in the 
2214
replacement text of a #define preprocessor directive.  The // characters and 
2215
any following characters do not become part of the replacement text of the 
2216
macro being defined.  This is consistent with how ordinary C comments 
2217
are handled in the Draft ANSI C Standard, and is also consistent with how 
2218
current C++ compilers work.  However, old C++ translators handled // 
2219
differently.  Warning: the description of single-line comments on page 130 
2220
of The C++ Programming Language, by Bjarne Stroustrup, describes the 
2221
anachronistic operation of the old C++ translators, not current C and C++ 
2222
compilers.
2223
 
2224
 
2225
Example:
2226
 
2227
Original program:
2228
 
2229
int example(char * string, double)
2230
{
2231
	int i;
2232
	i = 25;
2233
	return i;
2234
}
2235
 
2236
Default output from SPP:
2237
 
2238
int example(char * string, double d)
2239
{
2240
	int i;
2241
	TRACEPB("example",printf("(%s, %f)\n", string, d));
2242
	i = 25;
2243
	RETURN_INT("example", i);
2244
}
2245
 
2246
Output from SPP with the -t option on:
2247
 
2248
int example(char * string, double d)
2249
{
2250
	int i;
2251
	TRACEP("example",printf("(%s, %f)\n", string, d));
2252
	i = 25;
2253
	return i;
2254
}
2255
 
2256
Output from SPP with the -o option on:
2257
 
2258
int example(char * string, double d)
2259
{
2260
	int i;
2261
	TRACEPB("example",	  sl_lpout();
2262
		sl_sout(string);  sl_csout();
2263
		sl_dout(d);       sl_rlout());
2264
	i = 25;
2265
	RETURN_INT("example", i);
2266
}
2267
 
2268
 
2269
 
2270
CHAPTER 7  SDEL REFERENCE
2271
 
2272
 
2273
SDEL is a utility program that copies an input file to an output file, deleting 
2274
all calls to Sherlock macros as it does so.  It is not usually necessary to 
2275
remove Sherlock macros from a program in order to eliminate all the code 
2276
generated by Sherlock macros.  Indeed, you can eliminate all Sherlock 
2277
tracing code from your application simply by undefining the constant called 
2278
SHERLOCK and recompiling your program.  However, there may be 
2279
times when you want to remove all Sherlock macros from one of your 
2280
source files.  For instance, you may want to delete all Sherlock macros 
2281
before automatically re-introducing them with SPP.
2282
 
2283
Invoke SDEL as follows:
2284
 
2285
	SDEL input_file output_file [options]
2286
 
2287
For your protection, the name of the input file may not be the same as the 
2288
output file, and the output file must not already exist.
2289
 
2290
Options are one of the following:
2291
 
2292
 
2293
-d
2294
 
2295
Do not delete SL_DISABLE() macros.
2296
 
2297
 
2298
 
2299
-f	<file name>
2300
 
2301
Use alternate macro names.  The file named in <file name>  contains a list 
2302
of synonym lines.  Each line contains two macro names, a standard name 
2303
and a synonym.  SDEL will delete the synonyms instead of the standard 
2304
macro names.  The pound character (#) starts a comment which continues 
2305
to the end of the line.  An example synonym file:
2306
 
2307
	#synonym file:  May 20, 1988
2308
	#
2309
	TICKB		BEGIN_TIMING_CODE
2310
	TICKX		END_TIMING_CODE
2311
	SL_DUMP	REPORT_STATISTICS
2312
 
2313
 
2314
-i
2315
 
2316
Remove any lines consisting solely of:
2317
 
2318
	#include "sl.h"
2319
 
2320
 
2321
-n
2322
 
2323
Allow nested comments.  By default, comments do not nest.
2324
 
2325
 
2326
-r
2327
 
2328
Retain all SL_NAME macros (or synonyms for SL_NAME) in the output.
2329
 
2330
 
2331
-t
2332
 
2333
Output trigraph sequences instead of the following nine characters:
2334
 
2335
	  #  [  ]  \  {  }  ^  |  ~
2336
 
2337
 
2338
 
2339
CHAPTER 8  SDIF REFERENCE
2340
 
2341
 
2342
SDIF is a special purpose file comparison programDit compares two files 
2343
which should be identical except for the presence of Sherlock macros.  
2344
SDIF allows you to see at a glance which macros where inserted into a file 
2345
by SPP.  You can also use SDIF to check the operation of SPP and SDEL.  
2346
Given any file f.c containing Sherlock macros, the following sequence of 
2347
commands should produce output from SDIF consisting of lines containing 
2348
only white space:
2349
 
2350
	sdel f.c     temp1.c
2351
	spp  temp1.c temp2.c
2352
	sdel temp2.c temp3.c
2353
	sdif temp1.c temp3.c
2354
 
2355
Invoke SDIF as follows:
2356
 
2357
	SDIF file1(with_macros)  file2(without_macros) [-b] [-v]
2358
 
2359
File1 is assumed to be identical to file2 except that file1 contains Sherlock 
2360
macros and file2 does not.
2361
 
2362
The -b option causes SDIF to display inserted or deleted lines consisting 
2363
only on blanks or tabs.  By default SDIF does not display such lines 
2364
unless the -v option is in effect.
2365
 
2366
If the -v option is present, each line of file1 is printed, preceded by its 
2367
position in file1 and its position in file2 if the line also appears in file2.  If 
2368
the -v option is not present, only lines which are present in one file but not 
2369
the other are printed.
2370
 
2371
All output is sent to the standard output stream and may be redirected on 
2372
the command line.
2373
 
2374
 
2375
 
2376
CHAPTER 9  CPP REFERENCE
2377
 
2378
 
2379
CPP is a preprocessor for the C language which has been included as an 
2380
extensive example of how to use Sherlock macros.  CPP fully implements 
2381
the draft ANSI standard of January 11, 1988.  For a complete discussion 
2382
of what CPP does read section 3.8 of the draft standard.  A more general 
2383
discussion of what CPP does can be found in the book, The C 
2384
Programming Language, by Brian W. Kernighan and Dennis M. Ritchie, 
2385
published by Prentice-Hall.
2386
 
2387
Basically, CPP copies an input file to an output file doing the following as 
2388
it does so:
2389
 
2390
o It includes files whenever it sees an include directive.  Included files may 
2391
themselves contain include directives, which may be nested to any depth.
2392
 
2393
o It expands macros.  Macros may have arguments and may be call other 
2394
macros.
2395
 
2396
o It conditionally includes lines based on whether symbols have been 
2397
defined or on the value of constant expressions. The directives used for 
2398
this purpose may be nested to any depth.
2399
 
2400
o It eliminates all white space, including comments, thereby reducing the 
2401
size of the output. White space can be included in the output using a 
2402
command line option.
2403
 
2404
Invoke CPP as follows:
2405
 
2406
	CPP input_file  output_file  [options]
2407
 
2408
Options are one of the following:
2409
 
2410
 
2411
-c
2412
 
2413
Include comments and white space in the output file.
2414
 
2415
 
2416
-d	<id>=<string>
2417
 
2418
Define an identifier as if a define directive appeared before the first line of 
2419
the program.  For example:
2420
 
2421
	CPP  in  out  -d  a=xyz
2422
 
2423
The last example defines the macro a to have the replacement text xyz.  The 
2424
equal sign is not part of the replacement text.  If the equal sign and 
2425
replacement text are omitted, a null definition is created.  For example, the 
2426
following is valid:
2427
 
2428
	CPP  in  out  -d  a
2429
 
2430
One or more spaces are required following the -d argument and spaces are 
2431
prohibited around the equal sign.  In other words, the -d and a=5 are two, 
2432
and only two, separate command line arguments.
2433
 
2434
 
2435
-n
2436
 
2437
Allow nested comments. For example, the following is a nested comment 
2438
which is valid only when using the -n option.
2439
 
2440
	/*comment out - - - - -
2441
		a = 5;
2442
		/* This is a nested comment. */
2443
		b = 5;
2444
	- - - - - end comment out */
2445
 
2446
 
2447
 
2448
-s	<path>
2449
 
2450
Add a path to the list of "standard places" which is used when searching 
2451
for included files. 
2452
For example:
2453
 
2454
	CPP  in  out  -s  \src  -s  \etc
2455
 
2456
adds the directories called \src and \etc to the end of the list of standard 
2457
places.  Initially, the list of standard places is obtained by reading the 
2458
INCLUDE environment variable.  For example:
2459
 
2460
	set INCLUDE=c:\include;c:\usr\include
2461
 
2462
causes the list of standard places to contain c:\include and c:\usr\include.
2463
 
2464
 
2465
-u	<id>
2466
 
2467
Cancel the initial definition of a macro.  For example,
2468
 
2469
	CPP in out -u SHERLOCK
2470
 
2471
cancels the effect of the first definition of the macro called SHERLOCK, 
2472
just as if that definition had been immediately followed by
2473
 
2474
	#undef SHERLOCK
2475
 
2476
 
2477
 
2478
APPENDIX A: RUN TIME ERROR MESSAGES
2479
 
2480
 
2481
This appendix lists the error messages that are generated by the support
2482
routines in the file sherlock.c.  You will encounter these messages only
2483
while you are running a program containing Sherlock macros, never
2484
while compiling.  There are two sources of errors that will produce these
2485
messages: faulty Sherlock command line arguments and faulty tracepoint
2486
names in Sherlock macros.  The following abbreviations will be used in
2487
the explanation of these error messages:
2488
 
2489
	<addr> 	The hexadecimal address where the error occurred.
2490
	<char> 	A single character, printed in %c format.
2491
	<name> 	The name of the macro, i.e., TICK, TRACE, etc.
2492
	<on_prefix>  	The on_prefix parameter to the SL_PARSE macro.
2493
	<off_prefix> 	The off_string parameter to the SL_PARSE macro.
2494
	<string> 	The string representing the tracepoint name. 
2495
 
2496
 
2497
sl_check:<name>: null string @ <addr>.
2498
 
2499
The tracepoint name passed to a macro was the NULL string.
2500
 
2501
 
2502
sl_check:<name>: bad character <char> in <string> @ <addr>.
2503
 
2504
The tracepoint name of a macro contains an invalid character.  Only
2505
the following characters are valid in tracepoint names:
2506
 
2507
o The letters a through z and A through Z.
2508
o The numerals 0 through 9.
2509
o The underscore character.
2510
o The wildcard characters * and ? (on the command line only.)
2511
 
2512
 
2513
sl_check: <name>: run on argument: <string> @ <addr>.
2514
 
2515
The tracepoint name passed to a macro contained more than 25 characters.
2516
 
2517
 
2518
sl_init: Header version does not match run-time version.
2519
 
2520
The version of the macros in the file sl.h or sl1.h does not match the
2521
version of the code in the file sherlock.c.  Change either the version of
2522
the header file that you use to compile your programs or the version of
2523
the support routines that are linked with your program.
2524
 
2525
 
2526
sl_ret:  Entry/Exit mismatch at exit point <string>.
2527
Check for missing or misnamed exit macros.
2528
Dump of call stack:
2529
 
2530
The tracepoint name passed to an exit macro does not match the
2531
tracepoint name on top of the timing stack.  This indicates that name of
2532
the most recently executed entry macro does not match the name of the
2533
current exit macro.  As an aid in finding out where the problem occurred,
2534
the tracepoint names on the call stack are printed out.
2535
 
2536
 
2537
Lone <on_prefix>
2538
 
2539
The on_prefix appeared alone on the command line.  It must be
2540
followed immediately with no intervening spaces by a tracepoint name.
2541
This command line error  immediately terminates the program.
2542
 
2543
 
2544
Lone <off_prefix>
2545
 
2546
The off_prefix appeared alone on the command line.  It must be followed
2547
immediately with no intervening spaces by a tracepoint name. This
2548
command line error  immediately terminates the program.
2549
 
2550
 
2551
Trace table overflow.
2552
 
2553
Too many tracepoint names were encountered during execution of your
2554
program.  Different tracepoints with the same names do not add to this
2555
total.  Neither do tracepoints that are never executed.
2556
 
2557
To increase the maximum allowable number of tracepoint names, increase
2558
the MAX_STAT variable in sherlock.c and recompile sherlock.c.  To
2559
decrease the number of tracepoint names used by your program,  undefine
2560
SHERLOCK in one or more of your source files and recompile those files.
2561
 
2562
The tracing tables used by Sherlock are statically allocated so they do not
2563
interfere with the tracing of routines that do dynamic storage allocation.