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