On compile command line: B src.b l=b/trace ... In source (optionally): old unit = .trace( unit );
Whenever a call is made to a function within the user's program, a line is directed to the output unit, containing the name of the called function and a list of its arguments. When the call returns, a line with the value returned is output. No tracing is done of calls to library functions (this includes any libraries loaded below TRACE, i.e., the B library and any "Library=" options that follow "l=b/trace").
Tracing may be disabled or re-enabled, or the trace output directed to another unit, by a call to .TRACE. The argument is the unit number and defaults to 1 (standard output); an argument of 0 disables tracing. The value returned by .TRACE is the argument of the previous call to it. There is a null defined function .TRACE in the normal B library so that a program that calls .TRACE may be loaded without the trace library and function as if tracing was disabled.
Consider a recursive function for factorials defined thus:
Factorial (x) return (x?x*Factorial(x-1):1);
The line t = Factorial (4); in Main would produce this:
:CALL: factor(4) ::::CALL: factor(3) :::::::CALL: factor(2) ::::::::::CALL: factor(1) :::::::::::::CALL: factor(0) :::::::::::::RETN: 1 ::::::::::RETN: 1 :::::::RETN: 2 ::::RETN: 6 :RETN: 24=030
The meaning of the above should be obvious. Values other than 0 through 7 are printed in decimal and octal; they are also printed as character constants if possible, like this: if each 9-bit character of the value is either 0 or 012 or from 040 to 177, and the value is nonzero, it is printed as a character constant. Null (omitted when leading), newline, "'", "*", and rubout are respectively escaped as *0, *n, *', **, and *x.
The tracing mechanism is implemented by redefining the function entry/exit routines, .10000 and .10001. This makes programs significantly more expensive to run, even with tracing disabled.
Copyright © 1996, Thinkage Ltd.