INTRODUCTION ============ This file explains how to enable tracing in Harbour. TRACING ======= Harbour implements tracing by adding calls to the following macro in the C code: HB_TRACE( level, ( "printf-style parameters", arg1, arg2 ) ); The level specified for the HB_TRACE call affects Harbour in two ways: compilation time and run time. COMPILATION TIME ================ At compilation time, the macro checks whether the preprocessor constant HB_TR_LEVEL is set to any of the following values: #define HB_TR_ALWAYS 0 #define HB_TR_FATAL 1 #define HB_TR_ERROR 2 #define HB_TR_WARNING 3 #define HB_TR_INFO 4 #define HB_TR_DEBUG 5 #define HB_TR_LEVEL_ALWAYS 0 #define HB_TR_LEVEL_FATAL 1 #define HB_TR_LEVEL_ERROR 2 #define HB_TR_LEVEL_WARNING 3 #define HB_TR_LEVEL_INFO 4 #define HB_TR_LEVEL_DEBUG 5 If it is not set to any of these, the macro is set to the value of HB_TR_DEFAULT, which is currently set (in hbtrace.h) to HB_TR_WARNING. Whether the user explicitly sets HB_TR_LEVEL or it is set by the compiler, its effect is as follows: any calls in the code with a level higher than HB_TR_LEVEL are obliterated from the code; these calls simply disappear, and there is no effect in the code performance thereafter. RUN TIME ======== At run time, the user can set the environment variable HB_TR_LEVEL to one of HB_TR_ALWAYS HB_TR_FATAL HB_TR_ERROR HB_TR_WARNING HB_TR_INFO HB_TR_DEBUG with the following effect: any calls to HB_TRACE that were left by the compiler and which have a level lower or equal to HB_TR_LEVEL will print its arguments on STDERR. EXAMPLES ======== HB_TR_LEVEL HB_TR_LEVEL Description compilation run-time ----------- ----------- ---------------------------------------- HB_TR_INFO HB_TR_ERROR All calls with levels HB_DEBUG are or erased from the code, so they have no HB_TR_LEVEL_INFO performance effect; only calls with levels HB_TR_ERROR, HB_TR_FATAL and HB_TR_ALWAYS are printed. HB_TR_WARNING HB_TR_INFO All calls with levels HB_INFO and or HB_DEBUG are erased from the code, so HB_TR_LEVEL_WARNING they have no performance effect; only calls with levels HB_TR_WARNING, HB_TR_ERROR, HB_TR_FATAL and HB_TR_ALWAYS are printed. Notice how setting HB_TR_INFO at run-time has no effect, since the code was compiled with a lower tracing level. For example, I compile Harbour on Windows with gcc (mingw), so I usually set the HB_USER_CFLAGS environment variable like this: export HB_USER_CFLAGS='-DHB_TR_LEVEL=HB_TR_INFO' or for other OS (e.g.: MS-DOS, Windows) SET HB_USER_CFLAGS=-DHB_TR_LEVEL_INFO and make sure I have all the tracing for the INFO, WARNING, ERROR, FATAL and ALWAYS levels. If I get too much information, at run-time I can set an environment variable like this: export HB_TR_LEVEL=HB_TR_WARNING or for other OS (e.g.: MS-DOS, Windows) SET HB_TR_LEVEL=HB_TR_WARNING and get rid of all the tracing for the INFO level. In this case, all the calls to the tracing function for the INFO level will be done anyway, so there will be a performance hit. USAGE ===== When Harbour is compiled/run with some level of tracing and then used to compile a regular Harbour application, the app will output LOTS of tracing information to STDERR. If you are using a sensible command shell (such as bash) you can redirect STDERR to a file like this: my_app 2> trace.txt REDIRECTION =========== The output generated while tracing goes to STDERR by default. You can control this at run-time by setting the environment variable HB_TR_OUTPUT to the name of a file where you would like the tracing output to be directed. If there is any problem opening the file for writing, the output reverts to STDERR. When it happens an error and the controller of errors of Harbour cannot intercept it (e.g.: GPF), it can happen that part of information of tracing it is not written. This problem is avoided setting the environment variable HB_TR_FLUSH to 1 (one). This makes that every time that one record is sent to write, don't remain in the buffer, but rather it is written in the file before continuing with the execution. This set can produce an important reduction of speed of execution. TRACING THE PREPROCESSOR AND COMPILER ===================================== Usually, you will not want tracing enabled in the preprocessor and compiler; otherwise, you will see the trace output while compiling Harbour itself. If you REALLY want to enable tracing in the preprocessor and/or compiler, you must define, in addition to HB_TR_LEVEL as described above, the following variable, and then recompile the preprocessor/compiler: HB_TRACE_UTILS The value is of no importance. TRACING AND RUNTIME =================== It is also possible to enable and disable tracing at run-time, and to query and set the trace level. From C code: * To query the current tracing state, and optionally change the current state to a given value (which should be in the range [0,1], otherwise the current state remains unchanged): hb_tracestate( state ); Therefore, to just query the current state, you can safely call current_state = hb_tracestate( -1 ); To turn tracing completely off: hb_tracestate( 0 ); To turn tracing back on: hb_tracestate( 1 ); * To query the current tracing level, and optionally change the current level to a given value (which should be in the range [0,5], otherwise the current level remains unchanged): hb_tracelevel( level ); Therefore, to just query the current level, you can safely call current_level = hb_tracelevel( -1 ); There are wrapper functions callable from Clipper code: current_state := hb_traceState( [] ) current_level := hb_traceLevel( [] )