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