* gdb.base/call-ar-st.exp: Relax patterns matching tab characters.
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
CommitLineData
c906108c 1/* Target-vector operations for controlling win32 child processes, for GDB.
e6433c28
CF
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
c906108c
SS
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
c5aa993b
JM
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21 */
c906108c
SS
22
23/* by Steve Chamberlain, sac@cygnus.com */
24
25/* We assume we're being built with and will be used for cygwin. */
26
27#include "defs.h"
28#include "frame.h" /* required by inferior.h */
29#include "inferior.h"
30#include "target.h"
c906108c
SS
31#include "gdbcore.h"
32#include "command.h"
33#include <signal.h>
34#include <sys/types.h>
35#include <fcntl.h>
36#include <stdlib.h>
37
38#ifdef _MSC_VER
39#include "windefs.h"
40#else /* other WIN32 compiler */
41#include <windows.h>
c2d11a7d 42#include <imagehlp.h>
c906108c
SS
43#endif
44
45#include "buildsym.h"
46#include "symfile.h"
47#include "objfiles.h"
48#include "gdb_string.h"
49#include "gdbthread.h"
50#include "gdbcmd.h"
51#include <sys/param.h>
c2d11a7d 52#include <unistd.h>
c906108c 53
7a292a7a
SS
54/* The ui's event loop. */
55extern int (*ui_loop_hook) PARAMS ((int signo));
56
57/* If we're not using the old Cygwin header file set, define the
58 following which never should have been in the generic Win32 API
59 headers in the first place since they were our own invention... */
60#ifndef _GNU_H_WINDOWS_H
61#define FLAG_TRACE_BIT 0x100
62#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
63#endif
64
c906108c
SS
65/* The string sent by cygwin when it processes a signal.
66 FIXME: This should be in a cygwin include file. */
67#define CYGWIN_SIGNAL_STRING "cygwin: signal"
68
69#define CHECK(x) check (x, __FILE__,__LINE__)
70#define DEBUG_EXEC(x) if (debug_exec) printf x
71#define DEBUG_EVENTS(x) if (debug_events) printf x
72#define DEBUG_MEM(x) if (debug_memory) printf x
73#define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
74
75/* Forward declaration */
76extern struct target_ops child_ops;
77
78static void child_stop PARAMS ((void));
79static int win32_child_thread_alive PARAMS ((int));
7a292a7a 80void child_kill_inferior PARAMS ((void));
c906108c 81
c906108c
SS
82/* Thread information structure used to track information that is
83 not available in gdb's thread structure. */
84typedef struct thread_info_struct
c5aa993b
JM
85 {
86 struct thread_info_struct *next;
87 DWORD id;
88 HANDLE h;
89 char *name;
90 int suspend_count;
91 CONTEXT context;
c2d11a7d
JM
92 STACKFRAME sf;
93 } thread_info;
94
95static thread_info thread_head = {NULL};
c906108c 96
c2d11a7d
JM
97/* The saved state for a continue after breaking back to gdb. */
98static DWORD continue_status;
c906108c
SS
99
100/* The process and thread handles for the above context. */
101
102static DEBUG_EVENT current_event; /* The current debug event from
103 WaitForDebugEvent */
104static HANDLE current_process_handle; /* Currently executing process */
105static thread_info *current_thread; /* Info on currently selected thread */
c5aa993b 106static DWORD main_thread_id; /* Thread ID of the main thread */
c906108c
SS
107
108/* Counts of things. */
109static int exception_count = 0;
110static int event_count = 0;
111
112/* User options. */
113static int new_console = 0;
c2d11a7d 114static int new_group = 1;
c5aa993b
JM
115static int debug_exec = 0; /* show execution */
116static int debug_events = 0; /* show events from kernel */
117static int debug_memory = 0; /* show target memory accesses */
c906108c
SS
118static int debug_exceptions = 0; /* show target exceptions */
119
120/* This vector maps GDB's idea of a register's number into an address
121 in the win32 exception context vector.
122
123 It also contains the bit mask needed to load the register in question.
124
125 One day we could read a reg, we could inspect the context we
126 already have loaded, if it doesn't have the bit set that we need,
127 we read that set of registers in using GetThreadContext. If the
128 context already contains what we need, we just unpack it. Then to
129 write a register, first we have to ensure that the context contains
130 the other regs of the group, and then we copy the info in and set
131 out bit. */
132
133#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
134static const int mappings[] =
135{
c5aa993b
JM
136 context_offset (Eax),
137 context_offset (Ecx),
138 context_offset (Edx),
139 context_offset (Ebx),
140 context_offset (Esp),
141 context_offset (Ebp),
142 context_offset (Esi),
143 context_offset (Edi),
144 context_offset (Eip),
145 context_offset (EFlags),
146 context_offset (SegCs),
147 context_offset (SegSs),
148 context_offset (SegDs),
149 context_offset (SegEs),
150 context_offset (SegFs),
151 context_offset (SegGs),
152 context_offset (FloatSave.RegisterArea[0 * 10]),
153 context_offset (FloatSave.RegisterArea[1 * 10]),
154 context_offset (FloatSave.RegisterArea[2 * 10]),
155 context_offset (FloatSave.RegisterArea[3 * 10]),
156 context_offset (FloatSave.RegisterArea[4 * 10]),
157 context_offset (FloatSave.RegisterArea[5 * 10]),
158 context_offset (FloatSave.RegisterArea[6 * 10]),
159 context_offset (FloatSave.RegisterArea[7 * 10]),
c2d11a7d
JM
160 context_offset (FloatSave.ControlWord),
161 context_offset (FloatSave.StatusWord),
162 context_offset (FloatSave.TagWord),
163 context_offset (FloatSave.ErrorSelector),
164 context_offset (FloatSave.ErrorOffset),
165 context_offset (FloatSave.DataSelector),
166 context_offset (FloatSave.DataOffset),
ed9a39eb 167 context_offset (FloatSave.ErrorSelector)
c906108c
SS
168};
169
ed9a39eb
JM
170#undef context_offset
171
c906108c
SS
172/* This vector maps the target's idea of an exception (extracted
173 from the DEBUG_EVENT structure) to GDB's idea. */
174
175struct xlate_exception
176 {
177 int them;
178 enum target_signal us;
179 };
180
181static const struct xlate_exception
182 xlate[] =
183{
184 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
185 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
186 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
187 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
188 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
189 {-1, -1}};
190
191/* Find a thread record given a thread id.
192 If get_context then also retrieve the context for this
193 thread. */
194static thread_info *
195thread_rec (DWORD id, int get_context)
196{
197 thread_info *th;
198
c5aa993b 199 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
200 if (th->id == id)
201 {
202 if (!th->suspend_count && get_context)
203 {
204 if (get_context > 0)
205 th->suspend_count = SuspendThread (th->h) + 1;
206 else if (get_context < 0)
207 th->suspend_count = -1;
208
209 th->context.ContextFlags = CONTEXT_DEBUGGER;
210 GetThreadContext (th->h, &th->context);
211 }
212 return th;
213 }
214
215 return NULL;
216}
217
218/* Add a thread to the thread list */
219static thread_info *
c5aa993b 220child_add_thread (DWORD id, HANDLE h)
c906108c
SS
221{
222 thread_info *th;
223
224 if ((th = thread_rec (id, FALSE)))
225 return th;
226
227 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 228 memset (th, 0, sizeof (*th));
c906108c
SS
229 th->id = id;
230 th->h = h;
231 th->next = thread_head.next;
232 thread_head.next = th;
233 add_thread (id);
234 return th;
235}
236
237/* Clear out any old thread list and reintialize it to a
238 pristine state. */
239static void
240child_init_thread_list ()
241{
242 thread_info *th = &thread_head;
243
244 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
245 init_thread_list ();
246 while (th->next != NULL)
247 {
248 thread_info *here = th->next;
249 th->next = here->next;
250 (void) CloseHandle (here->h);
251 free (here);
252 }
253}
254
255/* Delete a thread from the list of threads */
256static void
257child_delete_thread (DWORD id)
258{
259 thread_info *th;
260
261 if (info_verbose)
262 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
263 delete_thread (id);
264
265 for (th = &thread_head;
266 th->next != NULL && th->next->id != id;
267 th = th->next)
268 continue;
269
270 if (th->next != NULL)
271 {
272 thread_info *here = th->next;
273 th->next = here->next;
274 CloseHandle (here->h);
275 free (here);
276 }
277}
278
279static void
280check (BOOL ok, const char *file, int line)
281{
282 if (!ok)
283 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
284}
285
286static void
287do_child_fetch_inferior_registers (int r)
288{
c2d11a7d
JM
289 char *context_offset = ((char *) &current_thread->context) + mappings[r];
290 long l;
291 if (r == FCS_REGNUM)
292 {
293 l = *((long *)context_offset) & 0xffff;
294 supply_register (r, (char *) &l);
295 }
296 else if (r == FOP_REGNUM)
297 {
298 l = (*((long *)context_offset) >> 16) & ((1 << 11) - 1);
299 supply_register (r, (char *) &l);
300 }
301 else if (r >= 0)
ed9a39eb 302 supply_register (r, context_offset);
c906108c
SS
303 else
304 {
305 for (r = 0; r < NUM_REGS; r++)
306 do_child_fetch_inferior_registers (r);
307 }
308}
309
310static void
311child_fetch_inferior_registers (int r)
312{
313 current_thread = thread_rec (inferior_pid, TRUE);
314 do_child_fetch_inferior_registers (r);
315}
316
317static void
318do_child_store_inferior_registers (int r)
319{
320 if (r >= 0)
321 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
322 else
323 {
324 for (r = 0; r < NUM_REGS; r++)
325 do_child_store_inferior_registers (r);
326 }
327}
328
329/* Store a new register value into the current thread context */
330static void
331child_store_inferior_registers (int r)
332{
333 current_thread = thread_rec (inferior_pid, TRUE);
334 do_child_store_inferior_registers (r);
335}
336
c2d11a7d
JM
337#include <psapi.h>
338static int psapi_loaded = 0;
339static HMODULE psapi_module_handle = NULL;
340static BOOL WINAPI (*psapi_EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD)= NULL;
341static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD)= NULL;
342static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD)= NULL;
343
344int psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
345{
346 DWORD len;
347 MODULEINFO mi;
348 int i;
349 HMODULE dh_buf [ 1 ];
350 HMODULE* DllHandle = dh_buf;
351 DWORD cbNeeded;
352 BOOL ok;
353
354 if (!psapi_loaded ||
355 psapi_EnumProcessModules == NULL ||
356 psapi_GetModuleInformation == NULL ||
357 psapi_GetModuleFileNameExA == NULL)
358 {
359 if (psapi_loaded)goto failed;
360 psapi_loaded = 1;
361 psapi_module_handle = LoadLibrary ("psapi.dll");
362 if (!psapi_module_handle)
363 {
364 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
365 goto failed;
366 }
367 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules" );
368 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
369 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
370 "GetModuleFileNameExA");
371 if (psapi_EnumProcessModules == NULL ||
372 psapi_GetModuleInformation == NULL ||
373 psapi_GetModuleFileNameExA == NULL)
374 goto failed;
375 }
376
377 cbNeeded = 0;
378 ok = (*psapi_EnumProcessModules) (current_process_handle,
379 DllHandle,
380 sizeof (HMODULE),
381 &cbNeeded);
382
383 if (!ok || !cbNeeded)
384 goto failed;
385
386 DllHandle = (HMODULE*) alloca (cbNeeded);
387 if (!DllHandle)
388 goto failed;
389
390 ok = (*psapi_EnumProcessModules) (current_process_handle,
391 DllHandle,
392 cbNeeded,
393 &cbNeeded);
394 if (!ok)
395 goto failed;
396
397 for (i = 0; i < cbNeeded / sizeof (HMODULE); i++)
398 {
399 if (!(*psapi_GetModuleInformation) (current_process_handle,
400 DllHandle [i],
401 &mi,
402 sizeof (mi)))
403 error ("Can't get module info");
404
405 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
406 DllHandle [i],
407 dll_name_ret,
408 MAX_PATH);
409 if (len == 0)
410 error ("Error getting dll name: %u\n", GetLastError ());
411
412 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
413 return 1;
414 }
415
416failed:
417 dll_name_ret[0] = '\0';
418 return 0;
419}
420
c906108c
SS
421/* Wait for child to do something. Return pid of child, or -1 in case
422 of error; store status through argument pointer OURSTATUS. */
423
424static int
425handle_load_dll (PTR dummy)
426{
c5aa993b 427 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c
SS
428 DWORD dll_name_ptr;
429 DWORD done;
430 char dll_buf[MAX_PATH + 1];
7be570e7 431 char *p, *dll_name = NULL;
c906108c
SS
432 struct objfile *objfile;
433 MEMORY_BASIC_INFORMATION minfo;
2acceee2 434 struct section_addr_info section_addrs;
c906108c 435
2acceee2 436 memset (&section_addrs, 0, sizeof (section_addrs));
c5aa993b 437 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 438
c2d11a7d
JM
439 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
440 dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
c906108c 441
c2d11a7d 442 dll_name = dll_buf;
c906108c
SS
443
444 /* Attempt to read the name of the dll that was detected.
445 This is documented to work only when actively debugging
446 a program. It will not work for attached processes. */
447 if (dll_name == NULL || *dll_name == '\0')
448 {
449 int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
450 int len = 0;
451 char b[2];
452
453 ReadProcessMemory (current_process_handle,
454 (LPCVOID) event->lpImageName,
455 (char *) &dll_name_ptr,
456 sizeof (dll_name_ptr), &done);
457
458 /* See if we could read the address of a string, and that the
c5aa993b 459 address isn't null. */
c906108c
SS
460
461 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
462 return 1;
463
464 do
465 {
466 ReadProcessMemory (current_process_handle,
467 (LPCVOID) (dll_name_ptr + len * size),
468 &b,
469 size,
470 &done);
471 len++;
472 }
473 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
474
475 dll_name = alloca (len);
476
477 if (event->fUnicode)
478 {
479 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
480 ReadProcessMemory (current_process_handle,
481 (LPCVOID) dll_name_ptr,
482 unicode_dll_name,
483 len * sizeof (WCHAR),
484 &done);
485
486 WideCharToMultiByte (CP_ACP, 0,
487 unicode_dll_name, len,
488 dll_name, len, 0, 0);
489 }
490 else
491 {
492 ReadProcessMemory (current_process_handle,
493 (LPCVOID) dll_name_ptr,
494 dll_name,
495 len,
496 &done);
497 }
498 }
499
500 if (!dll_name)
501 return 1;
502
503 while ((p = strchr (dll_name, '\\')))
504 *p = '/';
505
c906108c
SS
506 /* The symbols in a dll are offset by 0x1000, which is the
507 the offset from 0 of the first byte in an image - because
508 of the file header and the section alignment.
509
510 FIXME: Is this the real reason that we need the 0x1000 ? */
511
512 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
2acceee2 513 section_addrs.text_addr = (int) event->lpBaseOfDll + 0x1000;
2df3850c 514 symbol_file_add (dll_name, 0, &section_addrs, 0, OBJF_SHARED);
c906108c
SS
515 printf_unfiltered ("\n");
516
c906108c
SS
517 return 1;
518}
519
520/* Handle DEBUG_STRING output from child process.
521 Cygwin prepends its messages with a "cygwin:". Interpret this as
522 a Cygwin signal. Otherwise just print the string as a warning. */
523static int
524handle_output_debug_string (struct target_waitstatus *ourstatus)
525{
526 char *s;
527 int gotasig = FALSE;
528
529 if (!target_read_string
c5aa993b 530 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
531 || !s || !*s)
532 return gotasig;
533
ed9a39eb 534 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
c906108c 535 {
ed9a39eb 536 if (strncmp (s, "cYg", 3) != 0)
c2d11a7d 537 warning (s);
c906108c 538 }
ed9a39eb 539 else
c906108c
SS
540 {
541 char *p;
c2d11a7d
JM
542 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
543 gotasig = target_signal_from_host (sig);
7a292a7a
SS
544 ourstatus->value.sig = gotasig;
545 if (gotasig)
c906108c
SS
546 ourstatus->kind = TARGET_WAITKIND_STOPPED;
547 }
548
549 free (s);
550 return gotasig;
551}
552
553static int
554handle_exception (struct target_waitstatus *ourstatus)
555{
556 int i;
557 int done = 0;
558 thread_info *th;
559
560 ourstatus->kind = TARGET_WAITKIND_STOPPED;
561
562 /* Record the context of the current thread */
563 th = thread_rec (current_event.dwThreadId, -1);
564
565 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
566 {
567 case EXCEPTION_ACCESS_VIOLATION:
568 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
c5aa993b 569 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 570 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
c2d11a7d 571 continue_status = DBG_EXCEPTION_NOT_HANDLED;
c906108c 572 break;
0d06e24b
JM
573 case STATUS_FLOAT_UNDERFLOW:
574 case STATUS_FLOAT_DIVIDE_BY_ZERO:
575 case STATUS_FLOAT_OVERFLOW:
576 case STATUS_INTEGER_DIVIDE_BY_ZERO:
577 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
578 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
579 ourstatus->value.sig = TARGET_SIGNAL_FPE;
580 continue_status = DBG_EXCEPTION_NOT_HANDLED;
581 break;
c906108c
SS
582 case STATUS_STACK_OVERFLOW:
583 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
c5aa993b 584 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 585 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
c2d11a7d 586 continue_status = DBG_EXCEPTION_NOT_HANDLED;
c906108c
SS
587 break;
588 case EXCEPTION_BREAKPOINT:
589 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
c5aa993b 590 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
591 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
592 break;
593 case DBG_CONTROL_C:
594 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
c5aa993b 595 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c 596 ourstatus->value.sig = TARGET_SIGNAL_INT;
c2d11a7d 597 continue_status = DBG_EXCEPTION_NOT_HANDLED;
c906108c
SS
598 break;
599 case EXCEPTION_SINGLE_STEP:
600 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
c5aa993b 601 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
602 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
603 break;
8227c82d
CF
604 case EXCEPTION_ILLEGAL_INSTRUCTION:
605 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
606 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
607 ourstatus->value.sig = TARGET_SIGNAL_ILL;
608 break;
c906108c
SS
609 default:
610 /* This may be a structured exception handling exception. In
c5aa993b 611 that case, we want to let the program try to handle it, and
ed9a39eb 612 only break if we see the exception a second time.
c906108c 613 if (current_event.u.Exception.dwFirstChance)
ed9a39eb 614
c906108c 615 return 0;
ed9a39eb 616*/
c906108c
SS
617
618 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
c5aa993b
JM
619 current_event.u.Exception.ExceptionRecord.ExceptionCode,
620 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c 621 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
c2d11a7d 622 continue_status = DBG_EXCEPTION_NOT_HANDLED;
c906108c
SS
623 break;
624 }
625 exception_count++;
626 return 1;
627}
628
629/* Resume all artificially suspended threads if we are continuing
630 execution */
631static BOOL
c2d11a7d 632child_continue (int id)
c906108c
SS
633{
634 int i;
635 thread_info *th;
636 BOOL res;
637
638 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
639 current_event.dwProcessId, current_event.dwThreadId));
7a292a7a
SS
640 res = ContinueDebugEvent (current_event.dwProcessId,
641 current_event.dwThreadId,
642 continue_status);
c2d11a7d 643 continue_status = 0;
7a292a7a 644 if (res)
c5aa993b 645 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
646 if (((id == -1) || (id == th->id)) && th->suspend_count)
647 {
648 for (i = 0; i < th->suspend_count; i++)
649 (void) ResumeThread (th->h);
650 th->suspend_count = 0;
651 }
652
653 return res;
654}
655
c2d11a7d
JM
656static int
657get_child_debug_event (int pid, struct target_waitstatus *ourstatus,
658 DWORD *event_code, int *retval)
659{
660 BOOL debug_event;
661 int breakout = 1;
662
663 if (!(debug_event = WaitForDebugEvent (&current_event, 20)))
664 {
665 breakout = *retval = *event_code = 0;
666 goto out;
667 }
668
669 event_count++;
670 continue_status = DBG_CONTINUE;
671 *retval = 0;
672
673 switch (*event_code = current_event.dwDebugEventCode)
674 {
675 case CREATE_THREAD_DEBUG_EVENT:
676 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
677 (unsigned) current_event.dwProcessId,
678 (unsigned) current_event.dwThreadId,
679 "CREATE_THREAD_DEBUG_EVENT"));
680 /* Record the existence of this thread */
681 child_add_thread (current_event.dwThreadId,
682 current_event.u.CreateThread.hThread);
683 if (info_verbose)
684 printf_unfiltered ("[New %s]\n",
685 target_pid_to_str (current_event.dwThreadId));
686 break;
687
688 case EXIT_THREAD_DEBUG_EVENT:
689 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
690 (unsigned) current_event.dwProcessId,
691 (unsigned) current_event.dwThreadId,
692 "EXIT_THREAD_DEBUG_EVENT"));
693 child_delete_thread (current_event.dwThreadId);
694 break;
695
696 case CREATE_PROCESS_DEBUG_EVENT:
697 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
698 (unsigned) current_event.dwProcessId,
699 (unsigned) current_event.dwThreadId,
700 "CREATE_PROCESS_DEBUG_EVENT"));
701 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
702
703 main_thread_id = inferior_pid = current_event.dwThreadId;
704 /* Add the main thread */
705 current_thread = child_add_thread (inferior_pid,
706 current_event.u.CreateProcessInfo.hThread);
707 break;
708
709 case EXIT_PROCESS_DEBUG_EVENT:
710 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
711 (unsigned) current_event.dwProcessId,
712 (unsigned) current_event.dwThreadId,
713 "EXIT_PROCESS_DEBUG_EVENT"));
714 ourstatus->kind = TARGET_WAITKIND_EXITED;
715 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
716 CloseHandle (current_process_handle);
717 *retval = current_event.dwProcessId;
718 goto out;
719
720 case LOAD_DLL_DEBUG_EVENT:
721 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
722 (unsigned) current_event.dwProcessId,
723 (unsigned) current_event.dwThreadId,
724 "LOAD_DLL_DEBUG_EVENT"));
725 catch_errors (handle_load_dll, NULL, "", RETURN_MASK_ALL);
726 registers_changed (); /* mark all regs invalid */
727 break;
728
729 case UNLOAD_DLL_DEBUG_EVENT:
730 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
731 (unsigned) current_event.dwProcessId,
732 (unsigned) current_event.dwThreadId,
733 "UNLOAD_DLL_DEBUG_EVENT"));
734 break; /* FIXME: don't know what to do here */
735
736 case EXCEPTION_DEBUG_EVENT:
737 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
738 (unsigned) current_event.dwProcessId,
739 (unsigned) current_event.dwThreadId,
740 "EXCEPTION_DEBUG_EVENT"));
741 if (handle_exception (ourstatus)) /* sets continue_status */
742 {
743 *retval = current_event.dwThreadId;
744 goto out;
745 }
746 break;
747
748 case OUTPUT_DEBUG_STRING_EVENT:
749 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
750 (unsigned) current_event.dwProcessId,
751 (unsigned) current_event.dwThreadId,
752 "OUTPUT_DEBUG_STRING_EVENT"));
753 if (handle_output_debug_string (ourstatus))
754 {
755 *retval = main_thread_id;
756 goto out;
757 }
758 break;
759 default:
760 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
761 current_event.dwProcessId,
762 current_event.dwThreadId);
763 printf_unfiltered (" unknown event code %d\n",
764 current_event.dwDebugEventCode);
765 break;
766 }
767
768 breakout = 0;
769 CHECK (child_continue (-1));
770 continue_status = 0;
771
772out:
773 return breakout;
774}
775
776
777/* Wait for interesting events to occur in the target process. */
c906108c
SS
778static int
779child_wait (int pid, struct target_waitstatus *ourstatus)
780{
c2d11a7d
JM
781 DWORD event_code;
782 int retval;
783
c906108c
SS
784 /* We loop when we get a non-standard exception rather than return
785 with a SPURIOUS because resume can try and step or modify things,
786 which needs a current_thread->h. But some of these exceptions mark
787 the birth or death of threads, which mean that the current thread
788 isn't necessarily what you think it is. */
789
790 while (1)
791 {
c2d11a7d
JM
792 if (continue_status != 0)
793 CHECK (child_continue (-1));
794 if (get_child_debug_event (pid, ourstatus, &event_code, &retval))
795 return retval;
7a292a7a
SS
796 else
797 {
798 int detach = 0;
c906108c 799
7a292a7a
SS
800 if (ui_loop_hook != NULL)
801 detach = ui_loop_hook (0);
802
803 if (detach)
804 child_kill_inferior ();
805 }
c906108c
SS
806 }
807}
808
809/* Attach to process PID, then initialize for debugging it. */
810
811static void
812child_attach (args, from_tty)
813 char *args;
814 int from_tty;
815{
816 BOOL ok;
817
818 if (!args)
819 error_no_arg ("process-id to attach");
820
821 current_event.dwProcessId = strtoul (args, 0, 0);
822
823 ok = DebugActiveProcess (current_event.dwProcessId);
824
825 if (!ok)
826 error ("Can't attach to process.");
827
828 exception_count = 0;
829 event_count = 0;
830
831 if (from_tty)
832 {
833 char *exec_file = (char *) get_exec_file (0);
834
835 if (exec_file)
836 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
837 target_pid_to_str (current_event.dwProcessId));
838 else
839 printf_unfiltered ("Attaching to %s\n",
840 target_pid_to_str (current_event.dwProcessId));
841
842 gdb_flush (gdb_stdout);
843 }
844
845 push_target (&child_ops);
846}
847
848static void
849child_detach (args, from_tty)
850 char *args;
851 int from_tty;
852{
853 if (from_tty)
854 {
855 char *exec_file = get_exec_file (0);
856 if (exec_file == 0)
857 exec_file = "";
858 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
859 target_pid_to_str (inferior_pid));
860 gdb_flush (gdb_stdout);
861 }
862 inferior_pid = 0;
863 unpush_target (&child_ops);
864}
865
866/* Print status information about what we're accessing. */
867
868static void
869child_files_info (ignore)
870 struct target_ops *ignore;
871{
872 printf_unfiltered ("\tUsing the running image of %s %s.\n",
873 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
874}
875
876/* ARGSUSED */
877static void
878child_open (arg, from_tty)
879 char *arg;
880 int from_tty;
881{
882 error ("Use the \"run\" command to start a Unix child process.");
883}
884
885/* Start an inferior win32 child process and sets inferior_pid to its pid.
886 EXEC_FILE is the file to run.
887 ALLARGS is a string containing the arguments to the program.
888 ENV is the environment vector to pass. Errors reported with error(). */
889
890static void
891child_create_inferior (exec_file, allargs, env)
892 char *exec_file;
893 char *allargs;
894 char **env;
895{
896 char real_path[MAXPATHLEN];
897 char *winenv;
898 char *temp;
c5aa993b 899 int envlen;
c906108c 900 int i;
c906108c
SS
901 STARTUPINFO si;
902 PROCESS_INFORMATION pi;
903 struct target_waitstatus dummy;
904 BOOL ret;
905 DWORD flags;
906 char *args;
c2d11a7d 907 DWORD event_code;
c906108c
SS
908
909 if (!exec_file)
910 {
911 error ("No executable specified, use `target exec'.\n");
912 }
913
914 memset (&si, 0, sizeof (si));
915 si.cb = sizeof (si);
916
917 cygwin32_conv_to_win32_path (exec_file, real_path);
918
919 flags = DEBUG_ONLY_THIS_PROCESS;
920
921 if (new_group)
922 flags |= CREATE_NEW_PROCESS_GROUP;
923
924 if (new_console)
925 flags |= CREATE_NEW_CONSOLE;
926
927 args = alloca (strlen (real_path) + strlen (allargs) + 2);
928
929 strcpy (args, real_path);
930
931 strcat (args, " ");
932 strcat (args, allargs);
933
934 /* Prepare the environment vars for CreateProcess. */
935 {
936 /* This code use to assume all env vars were file names and would
937 translate them all to win32 style. That obviously doesn't work in the
938 general case. The current rule is that we only translate PATH.
939 We need to handle PATH because we're about to call CreateProcess and
940 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
941 in both posix and win32 environments. cygwin.dll will change it back
942 to posix style if necessary. */
943
944 static const char *conv_path_names[] =
c5aa993b
JM
945 {
946 "PATH=",
947 0
948 };
c906108c
SS
949
950 /* CreateProcess takes the environment list as a null terminated set of
951 strings (i.e. two nulls terminate the list). */
952
953 /* Get total size for env strings. */
954 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
955 {
956 int j, len;
957
958 for (j = 0; conv_path_names[j]; j++)
959 {
960 len = strlen (conv_path_names[j]);
961 if (strncmp (conv_path_names[j], env[i], len) == 0)
962 {
963 if (cygwin32_posix_path_list_p (env[i] + len))
964 envlen += len
965 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
966 else
967 envlen += strlen (env[i]) + 1;
968 break;
969 }
970 }
971 if (conv_path_names[j] == NULL)
972 envlen += strlen (env[i]) + 1;
973 }
974
975 winenv = alloca (envlen + 1);
976
977 /* Copy env strings into new buffer. */
978 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
979 {
980 int j, len;
981
982 for (j = 0; conv_path_names[j]; j++)
983 {
984 len = strlen (conv_path_names[j]);
985 if (strncmp (conv_path_names[j], env[i], len) == 0)
986 {
987 if (cygwin32_posix_path_list_p (env[i] + len))
988 {
989 memcpy (temp, env[i], len);
990 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
991 }
992 else
993 strcpy (temp, env[i]);
994 break;
995 }
996 }
997 if (conv_path_names[j] == NULL)
998 strcpy (temp, env[i]);
999
1000 temp += strlen (temp) + 1;
1001 }
1002
1003 /* Final nil string to terminate new env. */
1004 *temp = 0;
1005 }
1006
1007 ret = CreateProcess (0,
c5aa993b 1008 args, /* command line */
c906108c
SS
1009 NULL, /* Security */
1010 NULL, /* thread */
1011 TRUE, /* inherit handles */
1012 flags, /* start flags */
1013 winenv,
1014 NULL, /* current directory */
1015 &si,
1016 &pi);
1017 if (!ret)
c5aa993b 1018 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c
SS
1019
1020 exception_count = 0;
1021 event_count = 0;
1022
1023 current_process_handle = pi.hProcess;
1024 current_event.dwProcessId = pi.dwProcessId;
1025 memset (&current_event, 0, sizeof (current_event));
1026 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1027 push_target (&child_ops);
1028 child_init_thread_list ();
1029 init_wait_for_inferior ();
1030 clear_proceed_status ();
1031 target_terminal_init ();
1032 target_terminal_inferior ();
1033
c2d11a7d
JM
1034 /* Run until process and threads are loaded */
1035 do
1036 get_child_debug_event (inferior_pid, &dummy, &event_code, &ret);
1037 while (event_code != EXCEPTION_DEBUG_EVENT);
c906108c 1038
ed9a39eb
JM
1039 SymSetOptions (SYMOPT_DEFERRED_LOADS);
1040 SymInitialize (current_process_handle, NULL, TRUE);
1041
c2d11a7d 1042 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
c906108c
SS
1043}
1044
1045static void
1046child_mourn_inferior ()
1047{
c2d11a7d
JM
1048 continue_status = DBG_CONTINUE;
1049 (void) child_continue (-1);
c906108c
SS
1050 unpush_target (&child_ops);
1051 generic_mourn_inferior ();
1052}
1053
1054/* Send a SIGINT to the process group. This acts just like the user typed a
1055 ^C on the controlling terminal. */
1056
1057static void
1058child_stop ()
1059{
1060 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
c2d11a7d 1061 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
c5aa993b 1062 registers_changed (); /* refresh register state */
c906108c
SS
1063}
1064
1065int
1066child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1067 int write, struct target_ops *target)
1068{
1069 DWORD done;
1070 if (write)
1071 {
1072 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
1073 len, memaddr));
1074 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1075 len, &done);
1076 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1077 }
1078 else
1079 {
1080 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
1081 len, memaddr));
1082 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1083 &done);
1084 }
1085 return done;
1086}
1087
1088void
1089child_kill_inferior (void)
1090{
1091 CHECK (TerminateProcess (current_process_handle, 0));
1092
1093 for (;;)
1094 {
c2d11a7d
JM
1095 continue_status = DBG_CONTINUE;
1096 if (!child_continue (-1))
c906108c
SS
1097 break;
1098 if (!WaitForDebugEvent (&current_event, INFINITE))
1099 break;
1100 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1101 break;
1102 }
1103
1104 CHECK (CloseHandle (current_process_handle));
1105
1106 /* this may fail in an attached process so don't check. */
1107 (void) CloseHandle (current_thread->h);
c5aa993b 1108 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
1109}
1110
1111void
1112child_resume (int pid, int step, enum target_signal sig)
1113{
1114 int i;
1115 thread_info *th;
c906108c
SS
1116
1117 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1118 pid, step, sig));
1119
1120 /* Get context for currently selected thread */
1121 th = thread_rec (current_event.dwThreadId, FALSE);
1122 if (step)
1123 {
1124#ifdef i386
1125 /* Single step by setting t bit */
1126 child_fetch_inferior_registers (PS_REGNUM);
1127 th->context.EFlags |= FLAG_TRACE_BIT;
1128#endif
1129 }
1130
1131 if (th->context.ContextFlags)
1132 {
1133 CHECK (SetThreadContext (th->h, &th->context));
1134 th->context.ContextFlags = 0;
1135 }
1136
1137 /* Allow continuing with the same signal that interrupted us.
1138 Otherwise complain. */
c906108c 1139
c2d11a7d 1140 child_continue (pid);
c906108c
SS
1141}
1142
1143static void
1144child_prepare_to_store ()
1145{
1146 /* Do nothing, since we can store individual regs */
1147}
1148
1149static int
1150child_can_run ()
1151{
1152 return 1;
1153}
1154
1155static void
1156child_close ()
1157{
1158 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1159}
1160
c5aa993b 1161struct target_ops child_ops;
c906108c 1162
c5aa993b
JM
1163static void
1164init_child_ops (void)
c906108c 1165{
c5aa993b
JM
1166 child_ops.to_shortname = "child";
1167 child_ops.to_longname = "Win32 child process";
1168 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1169 child_ops.to_open = child_open;
1170 child_ops.to_close = child_close;
1171 child_ops.to_attach = child_attach;
1172 child_ops.to_detach = child_detach;
1173 child_ops.to_resume = child_resume;
1174 child_ops.to_wait = child_wait;
1175 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1176 child_ops.to_store_registers = child_store_inferior_registers;
1177 child_ops.to_prepare_to_store = child_prepare_to_store;
1178 child_ops.to_xfer_memory = child_xfer_memory;
1179 child_ops.to_files_info = child_files_info;
1180 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1181 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1182 child_ops.to_terminal_init = terminal_init_inferior;
1183 child_ops.to_terminal_inferior = terminal_inferior;
1184 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1185 child_ops.to_terminal_ours = terminal_ours;
1186 child_ops.to_terminal_info = child_terminal_info;
1187 child_ops.to_kill = child_kill_inferior;
1188 child_ops.to_load = 0;
1189 child_ops.to_lookup_symbol = 0;
1190 child_ops.to_create_inferior = child_create_inferior;
1191 child_ops.to_mourn_inferior = child_mourn_inferior;
1192 child_ops.to_can_run = child_can_run;
1193 child_ops.to_notice_signals = 0;
1194 child_ops.to_thread_alive = win32_child_thread_alive;
ed9a39eb 1195 child_ops.to_pid_to_str = cygwin_pid_to_str;
c5aa993b
JM
1196 child_ops.to_stop = child_stop;
1197 child_ops.to_stratum = process_stratum;
1198 child_ops.DONT_USE = 0;
1199 child_ops.to_has_all_memory = 1;
1200 child_ops.to_has_memory = 1;
1201 child_ops.to_has_stack = 1;
1202 child_ops.to_has_registers = 1;
1203 child_ops.to_has_execution = 1;
1204 child_ops.to_sections = 0;
1205 child_ops.to_sections_end = 0;
1206 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1207}
1208
1209void
1210_initialize_inftarg ()
1211{
1212 struct cmd_list_element *c;
c5aa993b 1213 init_child_ops ();
c906108c
SS
1214
1215 add_show_from_set
1216 (add_set_cmd ("new-console", class_support, var_boolean,
1217 (char *) &new_console,
1218 "Set creation of new console when creating child process.",
1219 &setlist),
1220 &showlist);
1221
1222 add_show_from_set
1223 (add_set_cmd ("new-group", class_support, var_boolean,
1224 (char *) &new_group,
1225 "Set creation of new group when creating child process.",
1226 &setlist),
1227 &showlist);
1228
1229 add_show_from_set
1230 (add_set_cmd ("debugexec", class_support, var_boolean,
1231 (char *) &debug_exec,
1232 "Set whether to display execution in child process.",
1233 &setlist),
1234 &showlist);
1235
1236 add_show_from_set
1237 (add_set_cmd ("debugevents", class_support, var_boolean,
1238 (char *) &debug_events,
1239 "Set whether to display kernel events in child process.",
1240 &setlist),
1241 &showlist);
1242
1243 add_show_from_set
1244 (add_set_cmd ("debugmemory", class_support, var_boolean,
1245 (char *) &debug_memory,
1246 "Set whether to display memory accesses in child process.",
1247 &setlist),
1248 &showlist);
1249
1250 add_show_from_set
1251 (add_set_cmd ("debugexceptions", class_support, var_boolean,
1252 (char *) &debug_exceptions,
c5aa993b 1253 "Set whether to display kernel exceptions in child process.",
c906108c
SS
1254 &setlist),
1255 &showlist);
1256
1257 add_target (&child_ops);
1258}
1259
1260/* Determine if the thread referenced by "pid" is alive
1261 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1262 it means that the pid has died. Otherwise it is assumed to be alive. */
1263static int
1264win32_child_thread_alive (int pid)
1265{
c5aa993b
JM
1266 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1267 FALSE : TRUE;
c906108c
SS
1268}
1269
1270/* Convert pid to printable format. */
1271char *
1272cygwin_pid_to_str (int pid)
1273{
1274 static char buf[80];
1275 if (pid == current_event.dwProcessId)
1276 sprintf (buf, "process %d", pid);
1277 else
1278 sprintf (buf, "thread %d.0x%x", current_event.dwProcessId, pid);
1279 return buf;
1280}
This page took 0.155615 seconds and 4 git commands to generate.