PostGIS debugging information 
=============================

Written by Mark Cave-Ayland
2008-05-31


Description
===========

This document attempts to describe the PostGIS debugging system for new developers to
the project. Previously, all debugging was either performed by uncommenting various
elog()/lwnotice() statements within the code areas of interest, or using an
existing #define to enable debugging within each individual file.

The net result of this was that debugging could be quite a painful process, involving
searching through each file as necessary and uncommenting the various options. There
were also issues regarding levels of verbosity; some sections of code define multiple
verbosity levels across many different files, and so getting the information required
could be quite frustrating.

To this end, a new debugging infrastructure has been added to PostGIS to help make
life easier for developers. It is now possible to include debugging information using
a set of new macros for the purpose. Each macro also allows a debug level to be  
specified, allowing output to be generated at the required verbosity level for the
task in hand.

Debugging is accomplished using four new macros:

	LWDEBUG(level, "message")
		- If the current debug level >= level, emit message

	LWDEBUGF(level, "format message", ...)
		- If the current debug level >= level, emit formatted message
		(this allows placeholders and extra arguments in exactly the
		same way as vasprintf())

	POSTGIS_DEBUG(level, "message")
		- If the current debug level >= level, emit message

	POSTGIS_DEBUGF(level, "format message", ...)
		- If the current debug level >= level, emit formatted message
		(this allows placeholders and extra arguments in exactly the
		same way as vasprintf())

The two LWDEBUG macros are designed for use within liblwgeom; i.e. geometry routines
that may not necessarily be used from PostgreSQL, and make use of the lwnotice() call.
Similarly, the POSTGIS_DEBUG macros are designed for code that can *only* be called
from within PostgreSQL, i.e. it calls ereport() directly. The trick is, of course,
to distinguish between the two. Generally anything within a function declared as
returning type Datum should use the POSTGIS_DEBUG macros, as well as code that can
only be called from these functions. Similarly, any functions that do not take
PostgreSQL-specific datatypes should use the LWDEBUG functions.

Note that the debugging macros automatically prefix the current filename, function name
and line number to any debugging messages. As well as allowing debug messages to be
shorter, it also makes following program flow much easier.

 
Usage
=====

The current debug level is set by the POSTGIS_DEBUG_LEVEL #define in postgis_config.h. 
By default, configure sets POSTGIS_DEBUG_LEVEL to 0 which disables all debugging output.
If debugging output is required, it is necessary to either redefine POSTGIS_DEBUG_LEVEL
to the required level (and rebuild the shared library), or re-run configure with the
--enable-debug option and then rebuild the shared library (currently configure defaults
to level 4).

A rebuild of the library is required since the output of the debug macros is conditional;
if POSTGIS_DEBUG_LEVEL is set to 0 then instead of providing debug output, the macros
simply evaluate to (void)0 which can be optimised away by the compiler. Hence adding
debugging statements during development will have negligible performance impact during
execution when debugging is disabled.


Verbosity levels
================

The following verbosity levels have been defined in the initial implementation; obviously
these may need to change as experience dictates. By specifying a debug level, output for
all levels up to and including the current debug level is generated. It should also be
obvious that as the debug level is increased, more complex output is generated.

0 - All debugging output is disable
1 - Reserved
2 - Function entry; for simply announcing when a function has been entered
3 - Normal function debug; output any information of interest to the developer
4 - Verbose function debug; output lots of useful detail
5 - Memory allocation; output all uses of alloc/free within the code

