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