Improving debugging (gdb) support

Michael Wetherell mike.wetherell at
Tue Jun 4 10:16:14 CDT 2002

On Saturday 01 Jun 2002 5:56 pm, Michael Cardenas wrote:
> This was discussed at wineconf, well, getting gdb to work with wine was
> discussed at wineconf because of the huge value in having a graphical
> front end for debugging.
> Ont major problem is that gdb doesn't understand wine's handling of
> windows threads, even if it does understand the windows pe format.
> Ulrich Weigand gave a great presentation where he talked about how the
> debugger is currently implemented, and things that would need to be done
> to have more support from gdb.
> Ulrich, you want to post your presentation here?

Well, I was trying to point out what people can do with gdb and wine as they 
are now really, and I think you can do some pretty useful things with it even 
on multithreaded programs. I wan't trying to suggest further work wouldn't be 
a good idea, and of course I hadn't heard about Eric Pouech's work on a 
winedbg stub for gdb when I wrote that either.

Like you say regular Unix gdb doesn't have any support for wine's threads, 
but as the gdb docs day 'there is a workaround which isn't too painful'. 
Another thing you don't get (aside from support for .PDBs, .DBGs, 16-bit code 
and JIT) is automatic loading of symbols.

For the symbols, you can create a gdb command file:
  $ cat syms
  set gnutarget pei-i386
  add-symbol-file HelloWin.exe
  add-symbol-file HelloDll.dll

And you can do one too for starting up your program and breaking at WinMain:
  $ cat strt
  tbreak main
  r HelloWin.exe
  tbreak start_process
  source syms
  tbreak WinMain

Then you can debug your program like this:
  $ gdb -x strt wine
same for ddd:
  $ ddd -x strt wine

To single step though the code of another thread, you could use the technique 
outlined the gdb manual for fork, or probably easier is to get the thread to 
invoke the debugger on itself by adding a line like this at the place you 
want to break:

  WinExec("y:\\bin\\debugme", SW_NORMAL);

and create a script to lunch gdb (or ddd, etc):
  $ cat ~/bin/debugme
  echo Debugging wine process $PPID
  gdb -x syms wine $PPID

In the debugger get a backtrace and you'll see WinExec maybe 6 frames up the 
stack, so you'd type 'up 6' then 'finish' and from there you'll be stepping 
though your own code.

On my machine, at least, gdb attaches quickly enough for the thread to still 
be in WinExec, but not if I use a front end like ddd. Anyway if on your setup 
you find it's already moved on then just add a small delay such as 
'Sleep(5000);' after the WinExec (then of course you'll be looking for 
'Sleep' on the backtrace instead of 'WinExec').

More information about the wine-devel mailing list