For general troubleshooting information please contact us. Also feel free to visit the web site at for tips and usage ideas. Several customers have sent in ideas for using Paul Bunyan and those are often added to the site.

Receiving log messages

Remember that there may be security issues involved that prevent you from receiving log messages Ė be aware of message keys! If you think you should be getting messages and want to simply verify things (locally, at least) you should go to the command line (or use the RunÖ command from the Start menu on the task bar) and run ĎPBLog.exe Helloí since that program will simply log the string ďHelloĒ as an unsecured comment message viewable to everyone. If it doesnít immediately show up in your query then you may want to check the event log for errors. If it does and you still think you should be seeing other log messages as well then it is most likely a security problem and you will need to add message keys with the Message Keys dialog.

Note that connections and queries both have filters that can also prevent the download and/or display of messages. However, if a new workspace was created and nothing was touched then both filters (in the default query and the local connection object) will be empty and have no filtration effects.

In general there are only two factors that affect messages: the connection and the security. If the connection shows up as good (if itís checked on the Connect menu) and itís actually pointing to the message server you want, then connectivity is not an issue Ė the initialization handshaking that is required to be completed before the connection is deemed good so if itís flagged OK there is communication to the message server. It is conceivable that the connection can be lost without the software uphill of it being notified but this is exceptionally rare and can be quickly tested by bouncing the connection. Security is the other half. If youíre only connecting to your own machine then this can be tested by running PBLog.exe as described above since it will log an unsecured message. Beyond that, there is some filtering in the connection or query knocking messages out or itís something more involved and you should call us.

Daylight savings time issues

The Win32 implementation of time zone corrections is based on the time zone that is currently set in control panel rather than the time zone that the machine would be in on the date of the timestamp being corrected. That means if itís summer and daylight savings time is in effect, all timestamps are corrected for daylight savings time (DST), even if they specify a winter date. Conversely, in winter no timestamps are corrected for DST. To realize the full implications of this (assuming your computer is set to adjust for DST), set your computerís date to July 1 and open the application event log. Note the date and time specified for a given message, close the event log, and set the date to December 1. When you re-open the event log, the time stamp for the message will have changed! This is also true for file dates displayed in Explorer.

Paul Bunyan uses Win32 API functions to manipulate timestamps, and thus exhibits the same behavior. This can have adverse effects on filtering. As an example, consider a selector configured to evaluate a bracketed time span of 9/1/98 Ė 9/30/98, 9am Ė 5pm using the local time zone. This will correctly match only messages generated during business hours in September. The problem occurs when trying to duplicate this functionality in October, when DST ends. Which messages match the selector depends on when the selector is evaluated. While DST is still in effect, there should be no problem (unless messages are being viewed which ďwereĒ generated in the future). Once DST ends, however, messages generated at 9am on a date before DST ended will have their local timestamps appear as 8am, since they are now adjusted as if DST is not in effect.

Note that this problem may not be as esoteric as the above example suggests. Monday you are looking for the results of the test that was run Friday at 9:30 am and canít find them because the timestamps now appear as 10:30 because DST was in effect over the weekend. The resolution to this problem is to use Greenwich Mean Time in selectors that may cross time zone or DST boundaries. We feel itís more appropriate to function the same way as the operating system rather than implement our own correction algorithm.

Leaking handles

When designing the API and considering shutdown and cleanup issues it was determined that explicit cleanup of resources was not necessary in most scenarios and as such we took steps to implement implicit cleanup. (For instance, we allocate no memory in the C/C++ API since there is no notification mechanism to indicate when to free it.) One of the ramifications of this is that the API will appear to leak kernel object handles under various conditions. This will potentially show up when running under debuggers or IDEs but is nothing to worry about as cleanup of these handles is an implicit part of the operating systemís procedure of shutting down processes whether they surrender their resources peaceably or die in violent rebellion. The only exception is when a logging module is unloaded from a process but the process does not terminate. This occurs if the static library is linked into a DLL that is explicitly loaded and unloaded using the Win32 API functions LoadLibrary and FreeLibrary, e.g. an in-proc COM server. The function PBUninitialize is provided to perform explicit cleanup when necessary.

First consider the normal case where the logging module is unloaded only at process termination (i.e. the static library is linked into an executable module or an implicitly linked DLL). The API always uses a fixed number of handles to manage IPC and sharing of resources. These handles are never explicitly closed so that a process can continue to use the API until the last possible moment. When a Win32 process ends, the thread that called ExitProcess (usually the main thread when it returns from the entry point function) executes any exit list functions (functions specified to the run-time function atexit and destructors of global C++ objects) and then the operating system takes over. The OS terminates any threads that the process has left running (these threads can successfully use API functions right up until the time they are terminated) and then cleans up any handles allocated on behalf of the process. Any code built into the process to detect whether handles are being leaked will be executed before the cleanup occurs and will report leaks, but since the fixed number of handles are allocated only once, there is no chance of a cumulative resource leak. (It is interesting though not particularly relevant to note that in implicitly linked DLLís DllMain is called with the DLL_PROCESS_DETACH notification and exit list functions are executed after any straggling threads in the process have been terminated. This prevents threads in a process from attempting to execute code in a DLL after the DLL has been unloaded.)

Handles are also used for thread default components and contexts. When component or context defaults are set for a thread, the API, whether using the C functions or the C++ classes, duplicates and stores the handle of the calling thread for internal uses. This handle is closed when the default is unset. (In the C API this is done by calling the PBSetDefaultComponent and PBSetDefaultContext functions with pcp or pcx parameters equal to NULL. In the C++ API the destructors call these same functions as necessary. Handles to any threads that have terminated will also be closed whenever one of these functions is called with the iOption parameter equal to PB_THREAD_DEFAULT.) This seems to open the door to a cumulative resource leak, but there are several mitigating factors. First note that there is an arbitrary maximum number of concurrent thread defaults, so a logging module can never leak more thread handles than this. Additionally if a thread always unsets any defaults it uses, the handles will be cleaned up at that time. Finally, since calling PBSetDefaultComponent or PBSetDefaultContext will close handles to any threads that are terminated, calling one of these functions with a pcp or pcx parameter of NULL on the last thread to terminate will clean up all the thread handles. Any defaults that are not explicitly unset by the API user will appear as resource leaks, but again they will always be cleaned up by the OS when the process terminates and there is a small, fixed number that can accumulate over the lifetime of a process.

All that is fine for executables and implicitly linked DLLís, but it just wonít do when the static library is linked into a module that is loaded on demand. Kernel object handles are allocated on behalf of processes, and when a module is unloaded from a processís address space, the OS does not clean up any handles allocated by code in the unloading module until the process terminates. If the same module is loaded and unloaded repeatedly by a process, and the module uses Paul Bunyan API functions, a cumulative resource leak will occur over the lifetime of the process. In this case it is necessary to call the function PBUninitialize when the logging module is unloaded to perform explicit cleanup. The only penalty for using this function is that API functions will no longer be available to the module after it is called. If you need to use this function, consult its documentation for usage notes.