Bug Hunting

# HACKING

LessTif is a complicated system, but not overwhelming. We've collected some tips on hacking LessTif here for your debugging and hacking pleasure. There are some features that are compiled in by default to make finding problems a little easier. Most can be turned off with configure options. One such feature is editres support. If you don't know what this is I suggest you search the web for editres.

There is a good section in bugs.html describing tracking down bugs in _any_ X based app.

Don't forget about "cvs log"!!!! The comments on previous commits can be very helpful, especially if you're new to the game.

## Useful Environment Variables

### DEBUG_SOURCES

`DEBUG_SOURCES` is an environment variable you can set to get debugging output on a particular collection of source files. `DEBUG_SOURCES=all` will give you more information than you ever wanted about what LessTif is doing internally. You can also set `DEBUG_SOURCES` to a single file, or a list of files separated by colons ':'. The ".c" postfix is optional here. If your shell is sh, bash, or ksh, you can for example set `DEBUG_SOURCES` by

    DEBUG_SOURCES=MainW.c:FileSB.c
    export DEBUG_SOURCES

If your shell is csh or tcsh, you can set `DEBUG_SOURCES` by

    setenv DEBUG_SOURCES "MainW.c:FileSB.c"

If you unset `DEBUG_SOURCES` or set it to "none" then no debugging output will be produced.

To block single files from producing debugging output, you may add a "-" prefix to their entry. Obviously this makes only sense if used in conjunction with the "all" keyword:
`DEBUG_SOURCES=all:-Vendor`
will produce debugging output for all sources, but Vendor.c!

### DEBUG_FILE

The amount of diagnostics generated by `DEBUG_SOURCES` can exceed the line buffering of typical terminal settings. The environmental variable `DEBUG_FILE` can be used to direct the output to a file instead of stdout. An alternate method is to run the tests as follows:

    DEBUG_SOURCES=MainW.c:FileSB.c ./test1 2>&1 | tee debug.log

The advantage of this is that you also get to see the messages on the screen as well as in a file. `DEBUG_SOURCES` is not limited to file names. In reality it can be any string that matches what is in the source for the _LtDebug() call. For example, `DEBUG_SOURCES=FOCUS` will print debug info related to menu focus events, regardless of the file the statement is in. There are some more in there also. Usually relating to specific problems involving many different files. To find out what is available try:

    grep _LtDebug *.c | grep -v __FILE__

### DEBUG_REDIRECT_XMWARNING

To avoid infinite loops in applications that redirect stderr to a scrolledText. you may set `DEBUG_REDIRECT_XMWARNING`. Output of _XmWarning() and equivalent functions (XmeWarning(), etc.) is then sent to the content of `DEBUG_FILE`

### DEBUG_PRINT_WIDGETID

If this variable exists, then all widgets printed with _LtDebug() etc. will also print their widget ID. If the variable doesn't exist, then they only print their name for identification.

### DEBUG_SIGNAL

It specifies the alphanumeric value of the signal which should be used to switch the built-in LessTif debugging system. Valid values depend on the system on which LessTif was compiled and is running on. Currently we support:
`SIGBREAK, SIGUNUSED, SIGUSR1, SIGUSR2, SIGUSR3`

### DEBUG_TOGGLE

This specifies the initial status of the built-in LessTif debugging system. Valid values are 'on' and 'off'

## Useful Interfaces

lib/Xm/DebugUtil.c and include/Motif-1.2/XmI/DebugUtil.h contain the stuff which we use for our own debugging purposes, i.e. routines which actually produce the formatted debugging output and so on. The interactive methods to adjust the debug level also include interfaces which you may call from your application if have the source.

### _LtDebugInit

    #include <XmI/DebugUtil.h>
    extern Boolean _LtDebugInit(void);

Call to initialize the debugging subsystem. Useful if called before any other library calls are done.

### _LtDebugSet

    #include <XmI/DebugUtil.h>
    extern void _LtDebugSet(Boolean flag);

Explicitly turn the debugging on/off according to `flag`.

### _LtDebugToggle

    #include <XmI/DebugUtil.h>
    extern void _LtDebugToggle(void);

Toggles the debugging system on/off.

## Testing patches

LessTif has an extensive test tree under `test/`. Since even the most seemingly trivial change can often have unexpected consequences, we recommend running the `testall` script under `test/` before and after applying a patch, to make sure that you haven't broken anything else with your fix.

In these test programs, there is data that is labeled "expected". Where do these values come from?
I guess I should answer this. They come from Jon :) Okay, sometimes I make them also. The PrintDetails call that you see in the test code will print out the Expected data in a format that can be cut'n pasted into the source, if the second arg is NULL. So, we have Motif generate the Expected data for us. The values are _very_ dependant on the default font in use. As long as you match the font that is used to generate the Expected values the results are usually right on. In a few cases we haven't been able to get an exact match. If we are off by just a pixel or so, the application resource "*geometrySlop" can be set to a value that will accept the error, and report success. In the cases where the slop is not 0, it is also printed out with the results. The most recent test results can also be viewed by pointing your web browser to http://www.lesstif.org/test-results/ (may be old stuff)

In the `test/common` directory there is a library that is linked with each of the test programs. In here you will find a replacement for XtAppMainLoop(). Our version allows the test apps to exit with a status that indicates success or failure. This is where the PrintDetails function referred to above lives. Nothing in this library relies on Motif, so that they function the same whether the test apps are linked with LessTif or Motif.
This is probably also a good time to mention that all of the tests can be compiled and linked with Motif as well as LessTif. By typing

    make motif-tests

in any of the test directories all the tests in that directory will be compiled and linked with Motif, assuming it is available. Therefore test1 will be the test compiled and linked with LessTif, test1.motif will be the same code compiled and linked with Motif. You can also build individual tests with

    make test1.motif

The test library also includes a bunch of functions to simulate button, presses, pointer movement, and other things necessary for automated testing.

The best thing about the tests is that they tell you whether everything it was meant to test worked. For an example, take a look at rowcolumn/test51. Try remembering to do all that everytime you make a change!!!!

Really, the best way to fix a bug, and have it stay fixed, is to write a test and have it included in the test tree. Once a test has passed, a change to the library will not be accepted if it causes a previously passing test to fail. Well, it won't be accepted easily anyway :)

If you're hunting for bugs in mwm (our window manager) you have several options: either you start a normal X11 session on your system, e.g. on DISPLAY :1 if you have already one :0. Since you may not need any fancy setup, starting the X server directly may work and then you run mwm from an arbitrary terminal, probably inside a debugger. Being non-root on un*x systems you have to use `/usr/X11/bin/Xwrapper` to start the server itself.
Sometimes you may not even need to have it running on a "real" X server, then you can use `Xvfb` (X virtual frame buffer).