John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1 | <chapter id="debugger"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 2 | <title>Debugging Wine</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 3 | |
| 4 | <sect1 id="dbg-intro"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 5 | <title>Introduction</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 6 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 7 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 8 | <title>Processes and threads: in underlying OS and in Windows</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 9 | |
| 10 | <para> |
| 11 | Before going into the depths of debugging in Wine, here's |
| 12 | a small overview of process and thread handling in Wine. |
| 13 | It has to be clear that there are two different beasts: |
| 14 | processes/threads from the Unix point of view and |
| 15 | processes/threads from a Windows point of view. |
| 16 | </para> |
| 17 | <para> |
| 18 | Each Windows' thread is implemented as a Unix process (under |
| 19 | Linux using the <function>clone</function> syscall), meaning |
| 20 | that all threads of a same Windows' process share the same |
| 21 | (unix) address space. |
| 22 | </para> |
| 23 | <para> |
| 24 | In the following: |
| 25 | </para> |
| 26 | <itemizedlist> |
| 27 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 28 | <para> |
| 29 | <varname>W-process</varname> means a process in Windows' terminology |
| 30 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 31 | </listitem> |
| 32 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 33 | <para> |
| 34 | <varname>U-process</varname> means a process in Unix' terminology |
| 35 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 36 | </listitem> |
| 37 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 38 | <para> |
| 39 | <varname>W-thread</varname> means a thread in Windows' terminology |
| 40 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 41 | </listitem> |
| 42 | </itemizedlist> |
| 43 | <para> |
| 44 | A <varname>W-process</varname> is made of one or several |
| 45 | <varname>W-threads</varname>. Each |
| 46 | <varname>W-thread</varname> is mapped to one and only one |
| 47 | <varname>U-process</varname>. All |
| 48 | <varname>U-processes</varname> of a same |
| 49 | <varname>W-process</varname> share the same address space. |
| 50 | </para> |
| 51 | <para> |
| 52 | Each Unix process can be identified by two values: |
| 53 | </para> |
| 54 | <itemizedlist> |
| 55 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 56 | <para> |
| 57 | the Unix process id (<varname>upid</varname> in the following) |
| 58 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 59 | </listitem> |
| 60 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 61 | <para> |
| 62 | the Windows's thread id (<varname>tid</varname>) |
| 63 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 64 | </listitem> |
| 65 | </itemizedlist> |
| 66 | <para> |
| 67 | Each Windows' process has also a Windows' process id |
| 68 | (<varname>wpid</varname> in the following). It must be clear |
| 69 | that <varname>upid</varname> and <varname>wpid</varname> are |
| 70 | different and shall not be used instead of the other. |
| 71 | </para> |
| 72 | <para> |
| 73 | <varname>Wpid</varname> and <varname>tid</varname> are |
| 74 | defined (Windows) system wide. They must not be confused |
| 75 | with process or thread handles which, as any handle, is an |
| 76 | indirection to a system object (in this case process or |
| 77 | thread). A same process can have several different handles |
| 78 | on the same kernel object. The handles can be defined as |
| 79 | local (the values is only valid in a process), or system |
| 80 | wide (the same handle can be used by any |
| 81 | <varname>W-process</varname>). |
| 82 | </para> |
| 83 | </sect2> |
| 84 | |
| 85 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 86 | <title>Wine, debugging and WineDbg</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 87 | |
| 88 | <para> |
| 89 | When talking of debugging in Wine, there are at least two |
| 90 | levels to think of: |
| 91 | </para> |
| 92 | <itemizedlist> |
| 93 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 94 | <para> |
| 95 | the Windows' debugging API. |
| 96 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 97 | </listitem> |
| 98 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 99 | <para> |
| 100 | the Wine integrated debugger, dubbed <command>WineDbg</command>. |
| 101 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 102 | </listitem> |
| 103 | </itemizedlist> |
| 104 | <para> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 105 | Wine implements most of the Windows' debugging API (the |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 106 | part in <filename>KERNEL32.DLL</filename>, not the one in |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 107 | <filename>IMAGEHLP.DLL</filename>), and allows any program |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 108 | (emulated or Winelib) using that API to debug a |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 109 | <varname>W-process</varname>. |
| 110 | </para> |
| 111 | <para> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 112 | <command>WineDbg</command> is a Winelib application making |
| 113 | use of this API to allow debugging both any Wine or Winelib |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 114 | applications as well as Wine itself (kernel and all DLLs). |
| 115 | </para> |
| 116 | </sect2> |
| 117 | </sect1> |
| 118 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 119 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 120 | <sect1 id="dbg-modes"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 121 | <title>WineDbg's modes of invocation</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 122 | |
| 123 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 124 | <title>Starting a process</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 125 | |
| 126 | <para> |
| 127 | Any application (either a Windows' native executable, or a |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 128 | Winelib application) can be run through |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 129 | <command>WineDbg</command>. Command line options and tricks |
| 130 | are the same as for wine: |
| 131 | </para> |
| 132 | <screen> |
| 133 | winedbg telnet.exe |
| 134 | winedbg "hl.exe -windowed" |
| 135 | </screen> |
| 136 | </sect2> |
| 137 | |
| 138 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 139 | <title>Attaching</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 140 | |
| 141 | <para> |
| 142 | <command>WineDbg</command> can also be launched without any |
| 143 | command line argument: <command>WineDbg</command> is started |
| 144 | without any attached process. You can get a list of running |
| 145 | <varname>W-processes</varname> (and their |
| 146 | <varname>wpid</varname>'s) using the <command>walk |
| 147 | process</command> command, and then, with the |
| 148 | <command>attach</command> command, pick up the |
| 149 | <varname>wpid</varname> of the <varname>W-process</varname> |
Dimitrie O. Paun | 639bf52 | 2003-09-22 19:33:43 +0000 | [diff] [blame] | 150 | you want to debug. This is a neat feature as it allows you |
| 151 | to debug an already started application. |
| 152 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 153 | </sect2> |
| 154 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 155 | <sect2 id="dbg-on-exception"> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 156 | <title id="dbg-exception-title">On exceptions</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 157 | |
| 158 | <para> |
| 159 | When something goes wrong, Windows tracks this as an |
| 160 | exception. Exceptions exist for segmentation violation, |
Dimitrie O. Paun | 639bf52 | 2003-09-22 19:33:43 +0000 | [diff] [blame] | 161 | stack overflow, division by zero, etc. |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 162 | </para> |
| 163 | <para> |
| 164 | When an exception occurs, Wine checks if the <varname>W-process</varname> is |
| 165 | debugged. If so, the exception event is sent to the |
| 166 | debugger, which takes care of it: end of the story. This |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 167 | mechanism is part of the standard Windows' debugging API. |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 168 | </para> |
| 169 | <para> |
| 170 | If the <varname>W-process</varname> is not debugged, Wine |
| 171 | tries to launch a debugger. This debugger (normally |
| 172 | <command>WineDbg</command>, see III Configuration for more |
| 173 | details), at startup, attaches to the |
| 174 | <varname>W-process</varname> which generated the exception |
| 175 | event. In this case, you are able to look at the causes of |
| 176 | the exception, and either fix the causes (and continue |
| 177 | further the execution) or dig deeper to understand what went |
| 178 | wrong. |
| 179 | </para> |
| 180 | <para> |
| 181 | If <command>WineDbg</command> is the standard debugger, the |
| 182 | <command>pass</command> and <command>cont</command> commands |
| 183 | are the two ways to let the process go further for the |
| 184 | handling of the exception event. |
| 185 | </para> |
| 186 | <para> |
| 187 | To be more precise on the way Wine (and Windows) generates |
| 188 | exception events, when a fault occurs (segmentation |
| 189 | violation, stack overflow...), the event is first sent to |
| 190 | the debugger (this is known as a first chance exception). |
| 191 | The debugger can give two answers: |
| 192 | </para> |
| 193 | |
| 194 | <variablelist> |
| 195 | <varlistentry> |
| 196 | <term>continue:</term> |
| 197 | <listitem> |
| 198 | <para> |
| 199 | the debugger had the ability to correct what's |
| 200 | generated the exception, and is now able to continue |
| 201 | process execution. |
| 202 | </para> |
| 203 | </listitem> |
| 204 | </varlistentry> |
| 205 | <varlistentry> |
| 206 | <term>pass:</term> |
| 207 | <listitem> |
| 208 | <para> |
| 209 | the debugger couldn't correct the cause of the |
| 210 | first chance exception. Wine will now try to walk |
| 211 | the list of exception handlers to see if one of them |
| 212 | can handle the exception. If no exception handler is |
| 213 | found, the exception is sent once again to the |
| 214 | debugger to indicate the failure of the exception |
| 215 | handling. |
| 216 | </para> |
| 217 | </listitem> |
| 218 | </varlistentry> |
| 219 | </variablelist> |
| 220 | <note> |
| 221 | <para> |
| 222 | since some of Wine's code uses exceptions and |
| 223 | <function>try/catch</function> blocks to provide some |
| 224 | functionality, <command>WineDbg</command> can be entered |
| 225 | in such cases with segv exceptions. This happens, for |
| 226 | example, with <function>IsBadReadPtr</function> function. |
| 227 | In that case, the <command>pass</command> command shall be |
| 228 | used, to let the handling of the exception to be done by |
| 229 | the <function>catch</function> block in |
| 230 | <function>IsBadReadPtr</function>. |
| 231 | </para> |
| 232 | </note> |
| 233 | </sect2> |
| 234 | |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 235 | <sect2 id="interrupt"> |
| 236 | <title>Interrupting</title> |
| 237 | |
| 238 | <para> |
| 239 | You can stop the debugger while it's running by hitting |
| 240 | Ctrl-C in its window. This will stop the debugged process, |
Dimitrie O. Paun | 639bf52 | 2003-09-22 19:33:43 +0000 | [diff] [blame] | 241 | and let you manipulate the current context. |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 242 | </para> |
| 243 | </sect2> |
| 244 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 245 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 246 | <title>Quitting</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 247 | |
| 248 | <para> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 249 | Wine supports the new XP APIs, allowing for a debugger to |
| 250 | detach from a program being debugged (see |
| 251 | <command>detach</command> command). Unfortunately, as the |
| 252 | debugger cannot, for now, neither clear its internal |
| 253 | information, nor restart a new process, the debugger, after |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 254 | detaching itself, cannot do much except being quitted. |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 255 | </para> |
| 256 | </sect2> |
| 257 | </sect1> |
| 258 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 259 | |
| 260 | <sect1 id="wine-debugger"> |
| 261 | <title>Using the Wine Debugger</title> |
| 262 | |
| 263 | <para> |
Dimitrie O. Paun | 639bf52 | 2003-09-22 19:33:43 +0000 | [diff] [blame] | 264 | This section describes where to start debugging Wine. If at any |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 265 | point you get stuck and want to ask for help, please read the |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 266 | <emphasis>How to Report A Bug</emphasis> section of the |
| 267 | <emphasis>Wine Users Guide</emphasis> for information on how to write |
| 268 | useful bug reports. |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 269 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 270 | |
| 271 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 272 | <title>Crashes</title> |
| 273 | |
| 274 | <para> |
| 275 | These usually show up like this: |
| 276 | </para> |
| 277 | <screen> |
| 278 | |Unexpected Windows program segfault - opcode = 8b |
| 279 | |Segmentation fault in Windows program 1b7:c41. |
| 280 | |Loading symbols from ELF file /root/wine/wine... |
| 281 | |....more Loading symbols from ... |
| 282 | |In 16 bit mode. |
| 283 | |Register dump: |
| 284 | | CS:01b7 SS:016f DS:0287 ES:0000 |
| 285 | | IP:0c41 SP:878a BP:8796 FLAGS:0246 |
| 286 | | AX:811e BX:0000 CX:0000 DX:0000 SI:0001 DI:ffff |
| 287 | |Stack dump: |
| 288 | |0x016f:0x878a: 0001 016f ffed 0000 0000 0287 890b 1e5b |
| 289 | |0x016f:0x879a: 01b7 0001 000d 1050 08b7 016f 0001 000d |
| 290 | |0x016f:0x87aa: 000a 0003 0004 0000 0007 0007 0190 0000 |
| 291 | |0x016f:0x87ba: |
| 292 | | |
| 293 | |0050: sel=0287 base=40211d30 limit=0b93f (bytes) 16-bit rw- |
| 294 | |Backtrace: |
| 295 | |0 0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c) |
| 296 | |1 0x01b7:0x1e5b (PXSRV_FONPUTCATFONT+0x2cd) |
| 297 | |2 0x01a7:0x05aa |
| 298 | |3 0x01b7:0x0768 (PXSRV_FONINITFONTS+0x81) |
| 299 | |4 0x014f:0x03ed (PDOXWIN_@SQLCURCB$Q6CBTYPEULN8CBSCTYPE+0x1b1) |
| 300 | |5 0x013f:0x00ac |
| 301 | | |
| 302 | |0x01b7:0x0c41 (PXSRV_FONGETFACENAME+0x7c): movw %es:0x38(%bx),%dx |
| 303 | </screen> |
| 304 | <para> |
| 305 | Steps to debug a crash. You may stop at any step, but please |
| 306 | report the bug and provide as much of the information |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 307 | gathered to the bug report as feasible. |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 308 | </para> |
| 309 | |
| 310 | <orderedlist> |
| 311 | <listitem> |
| 312 | <para> |
| 313 | Get the reason for the crash. This is usually an access to |
| 314 | an invalid selector, an access to an out of range address |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 315 | in a valid selector, popping a segment register from the |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 316 | stack or the like. When reporting a crash, report this |
| 317 | <emphasis>whole</emphasis> crashdump even if it doesn't |
| 318 | make sense to you. |
| 319 | </para> |
| 320 | <para> |
| 321 | (In this case it is access to an invalid selector, for |
| 322 | <systemitem>%es</systemitem> is <literal>0000</literal>, as |
| 323 | seen in the register dump). |
| 324 | </para> |
| 325 | </listitem> |
| 326 | <listitem> |
| 327 | <para> |
| 328 | Determine the cause of the crash. Since this is usually |
| 329 | a primary/secondary reaction to a failed or misbehaving |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 330 | Wine function, rerun Wine with the<parameter>WINEDEBUG=+relay</parameter> |
| 331 | environment variable set. This will |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 332 | generate quite a lot of output, but usually the reason is |
| 333 | located in the last call(s). Those lines usually look like |
| 334 | this: |
| 335 | </para> |
| 336 | <screen> |
| 337 | |Call KERNEL.90: LSTRLEN(0227:0692 "text") ret=01e7:2ce7 ds=0227 |
| 338 | ^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^^ |
| 339 | | | | | | |Datasegment |
| 340 | | | | | |Return address |
| 341 | | | | |textual parameter |
| 342 | | | | |
| 343 | | | |Argument(s). This one is a win16 segmented pointer. |
| 344 | | |Function called. |
| 345 | |The module, the function is called in. In this case it is KERNEL. |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 346 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 347 | |Ret KERNEL.90: LSTRLEN() retval=0x0004 ret=01e7:2ce7 ds=0227 |
| 348 | ^^^^^^ |
| 349 | |Returnvalue is 16 bit and has the value 4. |
| 350 | </screen> |
| 351 | </listitem> |
| 352 | <listitem> |
| 353 | <para> |
| 354 | If you have found a misbehaving function, try to find out |
| 355 | why it misbehaves. Find the function in the source code. |
| 356 | Try to make sense of the arguments passed. Usually there is |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 357 | a <function>WINE_DEFAULT_DEBUG_CHANNEL(<channel>);</function> |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 358 | at the beginning of the file. Rerun wine with the |
| 359 | <parameter>WINEDEBUG=+xyz,+relay</parameter> environment variable set. |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 360 | </para> |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 361 | <para> |
| 362 | Occasionally there are additional debug channels defined at the |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 363 | beginning of the file in the form. |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 364 | <function>WINE_DECLARE_DEBUG_CHANNEL(<channel>);</function> |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 365 | If so the offending function may also uses one of these alternate |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 366 | channels. Look through the the function for |
| 367 | <function>TRACE_(<channel>)(" ... /n");</function> and add any |
| 368 | additional channels to the commandline. |
| 369 | </para> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 370 | </listitem> |
| 371 | <listitem> |
| 372 | <para> |
| 373 | Additional information on how to debug using the internal |
| 374 | debugger can be found in |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 375 | <filename>programs/winedbg/README</filename>. |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 376 | </para> |
| 377 | </listitem> |
| 378 | <listitem> |
| 379 | <para> |
| 380 | If this information isn't clear enough or if you want to |
| 381 | know more about what's happening in the function itself, |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 382 | try running wine with <parameter>WINEDEBUG=+all</parameter>, |
| 383 | which dumps ALL included debug |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 384 | information in wine. |
| 385 | </para> |
| 386 | </listitem> |
| 387 | <listitem> |
| 388 | <para> |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 389 | If even that isn't enough, add more debug output for yourself |
| 390 | into the functions you find relevant. See The section on Debug |
| 391 | Logging in this guide for more information. You might |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 392 | also try to run the program in <command>gdb</command> |
Francois Gouget | 7572148 | 2003-01-05 01:08:56 +0000 | [diff] [blame] | 393 | instead of using the Wine debugger. If you do that, use |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 394 | <parameter>handle SIGSEGV nostop noprint</parameter> to |
| 395 | disable the handling of seg faults inside |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 396 | <command>gdb</command> (needed for Win16). |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 397 | </para> |
| 398 | </listitem> |
| 399 | <listitem> |
| 400 | <para> |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 401 | You can also set a breakpoint for that function. Start wine |
| 402 | useing <command>winedbg</command> instead of |
| 403 | <command>wine</command>. Once the debugger is is running enter |
| 404 | <command>break</command> <parameter>KERNEL_LSTRLEN</parameter> |
| 405 | (replace by function you want to debug, CASE IS RELEVANT) |
| 406 | to set a breakpoint. Then |
| 407 | use <command>continue</command> to start normal |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 408 | program-execution. Wine will stop if it reaches the |
| 409 | breakpoint. If the program isn't yet at the crashing call |
| 410 | of that function, use <command>continue</command> again |
| 411 | until you are about to enter that function. You may now |
| 412 | proceed with single-stepping the function until you reach |
| 413 | the point of crash. Use the other debugger commands to |
| 414 | print registers and the like. |
| 415 | </para> |
| 416 | </listitem> |
| 417 | </orderedlist> |
| 418 | </sect2> |
| 419 | |
| 420 | <sect2> |
| 421 | <title>Program hangs, nothing happens</title> |
| 422 | |
| 423 | <para> |
Tony Lambregts | 263cdcd | 2002-12-07 23:48:36 +0000 | [diff] [blame] | 424 | Start the program with <command>winedbg</command> instead of |
| 425 | <command>wine</command>. When the program locks up switch to the |
| 426 | winedbg terminal and press |
| 427 | <keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo>. this |
| 428 | will stop the program and let you debug the program as you would for |
| 429 | a crash. |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 430 | </para> |
| 431 | </sect2> |
| 432 | |
| 433 | <sect2> |
| 434 | <title>Program reports an error with a Messagebox</title> |
| 435 | |
| 436 | <para> |
| 437 | Sometimes programs are reporting failure using more or |
| 438 | less nondescript messageboxes. We can debug this using the |
| 439 | same method as Crashes, but there is one problem... For |
| 440 | setting up a message box the program also calls Wine |
| 441 | producing huge chunks of debug code. |
| 442 | </para> |
| 443 | <para> |
| 444 | Since the failure happens usually directly before setting up |
Tony Lambregts | 109fb9c | 2002-11-30 01:57:19 +0000 | [diff] [blame] | 445 | the Messagebox you can start winedbg and set a |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 446 | breakpoint at <function>MessageBoxA</function> (called by win16 |
| 447 | and win32 programs) and proceed with |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 448 | <command>continue</command>. With <parameter>WINEDEBUG=+all</parameter> |
| 449 | Wine will now stop directly before setting |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 450 | up the Messagebox. Proceed as explained above. |
| 451 | </para> |
| 452 | <para> |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 453 | You can also run wine using <command>WINEDEBUG=+relay wine |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 454 | program.exe 2>&1 | less -i</command> and in |
| 455 | <command>less</command> search for <quote>MessageBox</quote>. |
| 456 | </para> |
| 457 | </sect2> |
| 458 | |
| 459 | <sect2> |
| 460 | <title>Disassembling programs:</title> |
| 461 | |
| 462 | <para> |
| 463 | You may also try to disassemble the offending program to |
| 464 | check for undocumented features and/or use of them. |
| 465 | </para> |
| 466 | <para> |
| 467 | The best, freely available, disassembler for Win16 programs is |
Francois Gouget | 7572148 | 2003-01-05 01:08:56 +0000 | [diff] [blame] | 468 | <application>Windows Codeback</application>, archive name |
Francois Gouget | b4557d0 | 2003-09-15 20:06:47 +0000 | [diff] [blame] | 469 | <filename>wcbxxx.zip</> (e.g. <filename>wcb105a.zip</>), which |
| 470 | usually can be found in the <filename>Cica-Mirror</filename> |
| 471 | subdirectory on the Wine ftp sites. (See <filename>ANNOUNCE</>). |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 472 | </para> |
| 473 | <para> |
| 474 | Disassembling win32 programs is possible using |
Francois Gouget | b4557d0 | 2003-09-15 20:06:47 +0000 | [diff] [blame] | 475 | <application>Windows Disassembler 32</>. Look for |
| 476 | a file called <filename>w32dsm87.zip</> (or similar) |
| 477 | on <ulink url="http://www.winsite.com/">http://www.winsite.com</> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 478 | and mirrors. The shareware version does not allow saving of |
| 479 | disassembly listings. You can also use the newer (and in the |
| 480 | full version better) <application>Interactive |
| 481 | Disassembler</application> (IDA) from the ftp sites mentioned |
| 482 | at the end of the document. Understanding disassembled code is |
| 483 | mostly a question of exercise. |
| 484 | </para> |
| 485 | <para> |
| 486 | Most code out there uses standard C function entries (for it |
| 487 | is usually written in C). Win16 function entries usually |
| 488 | look like that: |
| 489 | </para> |
| 490 | <programlisting> |
| 491 | push bp |
| 492 | mov bp, sp |
| 493 | ... function code .. |
| 494 | retf XXXX <--------- XXXX is number of bytes of arguments |
| 495 | </programlisting> |
| 496 | <para> |
| 497 | This is a <function>FAR</function> function with no local |
| 498 | storage. The arguments usually start at |
| 499 | <literal>[bp+6]</literal> with increasing offsets. Note, that |
| 500 | <literal>[bp+6]</literal> belongs to the |
| 501 | <emphasis>rightmost</emphasis> argument, for exported win16 |
| 502 | functions use the PASCAL calling convention. So, if we use |
| 503 | <function>strcmp(a,b)</function> with <parameter>a</parameter> |
| 504 | and <parameter>b</parameter> both 32 bit variables |
| 505 | <parameter>b</parameter> would be at <literal>[bp+6]</literal> |
| 506 | and <parameter>a</parameter> at <literal>[bp+10]</literal>. |
| 507 | </para> |
| 508 | <para> |
| 509 | Most functions make also use of local storage in the stackframe: |
| 510 | </para> |
| 511 | <programlisting> |
| 512 | enter 0086, 00 |
| 513 | ... function code ... |
| 514 | leave |
| 515 | retf XXXX |
| 516 | </programlisting> |
| 517 | <para> |
| 518 | This does mostly the same as above, but also adds |
| 519 | <literal>0x86</literal> bytes of stackstorage, which is |
| 520 | accessed using <literal>[bp-xx]</literal>. Before calling a |
| 521 | function, arguments are pushed on the stack using something |
| 522 | like this: |
| 523 | </para> |
| 524 | <programlisting> |
| 525 | push word ptr [bp-02] <- will be at [bp+8] |
| 526 | push di <- will be at [bp+6] |
| 527 | call KERNEL.LSTRLEN |
| 528 | </programlisting> |
| 529 | <para> |
| 530 | Here first the selector and then the offset to the passed |
| 531 | string are pushed. |
| 532 | </para> |
| 533 | </sect2> |
| 534 | |
| 535 | <sect2> |
| 536 | <title>Sample debugging session:</title> |
| 537 | |
| 538 | <para> |
| 539 | Let's debug the infamous Word <filename>SHARE.EXE</filename> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 540 | messagebox: |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 541 | </para> |
| 542 | <screen> |
| 543 | |marcus@jet $ wine winword.exe |
| 544 | | +---------------------------------------------+ |
| 545 | | | ! You must leave Windows and load SHARE.EXE| |
| 546 | | | before starting Word. | |
| 547 | | +---------------------------------------------+ |
| 548 | </screen> |
| 549 | <screen> |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 550 | |marcus@jet $ WINEDEBUG=+relay,-debug wine winword.exe |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 551 | |CallTo32(wndproc=0x40065bc0,hwnd=000001ac,msg=00000081,wp=00000000,lp=00000000) |
| 552 | |Win16 task 'winword': Breakpoint 1 at 0x01d7:0x001a |
| 553 | |CallTo16(func=0127:0070,ds=0927) |
| 554 | |Call WPROCS.24: TASK_RESCHEDULE() ret=00b7:1456 ds=0927 |
| 555 | |Ret WPROCS.24: TASK_RESCHEDULE() retval=0x8672 ret=00b7:1456 ds=0927 |
| 556 | |CallTo16(func=01d7:001a,ds=0927) |
| 557 | | AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=0927 BP=0000 ES=11f7 |
| 558 | |Loading symbols: /home/marcus/wine/wine... |
| 559 | |Stopped on breakpoint 1 at 0x01d7:0x001a |
| 560 | |In 16 bit mode. |
| 561 | |Wine-dbg>break MessageBoxA <---- Set Breakpoint |
| 562 | |Breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190]) |
| 563 | |Wine-dbg>c <---- Continue |
| 564 | |Call KERNEL.91: INITTASK() ret=0157:0022 ds=08a7 |
| 565 | | AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=08a7 ES=11d7 EFL=00000286 |
| 566 | |CallTo16(func=090f:085c,ds=0dcf,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0dcf) |
| 567 | |... <----- Much debugoutput |
| 568 | |Call KERNEL.136: GETDRIVETYPE(0x0000) ret=060f:097b ds=0927 |
| 569 | ^^^^^^ Drive 0 (A:) |
| 570 | |Ret KERNEL.136: GETDRIVETYPE() retval=0x0002 ret=060f:097b ds=0927 |
| 571 | ^^^^^^ DRIVE_REMOVEABLE |
| 572 | (It is a floppy diskdrive.) |
| 573 | |
| 574 | |Call KERNEL.136: GETDRIVETYPE(0x0001) ret=060f:097b ds=0927 |
| 575 | ^^^^^^ Drive 1 (B:) |
| 576 | |Ret KERNEL.136: GETDRIVETYPE() retval=0x0000 ret=060f:097b ds=0927 |
| 577 | ^^^^^^ DRIVE_CANNOTDETERMINE |
| 578 | (I don't have drive B: assigned) |
| 579 | |
| 580 | |Call KERNEL.136: GETDRIVETYPE(0x0002) ret=060f:097b ds=0927 |
| 581 | ^^^^^^^ Drive 2 (C:) |
| 582 | |Ret KERNEL.136: GETDRIVETYPE() retval=0x0003 ret=060f:097b ds=0927 |
| 583 | ^^^^^^ DRIVE_FIXED |
| 584 | (specified as a harddisk) |
| 585 | |
| 586 | |Call KERNEL.97: GETTEMPFILENAME(0x00c3,0x09278364"doc",0x0000,0927:8248) ret=060f:09b1 ds=0927 |
| 587 | ^^^^^^ ^^^^^ ^^^^^^^^^ |
| 588 | | | |buffer for fname |
| 589 | | |temporary name ~docXXXX.tmp |
| 590 | |Force use of Drive C:. |
| 591 | |
| 592 | |Warning: GetTempFileName returns 'C:~doc9281.tmp', which doesn't seem to be writeable. |
| 593 | |Please check your configuration file if this generates a failure. |
| 594 | </screen> |
| 595 | <para> |
| 596 | Whoops, it even detects that something is wrong! |
| 597 | </para> |
| 598 | <screen> |
| 599 | |Ret KERNEL.97: GETTEMPFILENAME() retval=0x9281 ret=060f:09b1 ds=0927 |
| 600 | ^^^^^^ Temporary storage ID |
| 601 | |
| 602 | |Call KERNEL.74: OPENFILE(0x09278248"C:~doc9281.tmp",0927:82da,0x1012) ret=060f:09d8 ds=0927 |
| 603 | ^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^ |
| 604 | |filename |OFSTRUCT |open mode: |
| 605 | |
| 606 | OF_CREATE|OF_SHARE_EXCLUSIVE|OF_READWRITE |
| 607 | </screen> |
| 608 | <para> |
| 609 | This fails, since my <medialabel>C:</medialabel> drive is in |
| 610 | this case mounted readonly. |
| 611 | </para> |
| 612 | <screen> |
| 613 | |Ret KERNEL.74: OPENFILE() retval=0xffff ret=060f:09d8 ds=0927 |
| 614 | ^^^^^^ HFILE_ERROR16, yes, it failed. |
| 615 | |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 616 | |Call USER.1: MESSAGEBOX(0x0000,0x09278376"You must close Windows and load SHARE.EXE before you start Word.",0x00000000,0x1030) ret=060f:084f ds=0927 |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 617 | </screen> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 618 | <para> |
| 619 | And MessageBox'ed. |
| 620 | </para> |
| 621 | <screen> |
| 622 | |Stopped on breakpoint 2 at 0x40189100 (MessageBoxA [msgbox.c:190]) |
| 623 | |190 { <- the sourceline |
| 624 | In 32 bit mode. |
| 625 | Wine-dbg> |
| 626 | </screen> |
| 627 | <para> |
| 628 | The code seems to find a writeable harddisk and tries to create |
| 629 | a file there. To work around this bug, you can define |
| 630 | <medialabel>C:</medialabel> as a networkdrive, which is ignored |
| 631 | by the code above. |
| 632 | </para> |
| 633 | </sect2> |
| 634 | |
| 635 | <sect2> |
| 636 | <title>Debugging Tips</title> |
| 637 | |
| 638 | <para> |
Dimitrie O. Paun | 639bf52 | 2003-09-22 19:33:43 +0000 | [diff] [blame] | 639 | Here are some additional debugging tips: |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 640 | </para> |
| 641 | |
| 642 | <itemizedlist> |
| 643 | <listitem> |
| 644 | <para> |
| 645 | If you have a program crashing at such an early loader phase that you can't |
| 646 | use the Wine debugger normally, but Wine already executes the program's |
| 647 | start code, then you may use a special trick. You should do a |
| 648 | <programlisting> |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 649 | WINEDEBUG=+relay wine program |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 650 | </programlisting> |
| 651 | to get a listing of the functions the program calls in its start function. |
| 652 | Now you do a |
| 653 | <programlisting> |
Tony Lambregts | 263cdcd | 2002-12-07 23:48:36 +0000 | [diff] [blame] | 654 | winedbg winfile.exe |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 655 | </programlisting> |
| 656 | </para> |
| 657 | <para> |
Tony Lambregts | 263cdcd | 2002-12-07 23:48:36 +0000 | [diff] [blame] | 658 | This way, you get into <command>winedbg</command>. Now you |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 659 | can set a breakpoint on any function the program calls in |
| 660 | the start function and just type <userinput>c</userinput> |
| 661 | to bypass the eventual calls of Winfile to this function |
| 662 | until you are finally at the place where this function gets |
| 663 | called by the crashing start function. Now you can proceed |
| 664 | with your debugging as usual. |
| 665 | </para> |
| 666 | </listitem> |
| 667 | <listitem> |
| 668 | <para> |
| 669 | If you try to run a program and it quits after showing an error messagebox, |
| 670 | the problem can usually be identified in the return value of one of the |
| 671 | functions executed before <function>MessageBox()</function>. |
| 672 | That's why you should re-run the program with e.g. |
| 673 | <programlisting> |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 674 | WINEDEBUG=+relay wine <program name> &>relmsg |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 675 | </programlisting> |
| 676 | Then do a <command>more relmsg</command> and search for the |
| 677 | last occurrence of a call to the string "MESSAGEBOX". This is a line like |
| 678 | <programlisting> |
| 679 | Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff |
| 680 | </programlisting> |
| 681 | In my example the lines before the call to |
| 682 | <function>MessageBox()</function> look like that: |
| 683 | <programlisting> |
| 684 | Call KERNEL.96: FREELIBRARY(0x0347) ret=01cf:1033 ds=01ff |
| 685 | CallTo16(func=033f:0072,ds=01ff,0x0000) |
| 686 | Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1033 ds=01ff |
| 687 | Call KERNEL.96: FREELIBRARY(0x036f) ret=01cf:1043 ds=01ff |
| 688 | CallTo16(func=0367:0072,ds=01ff,0x0000) |
| 689 | Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:1043 ds=01ff |
| 690 | Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff |
| 691 | CallTo16(func=0317:0072,ds=01ff,0x0000) |
| 692 | Ret KERNEL.96: FREELIBRARY() retval=0x0001 ret=01cf:105c ds=01ff |
| 693 | Call USER.171: WINHELP(0x02ac,0x01ff05b4 "COMET.HLP",0x0002,0x00000000) ret=01cf:1070 ds=01ff |
| 694 | CallTo16(func=0117:0080,ds=01ff) |
| 695 | Call WPROCS.24: TASK_RESCHEDULE() ret=00a7:0a2d ds=002b |
| 696 | Ret WPROCS.24: TASK_RESCHEDULE() retval=0x0000 ret=00a7:0a2d ds=002b |
| 697 | Ret USER.171: WINHELP() retval=0x0001 ret=01cf:1070 ds=01ff |
| 698 | Call KERNEL.96: FREELIBRARY(0x01be) ret=01df:3e29 ds=01ff |
| 699 | Ret KERNEL.96: FREELIBRARY() retval=0x0000 ret=01df:3e29 ds=01ff |
| 700 | Call KERNEL.52: FREEPROCINSTANCE(0x02cf00ba) ret=01f7:1460 ds=01ff |
| 701 | Ret KERNEL.52: FREEPROCINSTANCE() retval=0x0001 ret=01f7:1460 ds=01ff |
| 702 | Call USER.1: MESSAGEBOX(0x0000,0x01ff1246 "Runtime error 219 at 0004:1056.",0x00000000,0x1010) ret=01f7:2160 ds=01ff |
| 703 | </programlisting> |
| 704 | </para> |
| 705 | <para> |
| 706 | I think that the call to <function>MessageBox()</function> |
| 707 | in this example is <emphasis>not</emphasis> caused by a |
| 708 | wrong result value of some previously executed function |
| 709 | (it's happening quite often like that), but instead the |
| 710 | messagebox complains about a runtime error at |
| 711 | <literal>0x0004:0x1056</literal>. |
| 712 | </para> |
| 713 | <para> |
| 714 | As the segment value of the address is only |
| 715 | <literal>4</literal>, I think that that is only an internal |
| 716 | program value. But the offset address reveals something |
| 717 | quite interesting: Offset <literal>1056</literal> is |
| 718 | <emphasis>very</emphasis> close to the return address of |
| 719 | <function>FREELIBRARY()</function>: |
| 720 | <programlisting> |
| 721 | Call KERNEL.96: FREELIBRARY(0x031f) ret=01cf:105c ds=01ff |
| 722 | ^^^^ |
| 723 | </programlisting> |
| 724 | </para> |
| 725 | <para> |
| 726 | Provided that segment <literal>0x0004</literal> is indeed segment |
| 727 | <literal>0x1cf</literal>, we now we can use IDA (available at |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 728 | <ulink url="http://www.filelibrary.com:8080/cgi-bin/freedownload/DOS/h/72/ida35bx.zip"> |
| 729 | http://www.filelibrary.com:8080/cgi-bin/freedownload/DOS/h/72/ida35bx.zip</ulink>) to |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 730 | disassemble the part that caused the error. We just have to find the address of |
| 731 | the call to <function>FreeLibrary()</function>. Some lines before that the |
| 732 | runtime error occurred. But be careful! In some cases you don't have to |
| 733 | disassemble the main program, but instead some DLL called by it in order to find |
| 734 | the correct place where the runtime error occurred. That can be determined by |
| 735 | finding the origin of the segment value (in this case <literal>0x1cf</literal>). |
| 736 | </para> |
| 737 | </listitem> |
| 738 | <listitem> |
| 739 | <para> |
| 740 | If you have created a relay file of some crashing |
| 741 | program and want to set a breakpoint at a certain |
| 742 | location which is not yet available as the program loads |
| 743 | the breakpoint's segment during execution, you may set a |
| 744 | breakpoint to <function>GetVersion16/32</function> as |
| 745 | those functions are called very often. |
| 746 | </para> |
| 747 | <para> |
| 748 | Then do a <userinput>c</userinput> until you are able to |
| 749 | set this breakpoint without error message. |
| 750 | </para> |
| 751 | </listitem> |
| 752 | <listitem> |
| 753 | <para> |
| 754 | Some useful programs: |
| 755 | </para> |
| 756 | <variablelist> |
| 757 | <varlistentry> |
| 758 | <term> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 759 | <application>IDA</application>: |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 760 | <filename> |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 761 | <ulink url="http://www.filelibrary.com:8080/cgi-bin/freedownload/DOS/h/72/ida35bx.zip"> |
| 762 | http://www.filelibrary.com:8080/cgi-bin/freedownload/DOS/h/72/ida35bx.zip</ulink> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 763 | </filename> |
| 764 | </term> |
| 765 | <listitem> |
| 766 | <para> |
| 767 | <emphasis>Very</emphasis> good DOS disassembler ! It's badly needed |
| 768 | for debugging Wine sometimes. |
| 769 | </para> |
| 770 | </listitem> |
| 771 | </varlistentry> |
| 772 | <varlistentry> |
| 773 | <term> |
| 774 | <application>XRAY</application>: |
| 775 | <filename> |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 776 | <ulink url="http://garbo.uwasa.fi/pub/pc/sysinfo/xray15.zip"> |
| 777 | http://garbo.uwasa.fi/pub/pc/sysinfo/xray15.zip</ulink> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 778 | </filename> |
| 779 | </term> |
| 780 | <listitem> |
| 781 | <para> |
| 782 | Traces DOS calls (Int 21h, DPMI, ...). Use it with |
| 783 | Windows to correct file management problems etc. |
| 784 | </para> |
| 785 | </listitem> |
| 786 | </varlistentry> |
| 787 | <varlistentry> |
| 788 | <term> |
| 789 | <application>pedump</application>: |
| 790 | <filename> |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 791 | <ulink url="ftp://ftp.simtel.net/pub/simtelnet/win95/prog/pedump.zip"> |
| 792 | ftp://ftp.simtel.net/pub/simtelnet/win95/prog/pedump.zip</ulink> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 793 | </filename> |
| 794 | </term> |
| 795 | <listitem> |
| 796 | <para> |
| 797 | Dumps the imports and exports of a PE (Portable |
| 798 | Executable) DLL. |
| 799 | </para> |
| 800 | </listitem> |
| 801 | </varlistentry> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 802 | <varlistentry> |
| 803 | <term> |
| 804 | <application>winedump</application>: |
| 805 | </term> |
| 806 | <listitem> |
| 807 | <para> |
| 808 | Dumps the imports and exports of a PE (Portable |
| 809 | Executable) DLL (included in wine tree). |
| 810 | </para> |
| 811 | </listitem> |
| 812 | </varlistentry> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 813 | </variablelist> |
| 814 | </listitem> |
| 815 | </itemizedlist> |
| 816 | </sect2> |
| 817 | |
| 818 | <sect2> |
| 819 | <title>Some basic debugger usages:</title> |
| 820 | |
| 821 | <para> |
| 822 | After starting your program with |
| 823 | </para> |
| 824 | <screen> |
| 825 | wine -debug myprog.exe |
| 826 | </screen> |
| 827 | <para> |
| 828 | the program loads and you get a prompt at the program |
| 829 | starting point. Then you can set breakpoints: |
| 830 | </para> |
| 831 | <screen> |
| 832 | b RoutineName (by outine name) OR |
| 833 | b *0x812575 (by address) |
| 834 | </screen> |
| 835 | <para> |
| 836 | Then you hit <command>c</command> (continue) to run the |
| 837 | program. It stops at the breakpoint. You can type |
| 838 | </para> |
| 839 | <screen> |
| 840 | step (to step one line) OR |
| 841 | stepi (to step one machine instruction at a time; |
| 842 | here, it helps to know the basic 386 |
| 843 | instruction set) |
| 844 | info reg (to see registers) |
| 845 | info stack (to see hex values in the stack) |
| 846 | info local (to see local variables) |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 847 | list <line number> (to list source code) |
| 848 | x <variable name> (to examine a variable; only works if code |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 849 | is not compiled with optimization) |
| 850 | x 0x4269978 (to examine a memory location) |
| 851 | ? (help) |
| 852 | q (quit) |
| 853 | </screen> |
| 854 | <para> |
| 855 | By hitting <keycap>Enter</keycap>, you repeat the last |
| 856 | command. |
| 857 | </para> |
| 858 | </sect2> |
| 859 | </sect1> |
| 860 | |
| 861 | |
| 862 | <sect1 id="memory-addresses"> |
| 863 | <title>Useful memory addresses</title> |
| 864 | <para> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 865 | Wine uses several different kinds of memory addresses. |
| 866 | </para> |
| 867 | <variablelist> |
| 868 | <varlistentry> |
| 869 | <term> |
| 870 | Win32/"normal" Wine addresses/Linux: linear addresses. |
| 871 | </term> |
| 872 | <listitem> |
| 873 | <para> |
| 874 | Linear addresses can be everything from 0x0 up to |
| 875 | 0xffffffff. In Wine on Linux they are often around |
| 876 | e.g. 0x08000000, 0x00400000 (std. Win32 program load |
| 877 | address), 0x40000000. Every Win32 process has its own |
| 878 | private 4GB address space (that is, from 0x0 up to |
| 879 | 0xffffffff). |
| 880 | </para> |
| 881 | </listitem> |
| 882 | </varlistentry> |
| 883 | <varlistentry> |
| 884 | <term> |
| 885 | Win16 "enhanced mode": segmented addresses. |
| 886 | </term> |
| 887 | <listitem> |
| 888 | <para> |
| 889 | These are the "normal" Win16 addresses, called SEGPTR. |
| 890 | They have a segment:offset notation, e.g. 0x01d7:0x0012. |
Andreas Mohr | 56e6cd0 | 2003-04-01 03:26:13 +0000 | [diff] [blame] | 891 | The segment part usually is a "selector", which |
| 892 | <emphasis>always</emphasis> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 893 | has the lowest 3 bits set. Some sample selectors are |
| 894 | 0x1f7, 0x16f, 0x8f. If these bits are set except for |
| 895 | the lowest bit, as e.g. with 0x1f6,xi then it might be a |
| 896 | handle to global memory. Just set the lowest bit to get |
| 897 | the selector in these cases. A selector kind of |
| 898 | "points" to a certain linear (see above) base address. |
| 899 | It has more or less three important attributes: segment |
| 900 | base address, segment limit, segment access rights. |
| 901 | </para> |
| 902 | <para> |
| 903 | Example: |
| 904 | </para> |
| 905 | <para> |
| 906 | Selector 0x1f7 (0x40320000, 0x0000ffff, r-x) So 0x1f7 |
| 907 | has a base address of 0x40320000, the segment's last |
| 908 | address is 0x4032ffff (limit 0xffff), and it's readable |
| 909 | and executable. So an address of 0x1f7:0x2300 would be |
| 910 | the linear address of 0x40322300. |
| 911 | </para> |
| 912 | </listitem> |
| 913 | </varlistentry> |
| 914 | <varlistentry> |
| 915 | <term> |
| 916 | DOS/Win16 "standard mode" |
| 917 | </term> |
| 918 | <listitem> |
| 919 | <para> |
| 920 | They, too, have a segment:offset notation. But they are |
| 921 | completely different from "normal" Win16 addresses, as |
| 922 | they just represent at most 1MB of memory: The segment |
| 923 | part can be anything from 0 to 0xffff, and it's the same |
| 924 | with the offset part. |
| 925 | </para> |
| 926 | <para> |
| 927 | Now the strange thing is the calculation that's behind |
| 928 | these addresses: Just calculate segment*16 + offset in |
| 929 | order to get a "linear DOS" address. So |
| 930 | e.g. 0x0f04:0x3628 results in 0xf040 + 0x3628 = 0x12668. |
| 931 | And the highest address you can get is 0xfffff (1MB), of |
| 932 | course. In Wine, this "linear DOS" address of 0x12668 |
| 933 | has to be added to the linear base address of the |
| 934 | corresponding DOS memory allocated for dosmod in order |
| 935 | to get the true linear address of a DOS seg:offs |
| 936 | address. And make sure that you're doing this in the |
| 937 | correct process with the correct linear address space, |
| 938 | of course ;-) |
| 939 | </para> |
| 940 | </listitem> |
| 941 | </varlistentry> |
| 942 | </variablelist> |
| 943 | </sect1> |
| 944 | |
| 945 | <sect1 id="dbg-config"> |
| 946 | <title>Configuration</title> |
| 947 | |
| 948 | <sect2> |
| 949 | <title>Registry configuration</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 950 | |
| 951 | <para> |
| 952 | The Windows' debugging API uses a registry entry to know |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 953 | which debugger to invoke when an unhandled exception occurs |
| 954 | (see <link endterm="dbg-exception-title" |
| 955 | linkend="dbg-on-exception"></link> for some details). Two |
| 956 | values in key |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 957 | </para> |
| 958 | <programlisting> |
| 959 | "MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" |
| 960 | </programlisting> |
| 961 | <para> |
| 962 | Determine the behavior: |
| 963 | </para> |
| 964 | <variablelist> |
| 965 | <varlistentry> |
| 966 | <term>Debugger:</term> |
| 967 | <listitem> |
| 968 | <para> |
| 969 | this is the command line used to launch the debugger |
| 970 | (it uses two <function>printf</function> formats |
| 971 | (<literal>%ld</literal>) to pass context dependent |
| 972 | information to the debugger). You should put here a |
| 973 | complete path to your debugger |
| 974 | (<command>WineDbg</command> can of course be used, but |
| 975 | any other Windows' debugging API aware debugger will |
| 976 | do). |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 977 | The path to the debugger you chose to use must be reachable |
| 978 | via a DOS drive in the Wine config file ! |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 979 | </para> |
| 980 | </listitem> |
| 981 | </varlistentry> |
| 982 | <varlistentry> |
| 983 | <term>Auto:</term> |
| 984 | <listitem> |
| 985 | <para> |
| 986 | if this value is zero, a message box will ask the |
| 987 | user if he/she wishes to launch the debugger when an |
| 988 | unhandled exception occurs. Otherwise, the debugger |
| 989 | is automatically started. |
| 990 | </para> |
| 991 | </listitem> |
| 992 | </varlistentry> |
| 993 | </variablelist> |
| 994 | |
| 995 | <para> |
| 996 | A regular Wine registry looks like: |
| 997 | </para> |
| 998 | <programlisting> |
| 999 | [MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug] 957636538 |
| 1000 | "Auto"=dword:00000001 |
Ivan Leo Murray-Smith | 593e537 | 2004-04-26 20:13:17 +0000 | [diff] [blame] | 1001 | "Debugger"="winedbg %ld %ld" |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1002 | </programlisting> |
| 1003 | |
| 1004 | <note> |
| 1005 | <title>Note 1</title> |
| 1006 | <para> |
| 1007 | creating this key is mandatory. Not doing so will not |
| 1008 | fire the debugger when an exception occurs. |
| 1009 | </para> |
| 1010 | </note> |
| 1011 | <note> |
| 1012 | <title>Note 2</title> |
| 1013 | <para> |
Eric Pouech | 21b366e | 2002-02-27 01:29:18 +0000 | [diff] [blame] | 1014 | <command>wineinstall</command> (available in Wine source) |
| 1015 | sets up this correctly. |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1016 | However, due to some limitation of the registry installed, |
| 1017 | if a previous Wine installation exists, it's safer to |
| 1018 | remove the whole |
| 1019 | </para> |
| 1020 | <programlisting> |
| 1021 | [MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug] |
| 1022 | </programlisting> |
| 1023 | <para> |
| 1024 | key before running again <command>wineinstall</command> to |
| 1025 | regenerate this key. |
| 1026 | </para> |
| 1027 | </note> |
| 1028 | </sect2> |
| 1029 | |
| 1030 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1031 | <title>WineDbg configuration</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1032 | |
| 1033 | <para> |
Francois Gouget | 588ff37 | 2001-08-21 17:07:17 +0000 | [diff] [blame] | 1034 | <command>WineDbg</command> can be configured through a number |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1035 | of options. Those options are stored in the registry, on a |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1036 | per user basis. The key is (in <emphasis>my</emphasis> registry) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1037 | </para> |
| 1038 | <programlisting> |
| 1039 | [eric\\Software\\Wine\\WineDbg] |
| 1040 | </programlisting> |
| 1041 | <para> |
| 1042 | Those options can be read/written while inside |
| 1043 | <command>WineDbg</command>, as part of the debugger |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1044 | expressions. To refer to one of these options, its name must |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1045 | be prefixed by a <literal>$</literal> sign. For example, |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1046 | </para> |
| 1047 | <programlisting> |
| 1048 | set $BreakAllThreadsStartup = 1 |
| 1049 | </programlisting> |
| 1050 | <para> |
| 1051 | sets the option <varname>BreakAllThreadsStartup</varname> to |
| 1052 | <literal>TRUE</literal>. |
| 1053 | </para> |
| 1054 | <para> |
| 1055 | All the options are read from the registry when |
| 1056 | <command>WineDbg</command> starts (if no corresponding value |
| 1057 | is found, a default value is used), and are written back to |
| 1058 | the registry when <command>WineDbg</command> exits (hence, |
| 1059 | all modifications to those options are automatically saved |
| 1060 | when <command>WineDbg</command> terminates). |
| 1061 | </para> |
| 1062 | <para> |
| 1063 | Here's the list of all options: |
| 1064 | </para> |
| 1065 | |
| 1066 | <sect3> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1067 | <title>Controlling when the debugger is entered</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1068 | |
| 1069 | <variablelist> |
| 1070 | <varlistentry> |
| 1071 | <term><varname>BreakAllThreadsStartup</varname></term> |
| 1072 | <listitem> |
| 1073 | <para> |
| 1074 | Set to <literal>TRUE</literal> if at all threads |
| 1075 | start-up the debugger stops set to |
| 1076 | <literal>FALSE</literal> if only at the first thread |
| 1077 | startup of a given process the debugger stops. |
| 1078 | <literal>FALSE</literal> by default. |
| 1079 | </para> |
| 1080 | </listitem> |
| 1081 | </varlistentry> |
| 1082 | <varlistentry> |
| 1083 | <term><varname>BreakOnCritSectTimeOut</varname></term> |
| 1084 | <listitem> |
| 1085 | <para> |
| 1086 | Set to <literal>TRUE</literal> if the debugger stops |
| 1087 | when a critical section times out (5 minutes); |
| 1088 | <literal>TRUE</literal> by default. |
| 1089 | </para> |
| 1090 | </listitem> |
| 1091 | </varlistentry> |
| 1092 | <varlistentry> |
| 1093 | <term><varname>BreakOnAttach</varname></term> |
| 1094 | <listitem> |
| 1095 | <para> |
| 1096 | Set to <literal>TRUE</literal> if when |
| 1097 | <command>WineDbg</command> attaches to an existing |
| 1098 | process after an unhandled exception, |
| 1099 | <command>WineDbg</command> shall be entered on the |
| 1100 | first attach event. Since the attach event is |
| 1101 | meaningless in the context of an exception event |
| 1102 | (the next event which is the exception event is of |
| 1103 | course relevant), that option is likely to be |
| 1104 | <literal>FALSE</literal>. |
| 1105 | </para> |
| 1106 | </listitem> |
| 1107 | </varlistentry> |
| 1108 | <varlistentry> |
| 1109 | <term><varname>BreakOnFirstChance</varname></term> |
| 1110 | <listitem> |
| 1111 | <para> |
| 1112 | An exception can generate two debug events. The |
| 1113 | first one is passed to the debugger (known as a |
| 1114 | first chance) just after the exception. The debugger |
| 1115 | can then decides either to resume execution (see |
| 1116 | <command>WineDbg</command>'s <command>cont</command> |
| 1117 | command) or pass the exception up to the exception |
| 1118 | handler chain in the program (if it exists) |
Francois Gouget | 588ff37 | 2001-08-21 17:07:17 +0000 | [diff] [blame] | 1119 | (<command>WineDbg</command> implements this through the |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1120 | <command>pass</command> command). If none of the |
| 1121 | exception handlers takes care of the exception, the |
| 1122 | exception event is sent again to the debugger (known |
| 1123 | as last chance exception). You cannot pass on a last |
| 1124 | exception. When the |
| 1125 | <varname>BreakOnFirstChance</varname> exception is |
| 1126 | <literal>TRUE</literal>, then winedbg is entered for |
| 1127 | both first and last chance execptions (to |
| 1128 | <literal>FALSE</literal>, it's only entered for last |
| 1129 | chance exceptions). |
| 1130 | </para> |
| 1131 | </listitem> |
| 1132 | </varlistentry> |
Eric Pouech | 4a85a45 | 2001-04-13 22:35:55 +0000 | [diff] [blame] | 1133 | <varlistentry> |
| 1134 | <term><varname>BreakOnDllLoad</varname></term> |
| 1135 | <listitem> |
| 1136 | <para> |
| 1137 | Set to <literal>TRUE</literal> if the debugger stops |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1138 | when a DLL is loaded into memory; when the debugger |
| 1139 | is invoked after a crash, the DLLs already mapped in |
Eric Pouech | 4a85a45 | 2001-04-13 22:35:55 +0000 | [diff] [blame] | 1140 | memory will not trigger this break. |
| 1141 | <literal>FALSE</literal> by default. |
| 1142 | </para> |
| 1143 | </listitem> |
| 1144 | </varlistentry> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1145 | </variablelist> |
| 1146 | </sect3> |
| 1147 | |
| 1148 | <sect3> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1149 | <title>Context information</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1150 | |
| 1151 | <variablelist> |
| 1152 | <varlistentry> |
| 1153 | <term><varname>ThreadId</varname></term> |
| 1154 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1155 | <para> |
| 1156 | ID of the <varname>W-thread</varname> currently |
| 1157 | examined by the debugger |
| 1158 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1159 | </listitem> |
| 1160 | </varlistentry> |
| 1161 | <varlistentry> |
| 1162 | <term><varname>ProcessId</varname></term> |
| 1163 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1164 | <para> |
| 1165 | ID of the <varname>W-thread</varname> currently |
| 1166 | examined by the debugger |
| 1167 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1168 | </listitem> |
| 1169 | </varlistentry> |
| 1170 | <varlistentry> |
| 1171 | <term><registers></term> |
| 1172 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1173 | <para> |
| 1174 | All CPU registers are also available |
| 1175 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1176 | </listitem> |
| 1177 | </varlistentry> |
| 1178 | </variablelist> |
| 1179 | |
| 1180 | <para> |
| 1181 | The <varname>ThreadId</varname> and |
| 1182 | <varname>ProcessId</varname> variables can be handy to set |
| 1183 | conditional breakpoints on a given thread or process. |
| 1184 | </para> |
| 1185 | </sect3> |
| 1186 | </sect2> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1187 | </sect1> |
| 1188 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1189 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1190 | <sect1 id="dbg-commands"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1191 | <title>WineDbg Command Reference</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1192 | |
| 1193 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1194 | <title>Misc</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1195 | |
| 1196 | <screen> |
| 1197 | abort aborts the debugger |
| 1198 | quit exits the debugger |
| 1199 | |
Jeff | 1c0b4aa | 2004-04-12 22:09:36 +0000 | [diff] [blame] | 1200 | attach N attach to a W-process (N is its ID, numeric or hexadecimal(0xN)). |
| 1201 | IDs can be obtained using the walk process command. Note the |
| 1202 | walk process command returns hexadecimal values |
Eric Pouech | 21b366e | 2002-02-27 01:29:18 +0000 | [diff] [blame] | 1203 | detach detach from a W-process. WineDbg will exit (this may |
| 1204 | be changed later on) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1205 | </screen> |
| 1206 | <screen> |
| 1207 | help prints some help on the commands |
| 1208 | help info prints some help on info commands |
| 1209 | </screen> |
| 1210 | <screen> |
| 1211 | mode 16 switch to 16 bit mode |
| 1212 | mode 32 switch to 32 bit mode |
| 1213 | </screen> |
| 1214 | </sect2> |
| 1215 | |
| 1216 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1217 | <title>Flow control</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1218 | |
| 1219 | <screen> |
| 1220 | cont continue execution until next breakpoint or exception. |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1221 | pass pass the exception event up to the filter chain. |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1222 | step continue execution until next C line of code (enters |
| 1223 | function call) |
| 1224 | next continue execution until next C line of code (doesn't |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1225 | enter function call) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1226 | stepi execute next assembly instruction (enters function |
| 1227 | call) |
| 1228 | nexti execute next assembly instruction (doesn't enter |
| 1229 | function call) |
| 1230 | finish do nexti commands until current function is exited |
| 1231 | </screen> |
| 1232 | <para> |
| 1233 | cont, step, next, stepi, nexti can be postfixed by a |
| 1234 | number (N), meaning that the command must be executed N |
| 1235 | times. |
| 1236 | </para> |
| 1237 | </sect2> |
| 1238 | |
| 1239 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1240 | <title>Breakpoints, watch points</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1241 | |
| 1242 | <screen> |
| 1243 | enable N enables (break|watch)point #N |
| 1244 | disable N disables (break|watch)point #N |
| 1245 | delete N deletes (break|watch)point #N |
| 1246 | cond N removes any a existing condition to (break|watch)point N |
| 1247 | cond N <expr> adds condition <expr> to (break|watch)point N. <expr> |
| 1248 | will be evaluated each time the breakpoint is hit. If |
| 1249 | the result is a zero value, the breakpoint isn't |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1250 | triggered |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1251 | break * N adds a breakpoint at address N |
| 1252 | break <id> adds a breakpoint at the address of symbol <id> |
| 1253 | break <id> N adds a breakpoint at the address of symbol <id> (N ?) |
| 1254 | break N adds a breakpoint at line N of current source file |
| 1255 | break adds a breakpoint at current $pc address |
| 1256 | watch * N adds a watch command (on write) at address N (on 4 bytes) |
| 1257 | watch <id> adds a watch command (on write) at the address of |
| 1258 | symbol <id> |
| 1259 | info break lists all (break|watch)points (with state) |
| 1260 | </screen> |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1261 | <para> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1262 | When setting a breakpoint on an <id>, if several symbols with this |
| 1263 | <id> exist, the debugger will prompt for the symbol you want to use. |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1264 | Pick up the one you want from its number. |
| 1265 | </para> |
Bill Medland | dea2952 | 2002-01-12 21:15:36 +0000 | [diff] [blame] | 1266 | <para> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1267 | Alternatively you can specify a DLL in the <id> (for example |
Bill Medland | dea2952 | 2002-01-12 21:15:36 +0000 | [diff] [blame] | 1268 | MYDLL.DLL.myFunc for function myFunc of |
| 1269 | <filename>G:\AnyPath\MyDll.dll)</filename>. |
| 1270 | </para> |
| 1271 | <para> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1272 | You can use the symbol <emphasis>EntryPoint</emphasis> to stand for |
Bill Medland | dea2952 | 2002-01-12 21:15:36 +0000 | [diff] [blame] | 1273 | the entry point of the Dll. |
| 1274 | </para> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1275 | <para> |
| 1276 | When setting a break/watch-point by <id>, if the symbol cannot be found (for example, the symbol is contained in a not yet loaded module), winedbg will |
| 1277 | recall the name of the symbol and will try to set the breakpoint each time a new module is loaded (until it succeeds). |
| 1278 | </para> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1279 | </sect2> |
| 1280 | |
| 1281 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1282 | <title>Stack manipulation</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1283 | |
| 1284 | <screen> |
| 1285 | bt print calling stack of current thread |
Eric Pouech | 800773f | 2001-08-06 17:51:52 +0000 | [diff] [blame] | 1286 | bt N print calling stack of thread of ID N (note: this |
| 1287 | doesn't change the position of the current frame as |
| 1288 | manipulated by the up & dn commands) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1289 | up goes up one frame in current thread's stack |
| 1290 | up N goes up N frames in current thread's stack |
| 1291 | dn goes down one frame in current thread's stack |
| 1292 | dn N goes down N frames in current thread's stack |
Eric Pouech | 800773f | 2001-08-06 17:51:52 +0000 | [diff] [blame] | 1293 | frame N set N as the current frame for current thread's stack |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1294 | info local prints information on local variables for current |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1295 | function |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1296 | </screen> |
| 1297 | </sect2> |
| 1298 | |
| 1299 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1300 | <title>Directory & source file manipulation</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1301 | |
| 1302 | <screen> |
| 1303 | show dir |
| 1304 | dir <pathname> |
| 1305 | dir |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1306 | symbolfile <pathname> loads external symbol definition |
| 1307 | symbolfile <pathname> N loads external symbol definition |
| 1308 | (applying an offset of N to addresses) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1309 | </screen> |
| 1310 | <screen> |
| 1311 | list lists 10 source lines from current position |
| 1312 | list - lists 10 source lines before current position |
| 1313 | list N lists 10 source lines from line N in current file |
| 1314 | list <path>:N lists 10 source lines from line N in file <path> |
| 1315 | list <id> lists 10 source lines of function <id> |
| 1316 | list * N lists 10 source lines from address N |
| 1317 | </screen> |
| 1318 | <para> |
| 1319 | You can specify the end target (to change the 10 lines |
| 1320 | value) using the ','. For example: |
| 1321 | </para> |
| 1322 | <screen> |
| 1323 | list 123, 234 lists source lines from line 123 up to line 234 in |
| 1324 | current file |
| 1325 | list foo.c:1,56 lists source lines from line 1 up to 56 in file foo.c |
| 1326 | </screen> |
| 1327 | </sect2> |
| 1328 | |
| 1329 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1330 | <title>Displaying</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1331 | |
| 1332 | <para> |
| 1333 | A display is an expression that's evaluated and printed |
| 1334 | after the execution of any <command>WineDbg</command> |
| 1335 | command. |
| 1336 | </para> |
| 1337 | <screen> |
| 1338 | display lists the active displays |
| 1339 | info display (same as above command) |
| 1340 | display <expr> adds a display for expression <expr> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1341 | display /fmt <expr> adds a display for expression <expr>. Printing |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1342 | evaluated <expr> is done using the given format (see |
| 1343 | print command for more on formats) |
| 1344 | del display N deletes display #N |
| 1345 | undisplay N (same as del display) |
| 1346 | </screen> |
| 1347 | </sect2> |
| 1348 | |
| 1349 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1350 | <title>Disassembly</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1351 | |
| 1352 | <screen> |
| 1353 | disas disassemble from current position |
| 1354 | disas <expr> disassemble from address <expr> |
| 1355 | disas <expr>,<expr>disassembles code between addresses specified by |
| 1356 | the two <expr> |
| 1357 | </screen> |
| 1358 | </sect2> |
| 1359 | |
| 1360 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1361 | <title>Information on Wine's internals</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1362 | |
| 1363 | <screen> |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1364 | info class <id> prints information on Windows's class <id> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1365 | walk class lists all Windows' class registered in Wine |
| 1366 | info share lists all the dynamic libraries loaded the debugged |
| 1367 | program (including .so files, NE and PE DLLs) |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1368 | info module <N> prints information on module of handle <N> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1369 | walk module lists all modules loaded by debugged program |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1370 | info regs prints the value of CPU register |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1371 | info segment <N>prints information on segment <N> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1372 | info segment lists all allocated segments |
| 1373 | info stack prints the values on top of the stack |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1374 | walk map lists all virtual mappings used by the debugged |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1375 | program |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1376 | walk map <N> lists all virtual mappings used by the program of pid <N> |
| 1377 | info wnd <N> prints information of Window of handle <N> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1378 | walk wnd lists all the window hierarchy starting from the |
| 1379 | desktop window |
Eric Pouech | 45adf08 | 2003-01-30 00:24:18 +0000 | [diff] [blame] | 1380 | walk wnd <N> lists all the window hierarchy starting from the |
| 1381 | window of handle <N> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1382 | walk process lists all w-processes in Wine session |
| 1383 | walk thread lists all w-threads in Wine session |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1384 | walk exception lists the exception frames (starting from current |
| 1385 | stack frame) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1386 | </screen> |
| 1387 | </sect2> |
| 1388 | |
| 1389 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1390 | <title>Memory (reading, writing, typing)</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1391 | |
| 1392 | <screen> |
| 1393 | x <expr> examines memory at <expr> address |
| 1394 | x /fmt <expr> examines memory at <expr> address using format /fmt |
| 1395 | print <expr> prints the value of <expr> (possibly using its type) |
| 1396 | print /fmt <expr> prints the value of <expr> (possibly using its |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1397 | type) |
| 1398 | set <lval>=<expr> writes the value of <expr> in <lval> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1399 | whatis <expr> prints the C type of expression <expr> |
| 1400 | </screen> |
| 1401 | <para> |
| 1402 | <filename>/fmt</filename> is either <filename>/<letter></filename> or |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1403 | <filename>/<count><letter></filename> letter can be |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1404 | </para> |
| 1405 | <screen> |
| 1406 | s => an ASCII string |
| 1407 | u => an Unicode UTF16 string |
| 1408 | i => instructions (disassemble) |
| 1409 | x => 32 bit unsigned hexadecimal integer |
| 1410 | d => 32 bit signed decimal integer |
| 1411 | w => 16 bit unsigned hexadecimal integer |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 1412 | c => character (only printable 0x20-0x7f are actually printed) |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1413 | b => 8 bit unsigned hexadecimal integer |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1414 | g => GUID |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1415 | </screen> |
| 1416 | </sect2> |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1417 | |
| 1418 | <sect2> |
| 1419 | <title>Expressions</title> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1420 | |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1421 | <para> |
| 1422 | Expressions in Wine Debugger are mostly written in a C form. However, there |
| 1423 | are a few discrepancies: |
| 1424 | <itemizedlist> |
| 1425 | <listitem> |
| 1426 | <para> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1427 | Identifiers can take a '.' in their names. This allow |
| 1428 | mainly to access symbols from different DLLs like |
| 1429 | <function>USER32.DLL.CreateWindowA</function>. |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1430 | </para> |
| 1431 | </listitem> |
| 1432 | <listitem> |
| 1433 | <para> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1434 | The debugger will try to distinguish this writing with structure operations. |
Eric Pouech | 38f2be4 | 2001-08-15 17:40:31 +0000 | [diff] [blame] | 1435 | Therefore, you can only use the previous writing in operations manipulating |
| 1436 | symbols ({break|watch}points, type information command...). |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1437 | </para> |
| 1438 | </listitem> |
| 1439 | </itemizedlist> |
| 1440 | </para> |
| 1441 | </sect2> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1442 | <sect2> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1443 | <title>Debug channels</title> |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1444 | <para> |
Francois Gouget | c5f775a | 2003-06-18 03:30:39 +0000 | [diff] [blame] | 1445 | It is possible to turn on and off debug messages as you are debugging using |
Tony Lambregts | 019c591 | 2002-07-03 01:20:46 +0000 | [diff] [blame] | 1446 | the set command. |
| 1447 | </para> |
| 1448 | <screen> |
| 1449 | set + warn win => turn on warn on 'win' channel |
| 1450 | set + win => turn on warn/fixme/err/trace on 'win' channel |
| 1451 | set - win => turn off warn/fixme/err/trace on 'win' channel |
| 1452 | set - fixme => turn off the 'fixme' class |
| 1453 | </screen> |
| 1454 | </sect2> |
Eric Pouech | 36eed03 | 2001-05-03 18:32:07 +0000 | [diff] [blame] | 1455 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1456 | </sect1> |
| 1457 | |
| 1458 | <sect1 id="dbg-others"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1459 | <title>Other debuggers</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1460 | |
| 1461 | <sect2> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1462 | <title>GDB mode</title> |
| 1463 | |
| 1464 | <para> |
| 1465 | WineDbg can act as a remote monitor for GDB. This allows to |
| 1466 | use all the power of GDB, but while debugging wine and/or |
| 1467 | any Win32 application. To enable this mode, just add |
| 1468 | <parameter>--gdb</parameter> to winedbg command line. You'll |
| 1469 | end up on a GDB prompt. You'll have to use the GDB commands |
| 1470 | (not the wine nes). |
| 1471 | </para> |
| 1472 | |
| 1473 | <para> |
| 1474 | However, some limitation in GDB while debugging wine (see |
Tom Wickline | c28575e | 2003-07-09 19:50:14 +0000 | [diff] [blame] | 1475 | below) don't appear in this mode: |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1476 | <itemizedlist> |
| 1477 | <listitem> |
| 1478 | <para> |
| 1479 | GDB will correctly present Win32 thread |
| 1480 | information and breakpoint behavior |
| 1481 | </para> |
| 1482 | </listitem> |
| 1483 | <listitem> |
| 1484 | <para> |
| 1485 | Moreover, it also provides support for the Dwarf II |
| 1486 | debug format (which became the default format (instead |
| 1487 | of stabs) in gcc 3.1). |
| 1488 | </para> |
| 1489 | </listitem> |
| 1490 | </itemizedlist> |
| 1491 | </para> |
| 1492 | |
| 1493 | <para> |
| 1494 | A few wine extensions available through the monitor command. |
| 1495 | <screen> |
| 1496 | monitor wnd lists all window in the Wine session |
| 1497 | monitor proc lists all processes in the Wine session |
| 1498 | monitor mem displays memory mapping of debugged process |
| 1499 | (doesn't work) |
| 1500 | </screen> |
| 1501 | </para> |
| 1502 | </sect2> |
| 1503 | |
| 1504 | <sect2> |
Eric Pouech | 0a970ce | 2003-06-20 21:27:27 +0000 | [diff] [blame] | 1505 | <title>Graphical frontends to gdb</title> |
| 1506 | |
| 1507 | <para> |
| 1508 | This section will describe how you can debug wine using the |
| 1509 | GDB mode of winedbg and some graphical front ends to GDB for |
| 1510 | those of you who really like graphical debuggers. |
| 1511 | </para> |
| 1512 | |
| 1513 | <sect3> |
| 1514 | <title>DDD</title> |
| 1515 | |
| 1516 | <para> |
| 1517 | Use the following steps, in this order: |
| 1518 | <orderedlist> |
| 1519 | <listitem> |
| 1520 | <para> |
| 1521 | Start the wine debugger with a command line |
| 1522 | like: |
| 1523 | <screen> |
| 1524 | winedbg -- --gdb --no-start <name_of_exe_to_debug.exe> |
| 1525 | </screen> |
| 1526 | </para> |
| 1527 | </listitem> |
| 1528 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1529 | <para> |
| 1530 | Start ddd |
| 1531 | </para> |
Eric Pouech | 0a970ce | 2003-06-20 21:27:27 +0000 | [diff] [blame] | 1532 | </listitem> |
| 1533 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1534 | <para> |
| 1535 | In ddd, use the 'Open File' or 'Open Program' to |
| 1536 | point to the wine executable |
| 1537 | </para> |
Eric Pouech | 0a970ce | 2003-06-20 21:27:27 +0000 | [diff] [blame] | 1538 | </listitem> |
| 1539 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1540 | <para> |
| 1541 | In the output of 1/, there's a line like |
Eric Pouech | 0a970ce | 2003-06-20 21:27:27 +0000 | [diff] [blame] | 1542 | <screen> |
| 1543 | target remote localhost:32878 |
| 1544 | </screen> |
| 1545 | copy that line and paste into ddd command pane (the one with the (gdb) |
| 1546 | prompt) |
| 1547 | </para> |
| 1548 | </listitem> |
| 1549 | </orderedlist> |
| 1550 | The program should now be loaded and up and running. If you want, you |
| 1551 | can also add in 1/ after the name of the exec all the needed |
| 1552 | parameters |
| 1553 | </para> |
| 1554 | </sect3> |
| 1555 | <sect3> |
| 1556 | <title>kdbg</title> |
| 1557 | |
| 1558 | <para> |
| 1559 | Use the following steps, in this order: |
| 1560 | <orderedlist> |
| 1561 | <listitem> |
| 1562 | <para> |
| 1563 | Start the wine debugger with a command line like: |
| 1564 | <screen> |
| 1565 | winedbg -- --gdb --no-start <name_of_exe_to_debug.exe> |
| 1566 | </screen> |
| 1567 | </para> |
| 1568 | </listitem> |
| 1569 | <listitem> |
Vincent Béron | b940e37 | 2003-07-21 22:42:50 +0000 | [diff] [blame] | 1570 | <para> |
| 1571 | In the output of 1/, there's a line like |
Eric Pouech | 0a970ce | 2003-06-20 21:27:27 +0000 | [diff] [blame] | 1572 | <screen> |
| 1573 | target remote localhost:32878 |
| 1574 | </screen> |
| 1575 | Start kdbg with |
| 1576 | <screen> |
| 1577 | kdbg -r localhost:32878 wine |
| 1578 | </screen> |
| 1579 | localhost:32878 is not a fixed value, but has been printed in step |
| 1580 | 1/. 'wine' should also be the full path to the wine executable. |
| 1581 | </para> |
| 1582 | </listitem> |
| 1583 | </orderedlist> |
| 1584 | The program should now be loaded and up and running. If you want, you |
| 1585 | can also add in 1/ after the name of the exec all the needed |
| 1586 | parameters |
| 1587 | </para> |
| 1588 | </sect3> |
| 1589 | </sect2> |
| 1590 | |
| 1591 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1592 | <title>Using other Unix debuggers</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1593 | |
| 1594 | <para> |
| 1595 | You can also use other debuggers (like |
| 1596 | <command>gdb</command>), but you must be aware of a few |
| 1597 | items: |
| 1598 | </para> |
| 1599 | <para> |
| 1600 | You need to attach the unix debugger to the correct unix |
| 1601 | process (representing the correct windows thread) (you can |
| 1602 | "guess" it from a <command>ps fax</command> for example: |
| 1603 | When running the emulator, usually the first two |
| 1604 | <varname>upids</varname> are for the Windows' application |
| 1605 | running the desktop, the first thread of the application is |
| 1606 | generally the third <varname>upid</varname>; when running a |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1607 | Winelib program, the first thread of the application is |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1608 | generally the first <varname>upid</varname>) |
| 1609 | </para> |
| 1610 | <note> |
| 1611 | <para> |
| 1612 | Even if latest <command>gdb</command> implements the |
| 1613 | notion of threads, it won't work with Wine because the |
| 1614 | thread abstraction used for implementing Windows' thread |
Andreas Mohr | 56e6cd0 | 2003-04-01 03:26:13 +0000 | [diff] [blame] | 1615 | is not 100% mapped onto the Linux POSIX threads |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1616 | implementation. It means that you'll have to spawn a |
| 1617 | different <command>gdb</command> session for each Windows' |
| 1618 | thread you wish to debug. |
| 1619 | </para> |
| 1620 | </note> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1621 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1622 | <para> |
| 1623 | Here's how to get info about the current execution status of a |
| 1624 | certain Wine process: |
| 1625 | </para> |
| 1626 | <para> |
| 1627 | Change into your Wine source dir and enter: |
| 1628 | </para> |
| 1629 | <screen> |
| 1630 | $ gdb wine |
| 1631 | </screen> |
| 1632 | <para> |
| 1633 | Switch to another console and enter <command>ps ax | grep |
| 1634 | wine</command> to find all wine processes. Inside |
| 1635 | <command>gdb</command>, repeat for all Wine processes: |
| 1636 | </para> |
| 1637 | <screen> |
| 1638 | (gdb) attach <userinput>PID</userinput> |
| 1639 | </screen> |
| 1640 | <para> |
| 1641 | with <userinput>PID</userinput> being the process ID of one of |
| 1642 | the Wine processes. Use |
| 1643 | </para> |
| 1644 | <screen> |
| 1645 | (gdb) bt |
| 1646 | </screen> |
| 1647 | <para> |
| 1648 | to get the backtrace of the current Wine process, i.e. the |
| 1649 | function call history. That way you can find out what the |
| 1650 | current process is doing right now. And then you can use |
| 1651 | several times: |
| 1652 | </para> |
| 1653 | <screen> |
| 1654 | (gdb) n |
| 1655 | </screen> |
| 1656 | <para> |
| 1657 | or maybe even |
| 1658 | </para> |
| 1659 | <screen> |
| 1660 | (gdb) b <userinput>SomeFunction</userinput> |
| 1661 | </screen> |
| 1662 | <para> |
| 1663 | and |
| 1664 | </para> |
| 1665 | <screen> |
| 1666 | (gdb) c |
| 1667 | </screen> |
| 1668 | <para> |
| 1669 | to set a breakpoint at a certain function and continue up to |
| 1670 | that function. Finally you can enter |
| 1671 | </para> |
| 1672 | <screen> |
| 1673 | (gdb) detach |
| 1674 | </screen> |
| 1675 | <para> |
| 1676 | to detach from the Wine process. |
| 1677 | </para> |
| 1678 | <!-- *** End of xtra content *** --> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1679 | </sect2> |
| 1680 | |
| 1681 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1682 | <title>Using other Windows debuggers</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1683 | |
| 1684 | <para> |
| 1685 | You can use any Windows' debugging API compliant debugger |
| 1686 | with Wine. Some reports have been made of success with |
| 1687 | VisualStudio debugger (in remote mode, only the hub runs |
| 1688 | in Wine). GoVest fully runs in Wine. |
| 1689 | </para> |
| 1690 | </sect2> |
| 1691 | |
| 1692 | <sect2> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1693 | <title>Main differences between winedbg and regular Unix debuggers</title> |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1694 | <table><title>Debuggers comparison</title> |
| 1695 | <tgroup cols=2 align="left"> |
| 1696 | <tbody> |
| 1697 | <row> |
| 1698 | <entry>WineDbg</entry><entry>gdb</entry> |
| 1699 | </row> |
| 1700 | <row> |
| 1701 | <entry> |
| 1702 | WineDbg debugs a Windows' process: the various |
| 1703 | threads will be handled by the same WineDbg session, |
| 1704 | and a breakpoint will be triggered for any thread of |
| 1705 | the W-process |
| 1706 | </entry> |
| 1707 | <entry> |
| 1708 | gdb debugs a Windows' thread: a separate gdb session |
| 1709 | is needed for each thread of a Windows' process and |
| 1710 | a breakpoint will be triggered only for the w-thread |
| 1711 | debugged |
| 1712 | </entry> |
| 1713 | </row> |
| 1714 | <row> |
| 1715 | <entry> |
| 1716 | WineDbg supports debug information from stabs |
| 1717 | (standard Unix format) and Microsoft's C, CodeView, |
| 1718 | .DBG |
| 1719 | </entry> |
| 1720 | <entry> |
| 1721 | GDB supports debug information from stabs (standard |
| 1722 | Unix format) and Dwarf II. |
| 1723 | </entry> |
| 1724 | </row> |
| 1725 | </tbody> |
| 1726 | </tgroup> |
| 1727 | </table> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1728 | </sect2> |
| 1729 | </sect1> |
| 1730 | |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1731 | |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1732 | <sect1 id="dbg-limits"> |
John R. Sheets | d9e064f | 2000-12-13 21:52:37 +0000 | [diff] [blame] | 1733 | <title>Limitations</title> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1734 | |
Eric Pouech | 0996541 | 2002-09-21 01:17:32 +0000 | [diff] [blame] | 1735 | <itemizedlist> |
| 1736 | <listitem> |
| 1737 | <para> |
| 1738 | 16 bit processes are not supported (but calls to 16 bit |
| 1739 | code in 32 bit applications are). |
| 1740 | </para> |
| 1741 | </listitem> |
| 1742 | <listitem> |
| 1743 | <para> |
| 1744 | Function call in expression is no longer supported |
| 1745 | </para> |
| 1746 | </listitem> |
| 1747 | </itemizedlist> |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1748 | </sect1> |
| 1749 | </chapter> |
| 1750 | |
| 1751 | <!-- Keep this comment at the end of the file |
| 1752 | Local variables: |
| 1753 | mode: sgml |
Dimitrie O. Paun | 255ecc5 | 2003-04-19 02:50:57 +0000 | [diff] [blame] | 1754 | sgml-parent-document:("wine-devel.sgml" "set" "book" "part" "chapter" "") |
John R. Sheets | 1e8e5ba | 2000-08-08 01:24:00 +0000 | [diff] [blame] | 1755 | End: |
| 1756 | --> |