1.5. Configuration

1.5.1. Windows Debugging 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:


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 choose to use must be reachable via one of the DOS drives configured under /dosdevices in your WINEPREFIX or ~/.wine folder.


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
"Debugger"="winedbg %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.

1.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)


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:


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.


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


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.


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 decide 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 exceptions (to FALSE, it's only entered for last chance exceptions).


Set to TRUE if the debugger, when looking up for a symbol from its name, displays all the thunks with that name. The default value (FALSE) allows not to have to choose between a symbol and all the import thunks from all the DLLs using that symbols.

1.5.3. Configuring +relay behaviour

When setting WINEDEBUG to +relay and debugging, you might get a lot of output. You can limit the output by configuring the value RelayExclude in the registry, located under the key [HKCU\\Software\\Wine\\Debug]

Set the value of RelayExclude to a semicolon-separated list of calls to exclude, e.g. "RtlEnterCriticalSection;RtlLeaveCriticalSection;kernel32.97;kernel32.98".

RelayInclude is an option similar to RelayExclude, except that functions listed here will be the only ones included in the output.

If your application runs too slow with +relay to get meaningful output and you're stuck with multi-GB relay log files, but you're not sure what to exclude, here's a trick to get you started. First, run your application for a minute or so, piping its output to a file on disk:

WINEDEBUG=+relay wine appname.exe &>relay.log
Then run this command to see which calls are performed the most:
awk -F'(' '{print $1}' < relay.log | awk '{print $2}' | sort | uniq -c | sort
Exclude the bottom-most calls with RelayExclude after making sure that they are irrelevant, then run your application again.