* config/tc-i386.c: Add INFER_ADDR_PREFIX code. Fix 16 bit mode nop.
[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>
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>
52#include <unistd.h>
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
SS
81
82static int last_sig = 0; /* Set if a signal was received from the
83 debugged process */
84
85/* Thread information structure used to track information that is
86 not available in gdb's thread structure. */
87typedef struct thread_info_struct
c5aa993b
JM
88 {
89 struct thread_info_struct *next;
90 DWORD id;
91 HANDLE h;
92 char *name;
93 int suspend_count;
94 CONTEXT context;
95 }
96thread_info;
c906108c 97
c5aa993b
JM
98static thread_info thread_head =
99{NULL};
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;
115static int new_group = 0;
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]),
c906108c
SS
161};
162
163/* This vector maps the target's idea of an exception (extracted
164 from the DEBUG_EVENT structure) to GDB's idea. */
165
166struct xlate_exception
167 {
168 int them;
169 enum target_signal us;
170 };
171
172static const struct xlate_exception
173 xlate[] =
174{
175 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
176 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
177 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
178 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
179 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
180 {-1, -1}};
181
182/* Find a thread record given a thread id.
183 If get_context then also retrieve the context for this
184 thread. */
185static thread_info *
186thread_rec (DWORD id, int get_context)
187{
188 thread_info *th;
189
c5aa993b 190 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
191 if (th->id == id)
192 {
193 if (!th->suspend_count && get_context)
194 {
195 if (get_context > 0)
196 th->suspend_count = SuspendThread (th->h) + 1;
197 else if (get_context < 0)
198 th->suspend_count = -1;
199
200 th->context.ContextFlags = CONTEXT_DEBUGGER;
201 GetThreadContext (th->h, &th->context);
202 }
203 return th;
204 }
205
206 return NULL;
207}
208
209/* Add a thread to the thread list */
210static thread_info *
c5aa993b 211child_add_thread (DWORD id, HANDLE h)
c906108c
SS
212{
213 thread_info *th;
214
215 if ((th = thread_rec (id, FALSE)))
216 return th;
217
218 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 219 memset (th, 0, sizeof (*th));
c906108c
SS
220 th->id = id;
221 th->h = h;
222 th->next = thread_head.next;
223 thread_head.next = th;
224 add_thread (id);
225 return th;
226}
227
228/* Clear out any old thread list and reintialize it to a
229 pristine state. */
230static void
231child_init_thread_list ()
232{
233 thread_info *th = &thread_head;
234
235 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
236 init_thread_list ();
237 while (th->next != NULL)
238 {
239 thread_info *here = th->next;
240 th->next = here->next;
241 (void) CloseHandle (here->h);
242 free (here);
243 }
244}
245
246/* Delete a thread from the list of threads */
247static void
248child_delete_thread (DWORD id)
249{
250 thread_info *th;
251
252 if (info_verbose)
253 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
254 delete_thread (id);
255
256 for (th = &thread_head;
257 th->next != NULL && th->next->id != id;
258 th = th->next)
259 continue;
260
261 if (th->next != NULL)
262 {
263 thread_info *here = th->next;
264 th->next = here->next;
265 CloseHandle (here->h);
266 free (here);
267 }
268}
269
270static void
271check (BOOL ok, const char *file, int line)
272{
273 if (!ok)
274 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
275}
276
277static void
278do_child_fetch_inferior_registers (int r)
279{
280 if (r >= 0)
281 supply_register (r, ((char *) &current_thread->context) + mappings[r]);
282 else
283 {
284 for (r = 0; r < NUM_REGS; r++)
285 do_child_fetch_inferior_registers (r);
286 }
287}
288
289static void
290child_fetch_inferior_registers (int r)
291{
292 current_thread = thread_rec (inferior_pid, TRUE);
293 do_child_fetch_inferior_registers (r);
294}
295
296static void
297do_child_store_inferior_registers (int r)
298{
299 if (r >= 0)
300 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
301 else
302 {
303 for (r = 0; r < NUM_REGS; r++)
304 do_child_store_inferior_registers (r);
305 }
306}
307
308/* Store a new register value into the current thread context */
309static void
310child_store_inferior_registers (int r)
311{
312 current_thread = thread_rec (inferior_pid, TRUE);
313 do_child_store_inferior_registers (r);
314}
315
316/* Wait for child to do something. Return pid of child, or -1 in case
317 of error; store status through argument pointer OURSTATUS. */
318
319static int
320handle_load_dll (PTR dummy)
321{
c5aa993b 322 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c
SS
323 DWORD dll_name_ptr;
324 DWORD done;
325 char dll_buf[MAX_PATH + 1];
326 char *p, *dll_name = NULL, *dll_basename;
327 struct objfile *objfile;
328 MEMORY_BASIC_INFORMATION minfo;
329
c5aa993b 330 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c
SS
331
332 /* The following code attempts to find the name of the dll by reading the
333 name from the processes memory. Unfortunately it doesn't work right.
334 Doing this the "right way" for Windows is very difficult. FIXME */
335#ifdef DOESNT_WORK
336 memset (&minfo, 0, sizeof minfo);
337 if (VirtualQueryEx (current_process_handle, (LPCVOID) event->lpBaseOfDll,
c5aa993b
JM
338 &minfo, sizeof (minfo)) && minfo.BaseAddress)
339 {
c906108c
SS
340 DWORD len;
341 IMAGE_DOS_HEADER *hmm0 = (IMAGE_DOS_HEADER *) minfo.BaseAddress;
342 HMODULE hmm = (HMODULE) (((DWORD) hmm0) + hmm0->e_lfanew);
343
344 if ((len = GetModuleFileName (hmm, dll_buf, MAX_PATH)))
345 {
346 dll_name = dll_buf;
347 dll_name[len] = '\0';
348 }
c5aa993b 349 }
c906108c
SS
350#endif
351
352 /* Attempt to read the name of the dll that was detected.
353 This is documented to work only when actively debugging
354 a program. It will not work for attached processes. */
355 if (dll_name == NULL || *dll_name == '\0')
356 {
357 int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
358 int len = 0;
359 char b[2];
360
361 ReadProcessMemory (current_process_handle,
362 (LPCVOID) event->lpImageName,
363 (char *) &dll_name_ptr,
364 sizeof (dll_name_ptr), &done);
365
366 /* See if we could read the address of a string, and that the
c5aa993b 367 address isn't null. */
c906108c
SS
368
369 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
370 return 1;
371
372 do
373 {
374 ReadProcessMemory (current_process_handle,
375 (LPCVOID) (dll_name_ptr + len * size),
376 &b,
377 size,
378 &done);
379 len++;
380 }
381 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
382
383 dll_name = alloca (len);
384
385 if (event->fUnicode)
386 {
387 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
388 ReadProcessMemory (current_process_handle,
389 (LPCVOID) dll_name_ptr,
390 unicode_dll_name,
391 len * sizeof (WCHAR),
392 &done);
393
394 WideCharToMultiByte (CP_ACP, 0,
395 unicode_dll_name, len,
396 dll_name, len, 0, 0);
397 }
398 else
399 {
400 ReadProcessMemory (current_process_handle,
401 (LPCVOID) dll_name_ptr,
402 dll_name,
403 len,
404 &done);
405 }
406 }
407
408 if (!dll_name)
409 return 1;
410
411 while ((p = strchr (dll_name, '\\')))
412 *p = '/';
413
414 /* FIXME!! It would be nice to define one symbol which pointed to the
415 front of the dll if we can't find any symbols. */
416
c5aa993b 417 if (!(dll_basename = strrchr (dll_name, '/')))
c906108c
SS
418 dll_basename = dll_name;
419 else
420 dll_basename++;
421
c5aa993b
JM
422 ALL_OBJFILES (objfile)
423 {
424 char *objfile_basename;
425 objfile_basename = strrchr (objfile->name, '/');
c906108c 426
c5aa993b
JM
427 if (objfile_basename &&
428 strcmp (dll_basename, objfile_basename + 1) == 0)
429 {
430 printf_unfiltered ("%x:%s (symbols previously loaded)\n",
431 event->lpBaseOfDll, dll_name);
432 goto out;
433 }
c906108c
SS
434 }
435
436 /* The symbols in a dll are offset by 0x1000, which is the
437 the offset from 0 of the first byte in an image - because
438 of the file header and the section alignment.
439
440 FIXME: Is this the real reason that we need the 0x1000 ? */
441
442 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
443 symbol_file_add (dll_name, 0, (int) event->lpBaseOfDll + 0x1000, 0, 0, 0, 0, 1);
444 printf_unfiltered ("\n");
445
446out:
447 return 1;
448}
449
450/* Handle DEBUG_STRING output from child process.
451 Cygwin prepends its messages with a "cygwin:". Interpret this as
452 a Cygwin signal. Otherwise just print the string as a warning. */
453static int
454handle_output_debug_string (struct target_waitstatus *ourstatus)
455{
456 char *s;
457 int gotasig = FALSE;
458
459 if (!target_read_string
c5aa993b 460 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
461 || !s || !*s)
462 return gotasig;
463
c5aa993b 464 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1))
c906108c
SS
465 {
466 warning (s);
467 }
468 else
469 {
470 char *p;
c5aa993b 471 /*last_sig = */ strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
7a292a7a
SS
472 gotasig = target_signal_from_host (last_sig);
473 ourstatus->value.sig = gotasig;
474 if (gotasig)
c906108c
SS
475 ourstatus->kind = TARGET_WAITKIND_STOPPED;
476 }
477
478 free (s);
479 return gotasig;
480}
481
482static int
483handle_exception (struct target_waitstatus *ourstatus)
484{
485 int i;
486 int done = 0;
487 thread_info *th;
488
489 ourstatus->kind = TARGET_WAITKIND_STOPPED;
490
491 /* Record the context of the current thread */
492 th = thread_rec (current_event.dwThreadId, -1);
493
494 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
495 {
496 case EXCEPTION_ACCESS_VIOLATION:
497 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
c5aa993b 498 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
499 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
500 break;
501 case STATUS_STACK_OVERFLOW:
502 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
c5aa993b 503 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
504 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
505 break;
506 case EXCEPTION_BREAKPOINT:
507 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
c5aa993b 508 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
509 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
510 break;
511 case DBG_CONTROL_C:
512 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
c5aa993b 513 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
514 ourstatus->value.sig = TARGET_SIGNAL_INT;
515 /* User typed CTRL-C. Continue with this status */
516 last_sig = SIGINT; /* FIXME - should check pass state */
517 break;
518 case EXCEPTION_SINGLE_STEP:
519 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
c5aa993b 520 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
521 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
522 break;
523 default:
524 /* This may be a structured exception handling exception. In
c5aa993b
JM
525 that case, we want to let the program try to handle it, and
526 only break if we see the exception a second time. */
c906108c
SS
527 if (current_event.u.Exception.dwFirstChance)
528 return 0;
529
530 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
c5aa993b
JM
531 current_event.u.Exception.ExceptionRecord.ExceptionCode,
532 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
533 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
534 break;
535 }
536 exception_count++;
537 return 1;
538}
539
540/* Resume all artificially suspended threads if we are continuing
541 execution */
542static BOOL
543child_continue (DWORD continue_status, int id)
544{
545 int i;
546 thread_info *th;
547 BOOL res;
548
549 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
550 current_event.dwProcessId, current_event.dwThreadId));
7a292a7a
SS
551 res = ContinueDebugEvent (current_event.dwProcessId,
552 current_event.dwThreadId,
553 continue_status);
554 if (res)
c5aa993b 555 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
556 if (((id == -1) || (id == th->id)) && th->suspend_count)
557 {
558 for (i = 0; i < th->suspend_count; i++)
559 (void) ResumeThread (th->h);
560 th->suspend_count = 0;
561 }
562
563 return res;
564}
565
566static int
567child_wait (int pid, struct target_waitstatus *ourstatus)
568{
569 /* We loop when we get a non-standard exception rather than return
570 with a SPURIOUS because resume can try and step or modify things,
571 which needs a current_thread->h. But some of these exceptions mark
572 the birth or death of threads, which mean that the current thread
573 isn't necessarily what you think it is. */
574
575 while (1)
576 {
577 DWORD continue_status;
7a292a7a 578 BOOL debug_event = WaitForDebugEvent (&current_event, 20);
c906108c
SS
579 char *p;
580 thread_info *th;
581 int sig;
582
7a292a7a 583 if (debug_event)
c906108c 584 {
7a292a7a
SS
585 event_count++;
586
587 continue_status = DBG_CONTINUE;
588
589 switch (current_event.dwDebugEventCode)
590 {
591 case CREATE_THREAD_DEBUG_EVENT:
592 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
c5aa993b 593 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
594 "CREATE_THREAD_DEBUG_EVENT"));
595 /* Record the existence of this thread */
596 child_add_thread (current_event.dwThreadId,
597 current_event.u.CreateThread.hThread);
598 if (info_verbose)
599 printf_unfiltered ("[New %s]\n",
c5aa993b 600 target_pid_to_str (current_event.dwThreadId));
7a292a7a
SS
601 break;
602
603 case EXIT_THREAD_DEBUG_EVENT:
604 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 605 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
606 "EXIT_THREAD_DEBUG_EVENT"));
607 child_delete_thread (current_event.dwThreadId);
608 break;
609
610 case CREATE_PROCESS_DEBUG_EVENT:
611 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 612 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
613 "CREATE_PROCESS_DEBUG_EVENT"));
614 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
615
616 main_thread_id = inferior_pid = current_event.dwThreadId;
617 /* Add the main thread */
618 current_thread = child_add_thread (inferior_pid,
c5aa993b 619 current_event.u.CreateProcessInfo.hThread);
7a292a7a
SS
620 break;
621
622 case EXIT_PROCESS_DEBUG_EVENT:
623 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 624 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
625 "EXIT_PROCESS_DEBUG_EVENT"));
626 ourstatus->kind = TARGET_WAITKIND_EXITED;
627 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
628 CloseHandle (current_process_handle);
629 return current_event.dwProcessId;
630 break;
631
632 case LOAD_DLL_DEBUG_EVENT:
633 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 634 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
635 "LOAD_DLL_DEBUG_EVENT"));
636 catch_errors (handle_load_dll, NULL, "", RETURN_MASK_ALL);
c5aa993b 637 registers_changed (); /* mark all regs invalid */
7a292a7a
SS
638 break;
639
640 case UNLOAD_DLL_DEBUG_EVENT:
641 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 642 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a 643 "UNLOAD_DLL_DEBUG_EVENT"));
c5aa993b 644 break; /* FIXME: don't know what to do here */
7a292a7a
SS
645
646 case EXCEPTION_DEBUG_EVENT:
647 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 648 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
649 "EXCEPTION_DEBUG_EVENT"));
650 if (handle_exception (ourstatus))
651 return current_event.dwThreadId;
652 continue_status = DBG_EXCEPTION_NOT_HANDLED;
653 break;
654
c5aa993b 655 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
7a292a7a 656 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 657 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
658 "OUTPUT_DEBUG_STRING_EVENT"));
659 if (handle_output_debug_string (ourstatus))
660 return main_thread_id;
661 break;
662 default:
663 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
664 current_event.dwProcessId,
665 current_event.dwThreadId);
666 printf_unfiltered (" unknown event code %d\n",
667 current_event.dwDebugEventCode);
668 break;
669 }
670
671 CHECK (child_continue (continue_status, -1));
c906108c 672 }
7a292a7a
SS
673 else
674 {
675 int detach = 0;
c906108c 676
7a292a7a
SS
677 if (ui_loop_hook != NULL)
678 detach = ui_loop_hook (0);
679
680 if (detach)
681 child_kill_inferior ();
682 }
c906108c
SS
683 }
684}
685
686/* Attach to process PID, then initialize for debugging it. */
687
688static void
689child_attach (args, from_tty)
690 char *args;
691 int from_tty;
692{
693 BOOL ok;
694
695 if (!args)
696 error_no_arg ("process-id to attach");
697
698 current_event.dwProcessId = strtoul (args, 0, 0);
699
700 ok = DebugActiveProcess (current_event.dwProcessId);
701
702 if (!ok)
703 error ("Can't attach to process.");
704
705 exception_count = 0;
706 event_count = 0;
707
708 if (from_tty)
709 {
710 char *exec_file = (char *) get_exec_file (0);
711
712 if (exec_file)
713 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
714 target_pid_to_str (current_event.dwProcessId));
715 else
716 printf_unfiltered ("Attaching to %s\n",
717 target_pid_to_str (current_event.dwProcessId));
718
719 gdb_flush (gdb_stdout);
720 }
721
722 push_target (&child_ops);
723}
724
725static void
726child_detach (args, from_tty)
727 char *args;
728 int from_tty;
729{
730 if (from_tty)
731 {
732 char *exec_file = get_exec_file (0);
733 if (exec_file == 0)
734 exec_file = "";
735 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
736 target_pid_to_str (inferior_pid));
737 gdb_flush (gdb_stdout);
738 }
739 inferior_pid = 0;
740 unpush_target (&child_ops);
741}
742
743/* Print status information about what we're accessing. */
744
745static void
746child_files_info (ignore)
747 struct target_ops *ignore;
748{
749 printf_unfiltered ("\tUsing the running image of %s %s.\n",
750 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
751}
752
753/* ARGSUSED */
754static void
755child_open (arg, from_tty)
756 char *arg;
757 int from_tty;
758{
759 error ("Use the \"run\" command to start a Unix child process.");
760}
761
762/* Start an inferior win32 child process and sets inferior_pid to its pid.
763 EXEC_FILE is the file to run.
764 ALLARGS is a string containing the arguments to the program.
765 ENV is the environment vector to pass. Errors reported with error(). */
766
767static void
768child_create_inferior (exec_file, allargs, env)
769 char *exec_file;
770 char *allargs;
771 char **env;
772{
773 char real_path[MAXPATHLEN];
774 char *winenv;
775 char *temp;
c5aa993b 776 int envlen;
c906108c
SS
777 int i;
778
779 STARTUPINFO si;
780 PROCESS_INFORMATION pi;
781 struct target_waitstatus dummy;
782 BOOL ret;
783 DWORD flags;
784 char *args;
785
786 if (!exec_file)
787 {
788 error ("No executable specified, use `target exec'.\n");
789 }
790
791 memset (&si, 0, sizeof (si));
792 si.cb = sizeof (si);
793
794 cygwin32_conv_to_win32_path (exec_file, real_path);
795
796 flags = DEBUG_ONLY_THIS_PROCESS;
797
798 if (new_group)
799 flags |= CREATE_NEW_PROCESS_GROUP;
800
801 if (new_console)
802 flags |= CREATE_NEW_CONSOLE;
803
804 args = alloca (strlen (real_path) + strlen (allargs) + 2);
805
806 strcpy (args, real_path);
807
808 strcat (args, " ");
809 strcat (args, allargs);
810
811 /* Prepare the environment vars for CreateProcess. */
812 {
813 /* This code use to assume all env vars were file names and would
814 translate them all to win32 style. That obviously doesn't work in the
815 general case. The current rule is that we only translate PATH.
816 We need to handle PATH because we're about to call CreateProcess and
817 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
818 in both posix and win32 environments. cygwin.dll will change it back
819 to posix style if necessary. */
820
821 static const char *conv_path_names[] =
c5aa993b
JM
822 {
823 "PATH=",
824 0
825 };
c906108c
SS
826
827 /* CreateProcess takes the environment list as a null terminated set of
828 strings (i.e. two nulls terminate the list). */
829
830 /* Get total size for env strings. */
831 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
832 {
833 int j, len;
834
835 for (j = 0; conv_path_names[j]; j++)
836 {
837 len = strlen (conv_path_names[j]);
838 if (strncmp (conv_path_names[j], env[i], len) == 0)
839 {
840 if (cygwin32_posix_path_list_p (env[i] + len))
841 envlen += len
842 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
843 else
844 envlen += strlen (env[i]) + 1;
845 break;
846 }
847 }
848 if (conv_path_names[j] == NULL)
849 envlen += strlen (env[i]) + 1;
850 }
851
852 winenv = alloca (envlen + 1);
853
854 /* Copy env strings into new buffer. */
855 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
856 {
857 int j, len;
858
859 for (j = 0; conv_path_names[j]; j++)
860 {
861 len = strlen (conv_path_names[j]);
862 if (strncmp (conv_path_names[j], env[i], len) == 0)
863 {
864 if (cygwin32_posix_path_list_p (env[i] + len))
865 {
866 memcpy (temp, env[i], len);
867 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
868 }
869 else
870 strcpy (temp, env[i]);
871 break;
872 }
873 }
874 if (conv_path_names[j] == NULL)
875 strcpy (temp, env[i]);
876
877 temp += strlen (temp) + 1;
878 }
879
880 /* Final nil string to terminate new env. */
881 *temp = 0;
882 }
883
884 ret = CreateProcess (0,
c5aa993b 885 args, /* command line */
c906108c
SS
886 NULL, /* Security */
887 NULL, /* thread */
888 TRUE, /* inherit handles */
889 flags, /* start flags */
890 winenv,
891 NULL, /* current directory */
892 &si,
893 &pi);
894 if (!ret)
c5aa993b 895 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c
SS
896
897 exception_count = 0;
898 event_count = 0;
899
900 current_process_handle = pi.hProcess;
901 current_event.dwProcessId = pi.dwProcessId;
902 memset (&current_event, 0, sizeof (current_event));
903 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
904 push_target (&child_ops);
905 child_init_thread_list ();
906 init_wait_for_inferior ();
907 clear_proceed_status ();
908 target_terminal_init ();
909 target_terminal_inferior ();
910
911 /* Ignore the first trap */
912 child_wait (inferior_pid, &dummy);
913
914 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
915}
916
917static void
918child_mourn_inferior ()
919{
920 (void) child_continue (DBG_CONTINUE, -1);
921 unpush_target (&child_ops);
922 generic_mourn_inferior ();
923}
924
925/* Send a SIGINT to the process group. This acts just like the user typed a
926 ^C on the controlling terminal. */
927
928static void
929child_stop ()
930{
931 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
932 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
c5aa993b 933 registers_changed (); /* refresh register state */
c906108c
SS
934}
935
936int
937child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
938 int write, struct target_ops *target)
939{
940 DWORD done;
941 if (write)
942 {
943 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
944 len, memaddr));
945 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
946 len, &done);
947 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
948 }
949 else
950 {
951 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
952 len, memaddr));
953 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
954 &done);
955 }
956 return done;
957}
958
959void
960child_kill_inferior (void)
961{
962 CHECK (TerminateProcess (current_process_handle, 0));
963
964 for (;;)
965 {
966 if (!child_continue (DBG_CONTINUE, -1))
967 break;
968 if (!WaitForDebugEvent (&current_event, INFINITE))
969 break;
970 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
971 break;
972 }
973
974 CHECK (CloseHandle (current_process_handle));
975
976 /* this may fail in an attached process so don't check. */
977 (void) CloseHandle (current_thread->h);
c5aa993b 978 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
979}
980
981void
982child_resume (int pid, int step, enum target_signal sig)
983{
984 int i;
985 thread_info *th;
986 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
c5aa993b 987 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
c906108c
SS
988
989 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
990 pid, step, sig));
991
992 /* Get context for currently selected thread */
993 th = thread_rec (current_event.dwThreadId, FALSE);
994 if (step)
995 {
996#ifdef i386
997 /* Single step by setting t bit */
998 child_fetch_inferior_registers (PS_REGNUM);
999 th->context.EFlags |= FLAG_TRACE_BIT;
1000#endif
1001 }
1002
1003 if (th->context.ContextFlags)
1004 {
1005 CHECK (SetThreadContext (th->h, &th->context));
1006 th->context.ContextFlags = 0;
1007 }
1008
1009 /* Allow continuing with the same signal that interrupted us.
1010 Otherwise complain. */
1011 if (sig && sig != last_sig)
1012 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
1013
1014 last_sig = 0;
1015 child_continue (continue_status, pid);
1016}
1017
1018static void
1019child_prepare_to_store ()
1020{
1021 /* Do nothing, since we can store individual regs */
1022}
1023
1024static int
1025child_can_run ()
1026{
1027 return 1;
1028}
1029
1030static void
1031child_close ()
1032{
1033 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1034}
1035
c5aa993b 1036struct target_ops child_ops;
c906108c 1037
c5aa993b
JM
1038static void
1039init_child_ops (void)
c906108c 1040{
c5aa993b
JM
1041 child_ops.to_shortname = "child";
1042 child_ops.to_longname = "Win32 child process";
1043 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1044 child_ops.to_open = child_open;
1045 child_ops.to_close = child_close;
1046 child_ops.to_attach = child_attach;
1047 child_ops.to_detach = child_detach;
1048 child_ops.to_resume = child_resume;
1049 child_ops.to_wait = child_wait;
1050 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1051 child_ops.to_store_registers = child_store_inferior_registers;
1052 child_ops.to_prepare_to_store = child_prepare_to_store;
1053 child_ops.to_xfer_memory = child_xfer_memory;
1054 child_ops.to_files_info = child_files_info;
1055 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1056 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1057 child_ops.to_terminal_init = terminal_init_inferior;
1058 child_ops.to_terminal_inferior = terminal_inferior;
1059 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1060 child_ops.to_terminal_ours = terminal_ours;
1061 child_ops.to_terminal_info = child_terminal_info;
1062 child_ops.to_kill = child_kill_inferior;
1063 child_ops.to_load = 0;
1064 child_ops.to_lookup_symbol = 0;
1065 child_ops.to_create_inferior = child_create_inferior;
1066 child_ops.to_mourn_inferior = child_mourn_inferior;
1067 child_ops.to_can_run = child_can_run;
1068 child_ops.to_notice_signals = 0;
1069 child_ops.to_thread_alive = win32_child_thread_alive;
1070 child_ops.to_stop = child_stop;
1071 child_ops.to_stratum = process_stratum;
1072 child_ops.DONT_USE = 0;
1073 child_ops.to_has_all_memory = 1;
1074 child_ops.to_has_memory = 1;
1075 child_ops.to_has_stack = 1;
1076 child_ops.to_has_registers = 1;
1077 child_ops.to_has_execution = 1;
1078 child_ops.to_sections = 0;
1079 child_ops.to_sections_end = 0;
1080 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1081}
1082
1083void
1084_initialize_inftarg ()
1085{
1086 struct cmd_list_element *c;
c5aa993b 1087 init_child_ops ();
c906108c
SS
1088
1089 add_show_from_set
1090 (add_set_cmd ("new-console", class_support, var_boolean,
1091 (char *) &new_console,
1092 "Set creation of new console when creating child process.",
1093 &setlist),
1094 &showlist);
1095
1096 add_show_from_set
1097 (add_set_cmd ("new-group", class_support, var_boolean,
1098 (char *) &new_group,
1099 "Set creation of new group when creating child process.",
1100 &setlist),
1101 &showlist);
1102
1103 add_show_from_set
1104 (add_set_cmd ("debugexec", class_support, var_boolean,
1105 (char *) &debug_exec,
1106 "Set whether to display execution in child process.",
1107 &setlist),
1108 &showlist);
1109
1110 add_show_from_set
1111 (add_set_cmd ("debugevents", class_support, var_boolean,
1112 (char *) &debug_events,
1113 "Set whether to display kernel events in child process.",
1114 &setlist),
1115 &showlist);
1116
1117 add_show_from_set
1118 (add_set_cmd ("debugmemory", class_support, var_boolean,
1119 (char *) &debug_memory,
1120 "Set whether to display memory accesses in child process.",
1121 &setlist),
1122 &showlist);
1123
1124 add_show_from_set
1125 (add_set_cmd ("debugexceptions", class_support, var_boolean,
1126 (char *) &debug_exceptions,
c5aa993b 1127 "Set whether to display kernel exceptions in child process.",
c906108c
SS
1128 &setlist),
1129 &showlist);
1130
1131 add_target (&child_ops);
1132}
1133
1134/* Determine if the thread referenced by "pid" is alive
1135 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1136 it means that the pid has died. Otherwise it is assumed to be alive. */
1137static int
1138win32_child_thread_alive (int pid)
1139{
c5aa993b
JM
1140 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1141 FALSE : TRUE;
c906108c
SS
1142}
1143
1144/* Convert pid to printable format. */
1145char *
1146cygwin_pid_to_str (int pid)
1147{
1148 static char buf[80];
1149 if (pid == current_event.dwProcessId)
1150 sprintf (buf, "process %d", pid);
1151 else
1152 sprintf (buf, "thread %d.0x%x", current_event.dwProcessId, pid);
1153 return buf;
1154}
This page took 0.073467 seconds and 4 git commands to generate.