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