WineHQ

Winedbg has several useful abilities, including the ability to generate backtraces, set breakpoints, and even disassemble code. It supports a subset of the gdb commands, especially the most common ones. For instance you can use info proc and info thread and then attach to a given process, which can be very useful for running backtraces on deadlocks.

Backtraces

While Windows binaries are usually stripped, making backtraces less effective, they can still contain debugging info for built-in Wine modules and can prove handy especially when using native DLLs. Getting a backtrace in Wine should be automatic when an app crashes, but sometimes, for various reasons, that doesn't happen.

You can trigger one manually by starting winedbg in a separate process and attaching it to the hexadecimal thread ID of your program:

(in 1st terminal)

wine foo.exe

(from now on in a separate terminal)

winedbg
info process
attach 0x<wpid of your process>

If the application has already failed, you can get the backtrace now. Otherwise, type in the winedbg prompt:

set $BreakOnFirstChance=0
cont

This ensures that winedbg will only break for unhandled exceptions, not for all of them (most are harmless). Now just wait for the program to crash and generate a backtrace.

If you just want to get a backtrace of all processes, including the failed program, without figuring out how to attach to it:

(in 1st terminal)

wine foo.exe

(from now on in a separate terminal)

winedbg
bt all


If for some reason, you cannot attach to your running process, invoke your program like so:

wine winedbg foo.exe
set $BreakOnFirstChance=0
cont

Then just wait for your program to crash.

If you have a background service crashing, the backtrace will only be available via the crash dialog. As a hack, you can print all backtraces to stdout, e.g.,:

diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index 11782fe..46ee4ce 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -115,7 +115,7 @@ static void dbg_outputA(const char* buffer, int len)
             if (len > 0) i = line_pos;  /* buffer is full, flush anyway */
             else break;
         }
-        WriteFile(dbg_houtput, line_buff, i, &w, NULL);
+        wine_dbg_printf("%.*s", i, line_buff);
         memmove( line_buff, line_buff + i, line_pos - i );
         line_pos -= i;
     }

Backtrace Quality

A good backtrace contains function names and the values of the parameters as well as line numbers like this:

    Backtrace:
    =>0 0x7ea5e750 CreateWindowExW(exStyle=0, className=0x7ed94f50, windowName=0x7ed94f40, style=13565952, x=0, y=0, width=570, height=427, parent=(nil), menu=(nil), instance=0x7ed80000, data=(nil)) [/home/foobar/git/wine/dlls/user32/win.c:1555] in user32 (0x0033fe08)
      1 0x7ed94c55 main+0xa5() [/home/foobar/git/wine/dlls/winecrt0/exe_main.c:48] in notepad (0x0033fe88)
      2 0x7ed94b77 __wine_spec_exe_entry+0x57(peb=0x7ffdf000) [/home/foobar/git/wine/dlls/winecrt0/exe_entry.c:36] in notepad (0x0033feb8)
      3 0x7b875ac5 start_process+0x55(peb=<register ESI not in topmost frame>) [/home/foobar/git/wine/dlls/kernel32/process.c:990] in kernel32 (0x0033fee8)
      4 0x7bc6c814 call_thread_func+0xc() in ntdll (0x0033fef8)
      5 0x7bc6e811 in ntdll (+0x5e811) (0x0033ffc8)
      6 0x7bc4945a in ntdll (+0x3945a) (0x0033ffe8)
      7 0xf7e6fc7d wine_call_on_stack+0x1d() in libwine.so.1 (0x00000000)
      3 0x7b875ac5 start_process+0x55(peb=<register ESI not in topmost frame>) [/home/foobar/git/wine/dlls/kernel32/process.c:990] in kernel32 (0x0033fee8)
      4 0x7bc6c814 call_thread_func+0xc() in ntdll (0x0033fef8)
      5 0x7bc6e811 in ntdll (+0x5e811) (0x0033ffc8)
      6 0x7bc4945a in ntdll (+0x3945a) (0x0033ffe8)
      7 0xf7e6fc7d wine_call_on_stack+0x1d() in libwine.so.1 (0x00000000)

If your backtrace is missing information like the source file name and line number then you may need to compile from source. First, check if your package manager has a 'wine-dev' or 'wine-dbg' package available, which may contain the debugging information. If not, or if it still doesn't show a proper backtrace after installing, build wine from source.

If you still aren't getting source annotations, check your CFLAGS. CFLAGS="-g" should enable them. On Fedora/RedHat, CFLAGS="-g -gdwarf-2" may be required. You can also often get better backtraces by compiling without optimization (e.g. with -O0 for gcc or /Od for visual c++).

See Also

This page was last edited on 20 September 2016, at 01:31.