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