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