WineDbg can act as a remote monitor for GDB. This allows to
use all the power of GDB, but while debugging wine and/or
any Win32 application. To enable this mode, just add
--gdb
to winedbg command line. You'll
end up on a GDB prompt. You'll have to use the GDB commands
(not WineDbg's).
However, some limitation in GDB while debugging wine (see below) don't appear in this mode:
GDB will correctly present Win32 thread information and breakpoint behavior
Moreover, it also provides support for the Dwarf II debug format (which became the default format (instead of stabs) in gcc 3.1).
A few Wine extensions available through the monitor command.
This section will describe how you can debug Wine using the GDB mode of winedbg and some graphical front ends to GDB for those of you who really like graphical debuggers.
Use the following steps, in this order:
Start the Wine debugger with a command line like:
winedbg --gdb --no-start <name_of_exe_to_debug.exe>
Start ddd
In ddd, use the 'Open File' or 'Open Program' to point to the Wine executable (which is either wine-pthread or wine-kthread depending on your settings).
In the output of 1/, there's a line like
target remote localhost:32878copy that line and paste into ddd command pane (the one with the (gdb) prompt)
Use the following steps, in this order:
Start the Wine debugger with a command line like:
winedbg --gdb --no-start <name_of_exe_to_debug.exe>
In the output of 1/, there's a line like
target remote localhost:32878Start kdbg with
kdbg -r localhost:32878 winelocalhost:32878 is not a fixed value, but has been printed in step 1/. 'wine' should also be the full path to the Wine executable (which is either wine-pthread or wine-kthread depending on your settings).
You can also use other debuggers (like gdb), but you must be aware of a few items:
You need to attach the unix debugger to the correct unix
process (representing the correct windows thread) (you can
"guess" it from a ps fax for example:
When running the emulator, usually the first two
upids
are for the Windows' application
running the desktop, the first thread of the application is
generally the third upid
; when running a
Winelib program, the first thread of the application is
generally the first upid
)
Note: Even if latest gdb implements the notion of threads, it won't work with Wine because the thread abstraction used for implementing Windows' thread is not 100% mapped onto the Linux POSIX threads implementation. It means that you'll have to spawn a different gdb session for each Windows' thread you wish to debug.
Here's how to get info about the current execution status of a certain Wine process:
Change into your Wine source dir and enter:
$ gdb wine
Switch to another console and enter ps ax | grep wine to find all wine processes. Inside gdb, repeat for all Wine processes:
(gdb) attach PID
with PID being the process ID of one of the Wine processes. Use
(gdb) bt
to get the backtrace of the current Wine process, i.e. the function call history. That way you can find out what the current process is doing right now. And then you can use several times:
(gdb) n
or maybe even
(gdb) b SomeFunction
and
(gdb) c
to set a breakpoint at a certain function and continue up to that function. Finally you can enter
(gdb) detach
to detach from the Wine process.
You can use any Windows' debugging API compliant debugger with Wine. Some reports have been made of success with VisualStudio debugger (in remote mode, only the hub runs in Wine). GoVest fully runs in Wine.
Table 1-13. Debuggers comparison
WineDbg | gdb |
WineDbg debugs a Windows' process: the various threads will be handled by the same WineDbg session, and a breakpoint will be triggered for any thread of the W-process | gdb debugs a Windows' thread: a separate gdb session is needed for each thread of a Windows' process and a breakpoint will be triggered only for the w-thread debugged |
WineDbg supports debug information from stabs (standard Unix format) and Microsoft's C, CodeView, .DBG | GDB supports debug information from stabs (standard Unix format) and Dwarf II. |