2.5. Configuration

2.5.1. Registry configuration

The Windows' debugging API uses a registry entry to know which debugger to invoke when an unhandled exception occurs (see On exceptions for some details). Two values in key

"MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"
        

Determine the behavior:

Debugger:

this is the command line used to launch the debugger (it uses two printf formats (%ld) to pass context dependent information to the debugger). You should put here a complete path to your debugger (WineDbg can of course be used, but any other Windows' debugging API aware debugger will do). The path to the debugger you chose to use must be reachable via a DOS drive in the Wine config file !

Auto:

if this value is zero, a message box will ask the user if he/she wishes to launch the debugger when an unhandled exception occurs. Otherwise, the debugger is automatically started.

A regular Wine registry looks like:

[MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug] 957636538
"Auto"=dword:00000001
"Debugger"="winedbg --debugmsg -all %ld %ld"
        

Note 1: creating this key is mandatory. Not doing so will not fire the debugger when an exception occurs.

Note 2: wineinstall (available in Wine source) sets up this correctly. However, due to some limitation of the registry installed, if a previous Wine installation exists, it's safer to remove the whole

[MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug]
          

key before running again wineinstall to regenerate this key.

2.5.2. WineDbg configuration

WineDbg can be configured through a number of options. Those options are stored in the registry, on a per user basis. The key is (in my registry)

[eric\\Software\\Wine\\WineDbg]
        

Those options can be read/written while inside WineDbg, as part of the debugger expressions. To refer to one of these options, its name must be prefixed by a $ sign. For example,

set $BreakAllThreadsStartup = 1
        

sets the option BreakAllThreadsStartup to TRUE.

All the options are read from the registry when WineDbg starts (if no corresponding value is found, a default value is used), and are written back to the registry when WineDbg exits (hence, all modifications to those options are automatically saved when WineDbg terminates).

Here's the list of all options:

2.5.2.1. Controlling when the debugger is entered

BreakAllThreadsStartup

Set to TRUE if at all threads start-up the debugger stops set to FALSE if only at the first thread startup of a given process the debugger stops. FALSE by default.

BreakOnCritSectTimeOut

Set to TRUE if the debugger stops when a critical section times out (5 minutes); TRUE by default.

BreakOnAttach

Set to TRUE if when WineDbg attaches to an existing process after an unhandled exception, WineDbg shall be entered on the first attach event. Since the attach event is meaningless in the context of an exception event (the next event which is the exception event is of course relevant), that option is likely to be FALSE.

BreakOnFirstChance

An exception can generate two debug events. The first one is passed to the debugger (known as a first chance) just after the exception. The debugger can then decides either to resume execution (see WineDbg's cont command) or pass the exception up to the exception handler chain in the program (if it exists) (WineDbg implements this through the pass command). If none of the exception handlers takes care of the exception, the exception event is sent again to the debugger (known as last chance exception). You cannot pass on a last exception. When the BreakOnFirstChance exception is TRUE, then winedbg is entered for both first and last chance execptions (to FALSE, it's only entered for last chance exceptions).

BreakOnDllLoad

Set to TRUE if the debugger stops when a DLL is loaded into memory; when the debugger is invoked after a crash, the DLLs already mapped in memory will not trigger this break. FALSE by default.

2.5.2.2. Output handling

ConChannelMask

Mask of active debugger output channels on console

StdChannelMask

Mask of active debugger output channels on stderr

UseXTerm

Set to TRUE if the debugger uses its own xterm window for console input/output. Set to FALSE if the debugger uses the current Unix console for input/output

Those last 3 variables are jointly used in two generic ways:

  1. default

    ConChannelMask = DBG_CHN_MESG (1)
    StdChannelMask = 0
    UseXTerm = 1
                  

    In this case, all input/output goes into a specific xterm window (but all debug messages TRACE, WARN... still goes to tty where wine is run from).

  2. to have all input/output go into the tty where Wine was started from (to be used in a X11-free environment)

    ConChannelMask = 0
    StdChannelMask = DBG_CHN_MESG (1)
    UseXTerm = 1
                  

Those variables also allow, for example for debugging purposes, to use:

ConChannelMask = 0xfff
StdChannelMask = 0xfff
UseXTerm = 1
          

This allows to redirect all WineDbg output to both tty Wine was started from, and xterm debugging window. If Wine (or WineDbg) was started with a redirection of stdout and/or stderr to a file (with for example >& shell redirect command), you'll get in that file both outputs. It may be interesting to look in the relay trace for specific values which the process segv'ed on.

2.5.2.3. Context information

ThreadId

ID of the W-thread currently examined by the debugger

ProcessId

ID of the W-thread currently examined by the debugger

<registers>

All CPU registers are also available

The ThreadId and ProcessId variables can be handy to set conditional breakpoints on a given thread or process.