winedbg: Fixed the auto mode.
[wine] / programs / winedbg / winedbg.c
1 /* Wine internal debugger
2  * Interface to Windows debugger API
3  * Copyright 2000-2004 Eric Pouech
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "config.h"
21 #include "wine/port.h"
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "debugger.h"
27
28 #include "winternl.h"
29 #include "wine/exception.h"
30 #include "wine/library.h"
31
32 #include "wine/debug.h"
33
34 /* TODO list:
35  *
36  * - minidump
37  *      + ensure that all commands work as expected in minidump reload function
38  *        (and reenable parser usager)
39  * - CPU adherence
40  *      + we always assume the stack grows as on i386 (ie downwards)
41  * - UI
42  *      + enable back the limited output (depth of structure printing and number of 
43  *        lines)
44  *      + make the output as close as possible to what gdb does
45  * - symbol management:
46  *      + symbol table loading is broken
47  *      + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
48  *        global vars (we may need this to force some display for example). A solution
49  *        would be always to return arrays with: local vars, global vars, thunks
50  * - type management:
51  *      + some bits of internal types are missing (like type casts and the address
52  *        operator)
53  *      + the type for an enum's value is always inferred as int (winedbg & dbghelp)
54  *      + most of the code implies that sizeof(void*) = sizeof(int)
55  *      + all computations should be made on long long
56  *              o expr computations are in int:s
57  *              o bitfield size is on a 4-bytes
58  *      + array_index and deref should be the same function (or should share the same
59  *        core)
60  * - execution:
61  *      + set a better fix for gdb (proxy mode) than the step-mode hack
62  *      + implement function call in debuggee
63  *      + trampoline management is broken when getting 16 <=> 32 thunk destination
64  *        address
65  *      + thunking of delayed imports doesn't work as expected (ie, when stepping,
66  *        it currently stops at first insn with line number during the library 
67  *        loading). We should identify this (__wine_delay_import) and set a
68  *        breakpoint instead of single stepping the library loading.
69  *      + it's wrong to copy thread->step_over_bp into process->bp[0] (when 
70  *        we have a multi-thread debuggee). complete fix must include storing all
71  *        thread's step-over bp in process-wide bp array, and not to handle bp
72  *        when we have the wrong thread running into that bp
73  *      + code in CREATE_PROCESS debug event doesn't work on Windows, as we cannot
74  *        get the name of the main module this way. We should rewrite all this code
75  *        and store in struct dbg_process as early as possible (before process
76  *        creation or attachment), the name of the main module
77  * - global:
78  *      + define a better way to enable the wine extensions (either DBG SDK function
79  *        in dbghelp, or TLS variable, or environment variable or ...)
80  *      + audit all files to ensure that we check all potential return values from
81  *        every function call to catch the errors
82  *      + BTW check also whether the exception mechanism is the best way to return
83  *        errors (or find a proper fix for MinGW port)
84  *      + use Wine standard list mechanism for all list handling
85  */
86
87 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
88
89 struct dbg_process*     dbg_curr_process = NULL;
90 struct dbg_thread*      dbg_curr_thread = NULL;
91 DWORD                   dbg_curr_tid;
92 DWORD                   dbg_curr_pid;
93 CONTEXT                 dbg_context;
94 BOOL                    dbg_interactiveP = FALSE;
95
96 static struct dbg_process*      dbg_process_list = NULL;
97
98 struct dbg_internal_var         dbg_internal_vars[DBG_IV_LAST];
99 const struct dbg_internal_var*  dbg_context_vars;
100 static HANDLE                   dbg_houtput;
101
102 void    dbg_outputA(const char* buffer, int len)
103 {
104     static char line_buff[4096];
105     static unsigned int line_pos;
106
107     DWORD w, i;
108
109     while (len > 0)
110     {
111         unsigned int count = min( len, sizeof(line_buff) - line_pos );
112         memcpy( line_buff + line_pos, buffer, count );
113         buffer += count;
114         len -= count;
115         line_pos += count;
116         for (i = line_pos; i > 0; i--) if (line_buff[i-1] == '\n') break;
117         if (!i)  /* no newline found */
118         {
119             if (len > 0) i = line_pos;  /* buffer is full, flush anyway */
120             else break;
121         }
122         WriteFile(dbg_houtput, line_buff, i, &w, NULL);
123         memmove( line_buff, line_buff + i, line_pos - i );
124         line_pos -= i;
125     }
126 }
127
128 void    dbg_outputW(const WCHAR* buffer, int len)
129 {
130     char* ansi = NULL;
131     int newlen;
132         
133     /* do a serious Unicode to ANSI conversion
134      * FIXME: should CP_ACP be GetConsoleCP()?
135      */
136     newlen = WideCharToMultiByte(CP_ACP, 0, buffer, len, NULL, 0, NULL, NULL);
137     if (newlen)
138     {
139         if (!(ansi = HeapAlloc(GetProcessHeap(), 0, newlen))) return;
140         WideCharToMultiByte(CP_ACP, 0, buffer, len, ansi, newlen, NULL, NULL);
141         dbg_outputA(ansi, newlen);
142         HeapFree(GetProcessHeap(), 0, ansi);
143     }
144 }
145
146 int     dbg_printf(const char* format, ...)
147 {
148     static    char      buf[4*1024];
149     va_list     valist;
150     int         len;
151
152     va_start(valist, format);
153     len = vsnprintf(buf, sizeof(buf), format, valist);
154     va_end(valist);
155
156     if (len <= -1 || len >= sizeof(buf)) 
157     {
158         len = sizeof(buf) - 1;
159         buf[len] = 0;
160         buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
161     }
162     dbg_outputA(buf, len);
163     return len;
164 }
165
166 static  unsigned dbg_load_internal_vars(void)
167 {
168     HKEY                        hkey;
169     DWORD                       type = REG_DWORD;
170     DWORD                       val;
171     DWORD                       count = sizeof(val);
172     int                         i;
173     struct dbg_internal_var*    div = dbg_internal_vars;
174
175 /* initializes internal vars table */
176 #define  INTERNAL_VAR(_var,_val,_ref,_tid)                      \
177         div->val = _val; div->name = #_var; div->pval = _ref;   \
178         div->typeid = _tid; div++;
179 #include "intvar.h"
180 #undef   INTERNAL_VAR
181
182     /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
183     if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
184     {
185         WINE_ERR("Cannot create WineDbg key in registry\n");
186         return FALSE;
187     }
188
189     for (i = 0; i < DBG_IV_LAST; i++) 
190     {
191         if (!dbg_internal_vars[i].pval) 
192         {
193             if (!RegQueryValueEx(hkey, dbg_internal_vars[i].name, 0,
194                                  &type, (LPBYTE)&val, &count))
195                 dbg_internal_vars[i].val = val;
196             dbg_internal_vars[i].pval = &dbg_internal_vars[i].val;
197         }
198     }
199     RegCloseKey(hkey);
200     /* set up the debug variables for the CPU context */
201     dbg_context_vars = be_cpu->init_registers(&dbg_context);
202     return TRUE;
203 }
204
205 static  unsigned dbg_save_internal_vars(void)
206 {
207     HKEY                        hkey;
208     int                         i;
209
210     /* @@ Wine registry key: HKCU\Software\Wine\WineDbg */
211     if (RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) 
212     {
213         WINE_ERR("Cannot create WineDbg key in registry\n");
214         return FALSE;
215     }
216
217     for (i = 0; i < DBG_IV_LAST; i++) 
218     {
219         /* FIXME: type should be infered from basic type -if any- of intvar */
220         if (dbg_internal_vars[i].pval == &dbg_internal_vars[i].val)
221             RegSetValueEx(hkey, dbg_internal_vars[i].name, 0,
222                           REG_DWORD, (const void*)dbg_internal_vars[i].pval, 
223                           sizeof(*dbg_internal_vars[i].pval));
224     }
225     RegCloseKey(hkey);
226     return TRUE;
227 }
228
229 const struct dbg_internal_var* dbg_get_internal_var(const char* name)
230 {
231     const struct dbg_internal_var*      div;
232
233     for (div = &dbg_internal_vars[DBG_IV_LAST - 1]; div >= dbg_internal_vars; div--)
234     {
235         if (!strcmp(div->name, name)) return div;
236     }
237     for (div = dbg_context_vars; div->name; div++)
238     {
239         if (!strcasecmp(div->name, name)) return div;
240     }
241
242     return NULL;
243 }
244
245 struct dbg_process*     dbg_get_process(DWORD pid)
246 {
247     struct dbg_process* p;
248
249     for (p = dbg_process_list; p; p = p->next)
250         if (p->pid == pid) break;
251     return p;
252 }
253
254 struct dbg_process*     dbg_get_process_h(HANDLE h)
255 {
256     struct dbg_process* p;
257
258     for (p = dbg_process_list; p; p = p->next)
259         if (p->handle == h) break;
260     return p;
261 }
262
263 struct dbg_process*     dbg_add_process(const struct be_process_io* pio, DWORD pid, HANDLE h)
264 {
265     struct dbg_process* p;
266
267     if ((p = dbg_get_process(pid)))
268     {
269         if (p->handle != 0)
270         {
271             WINE_ERR("Process (%lu) is already defined\n", pid);
272         }
273         else
274         {
275             p->handle = h;
276             p->process_io = pio;
277             p->imageName = NULL;
278         }
279         return p;
280     }
281
282     if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
283     p->handle = h;
284     p->pid = pid;
285     p->process_io = pio;
286     p->pio_data = NULL;
287     p->imageName = NULL;
288     p->threads = NULL;
289     p->continue_on_first_exception = FALSE;
290     p->active_debuggee = FALSE;
291     p->next_bp = 1;  /* breakpoint 0 is reserved for step-over */
292     memset(p->bp, 0, sizeof(p->bp));
293     p->delayed_bp = NULL;
294     p->num_delayed_bp = 0;
295
296     p->next = dbg_process_list;
297     p->prev = NULL;
298     if (dbg_process_list) dbg_process_list->prev = p;
299     dbg_process_list = p;
300     return p;
301 }
302
303 void dbg_set_process_name(struct dbg_process* p, const char* imageName)
304 {
305     assert(p->imageName == NULL);
306     if (imageName)
307     {
308         char* tmp = HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1);
309         if (tmp) p->imageName = strcpy(tmp, imageName);
310     }
311 }
312
313 void dbg_del_process(struct dbg_process* p)
314 {
315     int i;
316
317     while (p->threads) dbg_del_thread(p->threads);
318
319     for (i = 0; i < p->num_delayed_bp; i++)
320         if (p->delayed_bp[i].is_symbol)
321             HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name);
322
323     HeapFree(GetProcessHeap(), 0, p->delayed_bp);
324     if (p->prev) p->prev->next = p->next;
325     if (p->next) p->next->prev = p->prev;
326     if (p == dbg_process_list) dbg_process_list = p->next;
327     if (p == dbg_curr_process) dbg_curr_process = NULL;
328     HeapFree(GetProcessHeap(), 0, (char*)p->imageName);
329     HeapFree(GetProcessHeap(), 0, p);
330 }
331
332 struct mod_loader_info
333 {
334     HANDLE              handle;
335     IMAGEHLP_MODULE*    imh_mod;
336 };
337
338 static BOOL CALLBACK mod_loader_cb(PSTR mod_name, DWORD base, void* ctx)
339 {
340     struct mod_loader_info*     mli = (struct mod_loader_info*)ctx;
341
342     if (!strcmp(mod_name, "<wine-loader>"))
343     {
344         if (SymGetModuleInfo(mli->handle, base, mli->imh_mod))
345             return FALSE; /* stop enum */
346     }
347     return TRUE;
348 }
349
350 BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod)
351 {
352     struct mod_loader_info  mli;
353     DWORD                   opt;
354
355     /* this will resynchronize builtin dbghelp's internal ELF module list */
356     SymLoadModule(hProcess, 0, 0, 0, 0, 0);
357     mli.handle  = hProcess;
358     mli.imh_mod = imh_mod;
359     imh_mod->SizeOfStruct = sizeof(*imh_mod);
360     imh_mod->BaseOfImage = 0;
361     /* this is a wine specific options to return also ELF modules in the
362      * enumeration
363      */
364     SymSetOptions((opt = SymGetOptions()) | 0x40000000);
365     SymEnumerateModules(hProcess, mod_loader_cb, (void*)&mli);
366     SymSetOptions(opt);
367
368     return imh_mod->BaseOfImage != 0;
369 }
370
371 struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid)
372 {
373     struct dbg_thread*  t;
374
375     if (!p) return NULL;
376     for (t = p->threads; t; t = t->next)
377         if (t->tid == tid) break;
378     return t;
379 }
380
381 struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
382                                   HANDLE h, void* teb)
383 {
384     struct dbg_thread*  t = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_thread));
385
386     if (!t)
387         return NULL;
388
389     t->handle = h;
390     t->tid = tid;
391     t->teb = teb;
392     t->process = p;
393     t->exec_mode = dbg_exec_cont;
394     t->exec_count = 0;
395     t->step_over_bp.enabled = FALSE;
396     t->step_over_bp.refcount = 0;
397     t->stopped_xpoint = -1;
398     t->in_exception = FALSE;
399     t->frames = NULL;
400     t->num_frames = 0;
401     t->curr_frame = -1;
402     t->addr_mode = AddrModeFlat;
403
404     snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
405
406     t->next = p->threads;
407     t->prev = NULL;
408     if (p->threads) p->threads->prev = t;
409     p->threads = t;
410
411     return t;
412 }
413
414 void dbg_del_thread(struct dbg_thread* t)
415 {
416     HeapFree(GetProcessHeap(), 0, t->frames);
417     if (t->prev) t->prev->next = t->next;
418     if (t->next) t->next->prev = t->prev;
419     if (t == t->process->threads) t->process->threads = t->next;
420     if (t == dbg_curr_thread) dbg_curr_thread = NULL;
421     HeapFree(GetProcessHeap(), 0, t);
422 }
423
424 BOOL dbg_interrupt_debuggee(void)
425 {
426     if (!dbg_process_list) return FALSE;
427     /* FIXME: since we likely have a single process, signal the first process
428      * in list
429      */
430     if (dbg_process_list->next) dbg_printf("Ctrl-C: only stopping the first process\n");
431     else dbg_printf("Ctrl-C: stopping debuggee\n");
432     dbg_process_list->continue_on_first_exception = FALSE;
433     return DebugBreakProcess(dbg_process_list->handle);
434 }
435
436 static BOOL WINAPI ctrl_c_handler(DWORD dwCtrlType)
437 {
438     if (dwCtrlType == CTRL_C_EVENT)
439     {
440         return dbg_interrupt_debuggee();
441     }
442     return FALSE;
443 }
444
445 static void dbg_init_console(void)
446 {
447     /* set our control-C handler */
448     SetConsoleCtrlHandler(ctrl_c_handler, TRUE);
449
450     /* set our own title */
451     SetConsoleTitle("Wine Debugger");
452 }
453
454 static int dbg_winedbg_usage(BOOL advanced)
455 {
456     if (advanced)
457     {
458     dbg_printf("Usage:\n"
459                "   winedbg cmdline         launch process 'cmdline' (as if you were starting\n"
460                "                           it with wine) and run WineDbg on it\n"
461                "   winedbg <num>           attach to running process of pid <num> and run\n"
462                "                           WineDbg on it\n"
463                "   winedbg --gdb cmdline   launch process 'cmdline' (as if you were starting\n"
464                "                           wine) and run gdb (proxied) on it\n"
465                "   winedbg --gdb <num>     attach to running process of pid <num> and run\n"
466                "                           gdb (proxied) on it\n"
467                "   winedbg file.mdmp       reload the minidump file.mdmp into memory and run\n"
468                "                           WineDbg on it\n"
469                "   winedbg --help          prints advanced options\n");
470     }
471     else
472         dbg_printf("Usage:\n\twinedbg [ [ --gdb ] [ prog-name [ prog-args ] | <num> | file.mdmp | --help ]\n");
473     return -1;
474 }
475
476 struct backend_cpu* be_cpu;
477 #ifdef __i386__
478 extern struct backend_cpu be_i386;
479 #elif __powerpc__
480 extern struct backend_cpu be_ppc;
481 #elif __ALPHA__
482 extern struct backend_cpu be_alpha;
483 #elif __x86_64__
484 extern struct backend_cpu be_x86_64;
485 #else
486 # error CPU unknown
487 #endif
488
489 int main(int argc, char** argv)
490 {
491     int                 retv = 0;
492     HANDLE              hFile = INVALID_HANDLE_VALUE;
493     enum dbg_start      ds;
494
495 #ifdef __i386__
496     be_cpu = &be_i386;
497 #elif __powerpc__
498     be_cpu = &be_ppc;
499 #elif __ALPHA__
500     be_cpu = &be_alpha;
501 #elif __x86_64__
502     be_cpu = &be_x86_64;
503 #else
504 # error CPU unknown
505 #endif
506     /* Initialize the output */
507     dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);
508
509     /* Initialize internal vars */
510     if (!dbg_load_internal_vars()) return -1;
511
512     /* as we don't care about exec name */
513     argc--; argv++;
514
515     if (argc && !strcmp(argv[0], "--help"))
516         return dbg_winedbg_usage(TRUE);
517
518     if (argc && !strcmp(argv[0], "--gdb"))
519     {
520         retv = gdb_main(argc, argv);
521         if (retv == -1) dbg_winedbg_usage(FALSE);
522         return retv;
523     }
524     dbg_init_console();
525
526     SymSetOptions((SymGetOptions() & ~(SYMOPT_UNDNAME)) |
527                   SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS);
528
529     if (argc && (!strcmp(argv[0], "--auto") || !strcmp(argv[0], "--minidump")))
530     {
531         /* force some internal variables */
532         DBG_IVAR(BreakOnDllLoad) = 0;
533         dbg_houtput = GetStdHandle(STD_ERROR_HANDLE);
534         switch (dbg_active_auto(argc, argv))
535         {
536         case start_ok:          return 0;
537         case start_error_parse: return dbg_winedbg_usage(FALSE);
538         case start_error_init:  return -1;
539         }
540     }
541     /* parse options */
542     while (argc > 0 && argv[0][0] == '-')
543     {
544         if (!strcmp(argv[0], "--command"))
545         {
546             argc--; argv++;
547             hFile = parser_generate_command_file(argv[0], NULL);
548             if (hFile == INVALID_HANDLE_VALUE)
549             {
550                 dbg_printf("Couldn't open temp file (%lu)\n", GetLastError());
551                 return 1;
552             }
553             argc--; argv++;
554             continue;
555         }
556         if (!strcmp(argv[0], "--file"))
557         {
558             argc--; argv++;
559             hFile = CreateFileA(argv[0], GENERIC_READ|DELETE, 0, 
560                                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
561             if (hFile == INVALID_HANDLE_VALUE)
562             {
563                 dbg_printf("Couldn't open file %s (%lu)\n", argv[0], GetLastError());
564                 return 1;
565             }
566             argc--; argv++;
567             continue;
568         }
569         if (!strcmp(argv[0], "--"))
570         {
571             argc--; argv++;
572             break;
573         }
574         return dbg_winedbg_usage(FALSE);
575     }
576     if (!argc) ds = start_ok;
577     else if ((ds = dbg_active_attach(argc, argv)) == start_error_parse &&
578              (ds = minidump_reload(argc, argv)) == start_error_parse)
579         ds = dbg_active_launch(argc, argv);
580     switch (ds)
581     {
582     case start_ok:              break;
583     case start_error_parse:     return dbg_winedbg_usage(FALSE);
584     case start_error_init:      return -1;
585     }
586
587     if (dbg_curr_process)
588     {
589         dbg_printf("WineDbg starting on pid 0x%lx\n", dbg_curr_pid);
590         if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception();
591     }
592
593     dbg_interactiveP = TRUE;
594     parser_handle(hFile);
595
596     while (dbg_process_list)
597         dbg_process_list->process_io->close_process(dbg_process_list, TRUE);
598
599     dbg_save_internal_vars();
600
601     return 0;
602 }