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