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