            DBWIN Debug Message Logger
            --------------------------

The DBWIN utility allows you to see messages produced by the debug system
binaries, even if you don't have a debug terminal or debugger running.

In addition, it allows you to see certain errors even when running on a
retail system.

DBWIN also allows you to control the output of various kinds of messages:
whether they're displayed, whether you break to the debugger, etc.  You can
save your settings in win.ini so that they'll remain in effect the next time
you run Windows.

DBWIN provides a debugging feature that allows you to force allocation
failures, in order to test your code's out-of-memory handling.


            Setting Up
            ----------

DBWIN is designed to be used with the debugging system binaries, though it
can be used with the retail system as well.  So, you'll first need to install
the debugging binaries on your machine.  Because the debug system does run
10-20% slower than the retail system, you may want to switch back and forth
between them.  The best way to do this is to create two subdirectories in
your SYSTEM directory, RETAIL and DEBUG.  Copy the proper USER, GDI and
KRNL286/386 .exe and .sym files into the appropriate directory, then write
two batch files that will copy one set of files to the SYSTEM directory as
appropriate.  Then, you need only exit Windows and run the proper batch file
to set up the DEBUG or RETAIL system.

You may want to disable the default system debug output to AUX, since DBWIN
can be used to control output to COM1 or COM2.  It's a good idea to do this,
since it will improve the performance of your debug system when you have
redirected DBWIN output to NONE, or if DBWIN is not running.

To disable the default system debug output to AUX, just add the following to
the [Debug] section of system.ini:

    OutputTo=NUL

If you disable the default kernel output, and want to send output to COM1 or
COM2, you may need to set the DOS COM port baud rates to match the baud rates
of your debug terminal, using the DOS MODE command.  It's easiest to do this
in your autoexec.bat, e.g., mode 19200,n,8,1.


            Message Logging
            ---------------

You can log messages to the DBWIN window, to a monochrome screen (if you have
one attached), or to the COM1 or COM2 devices.  You can also turn off message
output (which makes the debug system run somewhat faster). By default,
messages are logged to a window.

The Options menu allows you to change the destination of debugging message
output.  These settings will be in effect the next time you run DBWIN.


            System Debug Options
            --------------------

The Options.Settings dialog allows you to control the output of various debug
messages produced by the debug system binaries.  There are three groups of
check boxes: Debug options, Break options, and Trace options.

The Settings dialog only works when you are running the debug system.

Debug options controls what kind of debugging features are enabled in the
system.

Break options controls whether and how a message will cause a break to the
debugger with a stack trace (i.e., FatalExit() call, or RIP).

Trace options controls whether or not certain kinds of informational messages
are produced.

The "App:" field allows you to see only messages related to a particular
application.  Normally, DBWIN will display all debug messages in the system,
but if you enter an application's module name in this entry field, only
messages for that app are displayed.  You must enter the application module
name as found in the app's .def file, which may be different than the file
name of the app.


            Debug Options
            -------------

    Validate Heap

        Check the consistency of global and local heaps before every memory
        management call.  Only affects the global heap if set as the default
        boot-time settings (i.e., saved with File.Save Settings). Only
        affects local heaps if set before heap is created and initialized
        (i.e., before you start the app)

    Check Free Blocks

        Must be used with Validate Heap.

        Ensures that freed local blocks aren't written into by writing 0xFB
        into free blocks, and checking to ensure that they're still filled
        with 0xFB when the heap is validated.  Only works with local heaps.

    Buffer Fill

        Fill buffers passed to APIs with 0xF9.  Ensures that all of supplied
        buffer is writeable.  Helps detect overwrite problems when supplied
        buffer size is not large enough (e.g., GetWindowText).

        NOTE: Some applications will not run with this option turned on,
        because the supplied buffer is actually smaller than specified in
        the count parameter, thus causing overwrite of application data.

    Break with INT 3

        Break to the debugger with an INT 3, rather than a fatal exit.
        Doesn't print a stack back trace.


    Don't trap faults

        Prevent the system from hooking GP and stack overflow faults.
        NOTE: Many faults that result from this would normally be handled
        by the system and restarted -- checking this option will result in
        faults that would not occur otherwise.


            Using DBWIN on a Retail System
            ------------------------------

