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