winedbg: Bring usage() and .man up to date.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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->next_bp = 1;  /* breakpoint 0 is reserved for step-over */
291     memset(p->bp, 0, sizeof(p->bp));
292     p->delayed_bp = NULL;
293     p->num_delayed_bp = 0;
294
295     p->next = dbg_process_list;
296     p->prev = NULL;
297     if (dbg_process_list) dbg_process_list->prev = p;
298     dbg_process_list = p;
299     return p;
300 }
301
302 void dbg_set_process_name(struct dbg_process* p, const char* imageName)
303 {
304     assert(p->imageName == NULL);
305     if (imageName)
306     {
307         char* tmp = HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1);
308         if (tmp) p->imageName = strcpy(tmp, imageName);
309     }
310 }
311
312 void dbg_del_process(struct dbg_process* p)
313 {
314     int i;
315
316     while (p->threads) dbg_del_thread(p->threads);
317
318     for (i = 0; i < p->num_delayed_bp; i++)
319         if (p->delayed_bp[i].is_symbol)
320             HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name);
321
322     HeapFree(GetProcessHeap(), 0, p->delayed_bp);
323     if (p->prev) p->prev->next = p->next;
324     if (p->next) p->next->prev = p->prev;
325     if (p == dbg_process_list) dbg_process_list = p->next;
326     if (p == dbg_curr_process) dbg_curr_process = NULL;
327     HeapFree(GetProcessHeap(), 0, (char*)p->imageName);
328     HeapFree(GetProcessHeap(), 0, p);
329 }
330
331 struct mod_loader_info
332 {
333     HANDLE              handle;
334     IMAGEHLP_MODULE*    imh_mod;
335 };
336
337 static BOOL CALLBACK mod_loader_cb(PSTR mod_name, DWORD base, void* ctx)
338 {
339     struct mod_loader_info*     mli = (struct mod_loader_info*)ctx;
340
341     if (!strcmp(mod_name, "<wine-loader>"))
342     {
343         if (SymGetModuleInfo(mli->handle, base, mli->imh_mod))
344             return FALSE; /* stop enum */
345     }
346     return TRUE;
347 }
348
349 BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod)
350 {
351     struct mod_loader_info  mli;
352     DWORD                   opt;
353
354     /* this will resynchronize builtin dbghelp's internal ELF module list */
355     SymLoadModule(hProcess, 0, 0, 0, 0, 0);
356     mli.handle  = hProcess;
357     mli.imh_mod = imh_mod;
358     imh_mod->SizeOfStruct = sizeof(*imh_mod);
359     imh_mod->BaseOfImage = 0;
360     /* this is a wine specific options to return also ELF modules in the
361      * enumeration
362      */
363     SymSetOptions((opt = SymGetOptions()) | 0x40000000);
364     SymEnumerateModules(hProcess, mod_loader_cb, (void*)&mli);
365     SymSetOptions(opt);
366
367     return imh_mod->BaseOfImage != 0;
368 }
369
370 struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid)
371 {
372     struct dbg_thread*  t;
373
374     if (!p) return NULL;
375     for (t = p->threads; t; t = t->next)
376         if (t->tid == tid) break;
377     return t;
378 }
379
380 struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
381                                   HANDLE h, void* teb)
382 {
383     struct dbg_thread*  t = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_thread));
384
385     if (!t)
386         return NULL;
387
388     t->handle = h;
389     t->tid = tid;
390     t->teb = teb;
391     t->process = p;
392     t->exec_mode = dbg_exec_cont;
393     t->exec_count = 0;
394     t->step_over_bp.enabled = FALSE;
395     t->step_over_bp.refcount = 0;
396     t->stopped_xpoint = -1;
397     t->in_exception = FALSE;
398     t->frames = NULL;
399     t->num_frames = 0;
400     t->curr_frame = -1;
401     t->addr_mode = AddrModeFlat;
402
403     snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
404
405     t->next = p->threads;
406     t->prev = NULL;
407     if (p->threads) p->threads->prev = t;
408     p->threads = t;
409
410     return t;
411 }
412
413 void dbg_del_thread(struct dbg_thread* t)
414 {
415     HeapFree(GetProcessHeap(), 0, t->frames);
416     if (t->prev) t->prev->next = t->next;
417     if (t->next) t->next->prev = t->prev;
418     if (t == t->process->threads) t->process->threads = t->next;
419     if (t == dbg_curr_thread) dbg_curr_thread = NULL;
420     HeapFree(GetProcessHeap(), 0, t);
421 }
422
423 BOOL dbg_interrupt_debuggee(void)
424 {
425     if (!dbg_process_list) return FALSE;
426     /* FIXME: since we likely have a single process, signal the first process
427      * in list
428      */
429     if (dbg_process_list->next) dbg_printf("Ctrl-C: only stopping the first process\n");
430     else dbg_printf("Ctrl-C: stopping debuggee\n");
431     dbg_process_list->continue_on_first_exception = FALSE;
432     return DebugBreakProcess(dbg_process_list->handle);
433 }
434
435 static BOOL WINAPI ctrl_c_handler(DWORD dwCtrlType)
436 {
437     if (dwCtrlType == CTRL_C_EVENT)
438     {
439         return dbg_interrupt_debuggee();
440     }
441     return FALSE;
442 }
443
444 static void dbg_init_console(void)
445 {
446     /* set our control-C handler */
447     SetConsoleCtrlHandler(ctrl_c_handler, TRUE);
448
449     /* set our own title */
450     SetConsoleTitle("Wine Debugger");
451 }
452
453 static int dbg_winedbg_usage(BOOL advanced)
454 {
455     if (advanced)
456     {
457     dbg_printf("Usage:\n"
458                "   winedbg cmdline         launch process 'cmdline' (as if you were starting\n"
459                "                           it with wine) and run WineDbg on it\n"
460                "   winedbg <num>           attach to running process of pid <num> and run\n"
461                "                           WineDbg on it\n"
462                "   winedbg --gdb cmdline   launch process 'cmdline' (as if you were starting\n"
463                "                           wine) and run gdb (proxied) on it\n"
464                "   winedbg --gdb <num>     attach to running process of pid <num> and run\n"
465                "                           gdb (proxied) on it\n"
466                "   winedbg file.mdmp       reload the minidump file.mdmp into memory and run\n"
467                "                           WineDbg on it\n"
468                "   winedbg --help          prints advanced options\n");
469     }
470     else
471         dbg_printf("Usage:\n\twinedbg [ [ --gdb ] [ prog-name [ prog-args ] | <num> | file.mdmp | --help ]\n");
472     return -1;
473 }
474
475 struct backend_cpu* be_cpu;
476 #ifdef __i386__
477 extern struct backend_cpu be_i386;
478 #elif __powerpc__
479 extern struct backend_cpu be_ppc;
480 #elif __ALPHA__
481 extern struct backend_cpu be_alpha;
482 #else
483 # error CPU unknown
484 #endif
485
486 int main(int argc, char** argv)
487 {
488     int                 retv = 0;
489     HANDLE              hFile = INVALID_HANDLE_VALUE;
490     enum dbg_start      ds;
491
492 #ifdef __i386__
493     be_cpu = &be_i386;
494 #elif __powerpc__
495     be_cpu = &be_ppc;
496 #elif __ALPHA__
497     be_cpu = &be_alpha;
498 #else
499 # error CPU unknown
500 #endif
501     /* Initialize the output */
502     dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);
503
504     /* Initialize internal vars */
505     if (!dbg_load_internal_vars()) return -1;
506
507     /* as we don't care about exec name */
508     argc--; argv++;
509
510     if (argc && !strcmp(argv[0], "--help"))
511         return dbg_winedbg_usage(TRUE);
512
513     if (argc && !strcmp(argv[0], "--gdb"))
514     {
515         retv = gdb_main(argc, argv);
516         if (retv == -1) dbg_winedbg_usage(FALSE);
517         return retv;
518     }
519     dbg_init_console();
520
521     SymSetOptions((SymGetOptions() & ~(SYMOPT_UNDNAME)) |
522                   SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_AUTO_PUBLICS);
523
524     if (argc && (!strcmp(argv[0], "--auto") || !strcmp(argv[0], "--minidump")))
525     {
526         /* force some internal variables */
527         DBG_IVAR(BreakOnDllLoad) = 0;
528         dbg_houtput = GetStdHandle(STD_ERROR_HANDLE);
529         switch (dbg_active_auto(argc, argv))
530         {
531         case start_ok:          return 0;
532         case start_error_parse: return dbg_winedbg_usage(FALSE);
533         case start_error_init:  return -1;
534         }
535     }
536     /* parse options */
537     while (argc > 0 && argv[0][0] == '-')
538     {
539         if (!strcmp(argv[0], "--command"))
540         {
541             argc--; argv++;
542             hFile = parser_generate_command_file(argv[0], NULL);
543             if (hFile == INVALID_HANDLE_VALUE)
544             {
545                 dbg_printf("Couldn't open temp file (%lu)\n", GetLastError());
546                 return 1;
547             }
548             argc--; argv++;
549             continue;
550         }
551         if (!strcmp(argv[0], "--file"))
552         {
553             argc--; argv++;
554             hFile = CreateFileA(argv[0], GENERIC_READ|DELETE, 0, 
555                                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
556             if (hFile == INVALID_HANDLE_VALUE)
557             {
558                 dbg_printf("Couldn't open file %s (%lu)\n", argv[0], GetLastError());
559                 return 1;
560             }
561             argc--; argv++;
562             continue;
563         }
564         if (!strcmp(argv[0], "--"))
565         {
566             argc--; argv++;
567             break;
568         }
569         return dbg_winedbg_usage(FALSE);
570     }
571     if (!argc) ds = start_ok;
572     else if ((ds = dbg_active_attach(argc, argv)) == start_error_parse &&
573              (ds = minidump_reload(argc, argv)) == start_error_parse)
574         ds = dbg_active_launch(argc, argv);
575     switch (ds)
576     {
577     case start_ok:              break;
578     case start_error_parse:     return dbg_winedbg_usage(FALSE);
579     case start_error_init:      return -1;
580     }
581
582     dbg_interactiveP = TRUE;
583     parser_handle(hFile);
584
585     while (dbg_process_list)
586         dbg_process_list->process_io->close_process(dbg_process_list, TRUE);
587
588     dbg_save_internal_vars();
589
590     return 0;
591 }