DBWIN can provide useful debugging messages on a retail system as well. The
setup and alloc break commands are disabled, and you will only see a limited
subset of debugging messages.

You should NEVER release an application without testing it under the full
debug system -- only the debug version of the system will inform you when
resources haven't been freed, for example.  There are many other important
errors and warnings that won't be displayed if DBWIN is run with the retail
system.

            Alloc Break
            -----------

The Alloc break feature is designed to help you ensure that your application
properly deals with out-of-memory conditions that might occur.

The idea is that the system counts each global or local memory allocation
performed.  When the number of allocations reaches the allocation break
count, that allocation and all subsequent allocations will fail.

Because memory allocations made by the system are failed once the break count
is reached, calls such as CreateWindow, CreateBrush, SelectObject, and others
will fail as well.  Only allocations made within the context of the application
you specify are affected by the alloc break.

You can use this feature to cause memory failures in turn for every
allocation your application performs at certain times, such as
initialization, load/save, etc.


            Setting an alloc break
            ----------------------

To set or examine an alloc break, choose the "Alloc Break..." command in the
Options menu.  You enter the module name of the application and the count at
which you want allocations to start failing.

The module name is limited to 8 characters.  In some cases the module name
may be different from the file name: it's the name specified in the
application .DEF file.  You can't specify the module name of a DLL: it must
be an application module name.

If you set the break count to 0, no allocation break will be set, but the
system will count allocations made by the specified application.  You can use
the "show count" button to determine the current count.

You can set an alloc break before the named application is run.  The alloc
count will be set to 0 and allocations will be counted as soon as the
application starts up.  If you run more than one instance of an application,
the alloc break will apply to the last instance run only.

The allocation count is also reset to 0 when you choose "Set" or "Inc & Set".

If you set the break count to 0, no alloc break will be set, but the system
will update the alloc count allocations.  You can use the "show count" button
to see the current count.

The best way to use this feature is to set an alloc break before some
operation (such as running the app, or loading a file, etc), perform the
operation, and ensure that your app deals gracefully with the problem.  Then,
choose "Inc & Set" and repeat the operation, to ensure that the next
allocation failure is handled properly.


            Recommended Settings
            --------------------

Most people find that the extra diagnostics provided by the debugging system
binaries are well worth the small performance degradation that they incur.

Applications should run with no errors OR warnings.  With very few
exceptions, it's possible to code around all the warnings that the system can
generate. When an application generates lots of errors or warnings, messages
that indicate a real bug are often lost in the volume of more mundane warnings.

During normal testing and development you may want to run with "Don't break
on warnings".  Quite frequently with code you've just written, you'll be able
to figure out what the problem is when you see a message without even having
to break into a debugger.  When you need to use the debugger to track
something down, you can turn off "don't break on errors" and turn on "Break
on warnings".  It's also a bit faster and more efficient to set "break with
INT 3": it saves having to wait for the stack backtrace to display.  With
these settings you will stop at all warnings and errors, giving you a chance
to have a look at what the problem is.

Quite a few shipping applications will generate lots of warnings and errors
on a debug system, making them difficult and slow to use sometimes.  You can
avoid this by entering the module name of the application you're debugging,
(so messages won't be generated by other apps), and checking "Don't break on
Errors" so that the system doesn't stop when an error is encountered.

Unfortunately, even though you can suppress the output of messages for other
apps in this way, you can't stop other applications from breaking to the
debugger.

            Troubleshooting
            ---------------

Common problems and their solutions:

1. Output appears on the debugging terminal even though Options.No Output
   is selected.

   This will arise if you are using a debugger such as wdeb386 that uses
   COM1 or COM2 as its debugging output

2. Debugging messages are duplicated twice on the debugging terminal.

   This will occur if you have not redirected the debug kernel's default
   debugging output to NUL.  You need to add [Debug] OutputTo=NUL to your
   system.ini file before starting Windows.

3. My serial mouse doesn't work right when DBWIN runs.

   This problem can arise when DBWIN is set up to output its debug
   information to the same COM port where you have your mouse installed.
   Just change the output to another com port or to a window.

4. No monochrome debug output appears when I'm running CVW or another
   application that uses the monochrome display

   DBWIN tries to detect that another app is using the monochrome display
   memory, and suppresses any output.  You can redirect output elsewhere,
   if you're not seeing the messages in your debugger.
