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