Using Assert for Trace statements (was: [lazarus] Lazarus Pascal code)

Michael A. Hess mhess at
Wed May 3 01:34:13 EDT 2000

dvortex wrote:
> I am not.. please send me a "example".
> i remember some time ago (when i was lurking around) about some
> discussion of {$IFDEF DEBUG} thingies.. but missed the end of it...

Not related to #IFDEF DEBUG at all.


This uses the ASSERTIONS feature found in FPC.

At the top of most of the units you should find the following code:

{$ifdef Trace}

If you declare "Trace" either before this in the unit file or globally
in the 'make' this turns on 'ASSERTIONS'.

In place of the writeln statement in the code us the following:

Assert(False, 'Trace:[whatever you want]');

This is a standard Assert call.

The 'False" tells the Assertion handler that the AssertionProc procedure
should be called and passed the next parameter as a message.

The utrace.pp unit has replaced the standard AssertionProc with one that
will handle the 'Trace:' key in the message. If the AssertionProc sees
the leading work 'Trace:' in the message it assumes it is just being
used to do code tracing and does not fire a normal Assertions. If this
key word is not found it deals with the Assertion as it normally would
by calling the original AssertionProc. You can see how this is done in
the utrace.pp unit.

The output from the above line is everything after the 'Trace:' keyword.
This output defaults to the console. However if someplace in your code
you set the variable 'TraceFileName' to some value say 'trace.log' for
example it will then output all of the trace statements to that file.

Here is an example of an Assert line as it is found in the file.

   Assert(False, Format('Trace:[TCustomForm.LMPaint] %s, [ClassName]));

You can see that in this example it uses the Format function to create a
dynamic output. As long as the first 6 characters of the string being
passed to the Assert procedure equals 'Trace:' it will work correctly.

The beauty of this is that you can turn on tracing for the whole of the
LCL or only for the unit you are working on. If you define the word
'Trace' in your 'make' call then all of the LCL units will use and
report their Assert calls. If however you are working on a specific unit
and only need info from it you only need place the '$define Trace'
statement at the top of the file to make sure Assertions are turned on
for that unit and that unit only. If the compiler directive 'Trace' is
never set then the ASSERTIONS are never turned on which means that the
application will not output to the console. It also means that the Trace
code is not even INCLUDED in the BINARY. The Trace statements in the
form of Assert calls can stay in the code forever because they are only
included in the compiled binary if and only if $ASSERTIONS ON is set. As
it stands now we need to either remove or attempt to comment out the

The advantage to this is that in the future if someone reports a problem
it is a simple matter of having them turn on ASSERTIONS by recompiling
with the $define Trace statement and giving us a dump of what is going


I will take the above piece of information and add it to the web site
where appropriate.

==== Programming my first best destiny! ====

Michael A. Hess      Miracle Concepts, Inc.
mhess at

More information about the Lazarus mailing list