windows-nat.c 30.8 KB
Newer Older
1
/* Target-vector operations for controlling win32 child processes, for GDB.
2
   Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3
   Contributed by Cygnus Support.
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
19
20
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
21
22
23

/* by Steve Chamberlain, sac@cygnus.com */

24
/* We assume we're being built with and will be used for cygwin.  */
25

26
27
28
29
30
31
32
33
34
35
#include "defs.h"
#include "frame.h"		/* required by inferior.h */
#include "inferior.h"
#include "target.h"
#include "wait.h"
#include "gdbcore.h"
#include "command.h"
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
36
37
38
#include <stdlib.h>

#ifdef _MSC_VER
39
#include "windefs.h"
40
41
42
43
#else /* other WIN32 compiler */
#include <windows.h>
#endif

44
#include "buildsym.h"
45
46
#include "symfile.h"
#include "objfiles.h"
47
#include "gdb_string.h"
48
#include "gdbthread.h"
49
#include "gdbcmd.h"
50
#include <sys/param.h>
51
#include <unistd.h>
52

53
54
55
56
/* The string sent by cygwin when it processes a signal.
   FIXME: This should be in a cygwin include file. */
#define CYGWIN_SIGNAL_STRING "cygwin: signal"

57
58
59
60
61
#define CHECK(x) 	check (x, __FILE__,__LINE__)
#define DEBUG_EXEC(x)	if (debug_exec)		printf x
#define DEBUG_EVENTS(x)	if (debug_events)	printf x
#define DEBUG_MEM(x)	if (debug_memory)	printf x
#define DEBUG_EXCEPT(x)	if (debug_exceptions)	printf x
62
63
64
65

/* Forward declaration */
extern struct target_ops child_ops;

66
static void child_stop PARAMS ((void));
Andrew Cagney's avatar
Andrew Cagney committed
67
static int win32_child_thread_alive PARAMS ((int));
68
69
70

static int last_sig = 0;	/* Set if a signal was received from the
				   debugged process */
71

72
73
74
75
76
77
78
79
80
81
82
/* Thread information structure used to track information that is
   not available in gdb's thread structure. */
typedef struct thread_info_struct
{
  struct thread_info_struct *next;
  DWORD id;
  HANDLE h;
  char *name;
  int suspend_count;
  CONTEXT context;
} thread_info;
83

84
static thread_info thread_head = {NULL};
85
86
87

/* The process and thread handles for the above context. */

88
89
90
91
92
static DEBUG_EVENT current_event;	/* The current debug event from
					   WaitForDebugEvent */
static HANDLE current_process_handle;	/* Currently executing process */
static thread_info *current_thread;	/* Info on currently selected thread */
static DWORD main_thread_id;		/* Thread ID of the main thread */
93
94
95
96
97
98
99
100

/* Counts of things. */
static int exception_count = 0;
static int event_count = 0;

/* User options. */
static int new_console = 0;
static int new_group = 0;
101
102
103
104
static int debug_exec = 0;		/* show execution */
static int debug_events = 0;		/* show events from kernel */
static int debug_memory = 0;		/* show target memory accesses */
static int debug_exceptions = 0;	/* show target exceptions */
105
106

/* This vector maps GDB's idea of a register's number into an address
107
   in the win32 exception context vector.
108

109
   It also contains the bit mask needed to load the register in question.
110
111
112
113
114
115
116
117
118

   One day we could read a reg, we could inspect the context we
   already have loaded, if it doesn't have the bit set that we need,
   we read that set of registers in using GetThreadContext.  If the
   context already contains what we need, we just unpack it. Then to
   write a register, first we have to ensure that the context contains
   the other regs of the group, and then we copy the info in and set
   out bit. */

119
120
#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
static const int mappings[] =
121
{
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  context_offset(Eax),
  context_offset(Ecx),
  context_offset(Edx),
  context_offset(Ebx),
  context_offset(Esp),
  context_offset(Ebp),
  context_offset(Esi),
  context_offset(Edi),
  context_offset(Eip),
  context_offset(EFlags),
  context_offset(SegCs),
  context_offset(SegSs),
  context_offset(SegDs),
  context_offset(SegEs),
  context_offset(SegFs),
  context_offset(SegGs),
  context_offset(FloatSave.RegisterArea[0 * 10]),
  context_offset(FloatSave.RegisterArea[1 * 10]),
  context_offset(FloatSave.RegisterArea[2 * 10]),
  context_offset(FloatSave.RegisterArea[3 * 10]),
  context_offset(FloatSave.RegisterArea[4 * 10]),
  context_offset(FloatSave.RegisterArea[5 * 10]),
  context_offset(FloatSave.RegisterArea[6 * 10]),
  context_offset(FloatSave.RegisterArea[7 * 10]),
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
};

/* This vector maps the target's idea of an exception (extracted
   from the DEBUG_EVENT structure) to GDB's idea. */

struct xlate_exception
  {
    int them;
    enum target_signal us;
  };

static const struct xlate_exception
  xlate[] =
{
  {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
161
  {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
162
163
164
165
166
  {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
  {DBG_CONTROL_C, TARGET_SIGNAL_INT},
  {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
  {-1, -1}};

167
168
169
170
171
/* Find a thread record given a thread id.
   If get_context then also retrieve the context for this
   thread. */
static thread_info *
thread_rec (DWORD id, int get_context)
172
{
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  thread_info *th;

  for (th = &thread_head; (th = th->next) != NULL; )
    if (th->id == id)
      {
	if (!th->suspend_count && get_context)
	  {
	    if (get_context > 0)
	      th->suspend_count = SuspendThread (th->h) + 1;
	    else if (get_context < 0)
	      th->suspend_count = -1;

	    th->context.ContextFlags = CONTEXT_DEBUGGER;
	    GetThreadContext (th->h, &th->context);
	  }
	return th;
      }

  return NULL;
}

/* Add a thread to the thread list */
static thread_info *
child_add_thread(DWORD id, HANDLE h)
{
  thread_info *th;

  if ((th = thread_rec (id, FALSE)))
    return th;

  th = (thread_info *) xmalloc (sizeof (*th));
  memset(th, 0, sizeof (*th));
  th->id = id;
  th->h = h;
  th->next = thread_head.next;
  thread_head.next = th;
  add_thread (id);
  return th;
211
212
}

213
214
/* Clear out any old thread list and reintialize it to a
   pristine state. */
215
static void
216
child_init_thread_list ()
217
{
218
219
220
221
222
  thread_info *th = &thread_head;

  DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
  init_thread_list ();
  while (th->next != NULL)
223
    {
224
225
226
227
      thread_info *here = th->next;
      th->next = here->next;
      (void) CloseHandle (here->h);
      free (here);
228
    }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
}

/* Delete a thread from the list of threads */
static void
child_delete_thread (DWORD id)
{
  thread_info *th;

  if (info_verbose)
    printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
  delete_thread (id);

  for (th = &thread_head;
       th->next != NULL && th->next->id != id;
       th = th->next)
    continue;

  if (th->next != NULL)
247
    {
248
249
250
251
      thread_info *here = th->next;
      th->next = here->next;
      CloseHandle (here->h);
      free (here);
252
253
254
255
    }
}

static void
256
257
258
259
260
261
262
263
check (BOOL ok, const char *file, int line)
{
  if (!ok)
    printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
}

static void
do_child_fetch_inferior_registers (int r)
264
{
265
266
267
  if (r >= 0)
    supply_register (r, ((char *) &current_thread->context) + mappings[r]);
  else
268
269
    {
      for (r = 0; r < NUM_REGS; r++)
270
	do_child_fetch_inferior_registers (r);
271
    }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
}

static void
child_fetch_inferior_registers (int r)
{
  current_thread = thread_rec (inferior_pid, TRUE);
  do_child_fetch_inferior_registers (r);
}

static void
do_child_store_inferior_registers (int r)
{
  if (r >= 0)
    read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
286
287
  else
    {
288
289
      for (r = 0; r < NUM_REGS; r++)
	do_child_store_inferior_registers (r);
290
291
292
    }
}

293
294
295
296
297
298
299
/* Store a new register value into the current thread context */
static void
child_store_inferior_registers (int r)
{
  current_thread = thread_rec (inferior_pid, TRUE);
  do_child_store_inferior_registers (r);
}
300
301
302
303

/* Wait for child to do something.  Return pid of child, or -1 in case
   of error; store status through argument pointer OURSTATUS.  */

304
static int
Andrew Cagney's avatar
Andrew Cagney committed
305
handle_load_dll (PTR dummy)
306
{
307
  LOAD_DLL_DEBUG_INFO * event = &current_event.u.LoadDll;
308
309
  DWORD dll_name_ptr;
  DWORD done;
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  char dll_buf[MAX_PATH + 1];
  char *p, *dll_name = NULL, *dll_basename;
  struct objfile *objfile;
  MEMORY_BASIC_INFORMATION minfo;

  dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';

  /* The following code attempts to find the name of the dll by reading the
     name from the processes memory.  Unfortunately it doesn't work right.
     Doing this the "right way" for Windows is very difficult.  FIXME */
#ifdef DOESNT_WORK
  memset (&minfo, 0, sizeof minfo);
  if (VirtualQueryEx (current_process_handle, (LPCVOID) event->lpBaseOfDll,
		      &minfo, sizeof(minfo)) && minfo.BaseAddress) {
      DWORD len;
      IMAGE_DOS_HEADER *hmm0 = (IMAGE_DOS_HEADER *) minfo.BaseAddress;
      HMODULE hmm = (HMODULE) (((DWORD) hmm0) + hmm0->e_lfanew);

      if ((len = GetModuleFileName (hmm, dll_buf, MAX_PATH)))
	{
	  dll_name = dll_buf;
	  dll_name[len] = '\0';
	}
  }
#endif
335

336
337
338
339
  /* Attempt to read the name of the dll that was detected.
     This is documented to work only when actively debugging
     a program.  It will not work for attached processes. */
  if (dll_name == NULL || *dll_name == '\0')
340
    {
341
      int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
342
343
      int len = 0;
      char b[2];
344
345
346
347
348
349
350
351
352
353
354
355

      ReadProcessMemory (current_process_handle,
			 (LPCVOID) event->lpImageName,
			 (char *) &dll_name_ptr,
			 sizeof (dll_name_ptr), &done);

      /* See if we could read the address of a string, and that the
	 address isn't null. */

      if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
	return 1;

356
357
      do
	{
358
359
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) (dll_name_ptr + len * size),
360
361
362
363
364
365
366
367
368
			     &b,
			     size,
			     &done);
	  len++;
	}
      while ((b[0] != 0 || b[size - 1] != 0) && done == size);

      dll_name = alloca (len);

369
      if (event->fUnicode)
370
371
	{
	  WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
372
373
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) dll_name_ptr,
374
375
376
377
378
379
380
381
382
383
			     unicode_dll_name,
			     len * sizeof (WCHAR),
			     &done);

	  WideCharToMultiByte (CP_ACP, 0,
			       unicode_dll_name, len,
			       dll_name, len, 0, 0);
	}
      else
	{
384
385
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) dll_name_ptr,
386
387
388
389
390
			     dll_name,
			     len,
			     &done);
	}
    }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

  if (!dll_name)
    return 1;

  while ((p = strchr (dll_name, '\\')))
    *p = '/';

  /* FIXME!! It would be nice to define one symbol which pointed to the
     front of the dll if we can't find any symbols. */

  if (!(dll_basename = strrchr(dll_name, '/')))
    dll_basename = dll_name;
  else
    dll_basename++;

  ALL_OBJFILES(objfile)
    {
      char *objfile_basename;
      objfile_basename = strrchr(objfile->name, '/');

      if (objfile_basename &&
	  strcmp(dll_basename, objfile_basename + 1) == 0)
	{
	  printf_unfiltered ("%x:%s (symbols previously loaded)\n",
			     event->lpBaseOfDll, dll_name);
	  goto out;
	}
  }

  /* The symbols in a dll are offset by 0x1000, which is the
     the offset from 0 of the first byte in an image - because
     of the file header and the section alignment.

     FIXME: Is this the real reason that we need the 0x1000 ? */

  printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
427
  symbol_file_add (dll_name, 0, (int) event->lpBaseOfDll + 0x1000, 0, 0, 0, 0, 1);
428
429
430
  printf_unfiltered ("\n");

out:
431
  return 1;
432
433
}

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/* Handle DEBUG_STRING output from child process.
   Cygwin prepends its messages with a "cygwin:".  Interpret this as
   a Cygwin signal.  Otherwise just print the string as a warning. */
static int
handle_output_debug_string (struct target_waitstatus *ourstatus)
{
  char *s;
  int gotasig = FALSE;

  if (!target_read_string
      ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
      || !s || !*s)
    return gotasig;

  if (strncmp(s, CYGWIN_SIGNAL_STRING, sizeof(CYGWIN_SIGNAL_STRING) - 1))
    {
      warning (s);
    }
  else
    {
      char *p;
      /*last_sig = */strtol(s + sizeof(CYGWIN_SIGNAL_STRING) - 1, &p, 0);
      if (gotasig = (ourstatus->value.sig = target_signal_from_host (last_sig)))
	ourstatus->kind = TARGET_WAITKIND_STOPPED;
    }

  free (s);
  return gotasig;
}
463

464
static int
465
handle_exception (struct target_waitstatus *ourstatus)
466
467
468
{
  int i;
  int done = 0;
469
470
  thread_info *th;

471
472
  ourstatus->kind = TARGET_WAITKIND_STOPPED;

473
474
  /* Record the context of the current thread */
  th = thread_rec (current_event.dwThreadId, -1);
475

476
  switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
477
    {
478
479
    case EXCEPTION_ACCESS_VIOLATION:
      DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
480
		     current_event.u.Exception.ExceptionRecord.ExceptionAddress));
481
482
483
484
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
      break;
    case STATUS_STACK_OVERFLOW:
      DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
485
		     current_event.u.Exception.ExceptionRecord.ExceptionAddress));
486
487
488
489
      ourstatus->value.sig = TARGET_SIGNAL_SEGV;
      break;
    case EXCEPTION_BREAKPOINT:
      DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
490
		     current_event.u.Exception.ExceptionRecord.ExceptionAddress));
491
492
493
494
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
      break;
    case DBG_CONTROL_C:
      DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
495
		     current_event.u.Exception.ExceptionRecord.ExceptionAddress));
496
      ourstatus->value.sig = TARGET_SIGNAL_INT;
497
498
      /* User typed CTRL-C.  Continue with this status */
      last_sig = SIGINT;	/* FIXME - should check pass state */
499
500
501
      break;
    case EXCEPTION_SINGLE_STEP:
      DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
502
		     current_event.u.Exception.ExceptionRecord.ExceptionAddress));
503
504
505
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
      break;
    default:
506
      /* This may be a structured exception handling exception.  In
507
508
509
	 that case, we want to let the program try to handle it, and
	 only break if we see the exception a second time.  */
      if (current_event.u.Exception.dwFirstChance)
510
511
	return 0;

512
      printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
513
514
			 current_event.u.Exception.ExceptionRecord.ExceptionCode,
			 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
515
      ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
516
      break;
517
518
    }
  exception_count++;
519
  return 1;
520
521
}

522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
/* Resume all artificially suspended threads if we are continuing
   execution */
static BOOL
child_continue (DWORD continue_status, int id)
{
  int i;
  thread_info *th;
  BOOL res;

  DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
		 current_event.dwProcessId, current_event.dwThreadId));
  if (res = ContinueDebugEvent (current_event.dwProcessId,
				current_event.dwThreadId,
			        continue_status))
    for (th = &thread_head; (th = th->next) != NULL; )
      if (((id == -1) || (id == th->id)) && th->suspend_count)
	{
	  for (i = 0; i < th->suspend_count; i++)
	    (void) ResumeThread (th->h);
	  th->suspend_count = 0;
	}

  return res;
}

547
548
549
550
551
static int
child_wait (int pid, struct target_waitstatus *ourstatus)
{
  /* We loop when we get a non-standard exception rather than return
     with a SPURIOUS because resume can try and step or modify things,
552
     which needs a current_thread->h.  But some of these exceptions mark
553
554
555
556
557
     the birth or death of threads, which mean that the current thread
     isn't necessarily what you think it is. */

  while (1)
    {
558
      DWORD continue_status;
559
560
561
562
      BOOL t = WaitForDebugEvent (&current_event, INFINITE);
      char *p;
      thread_info *th;
      int sig;
563
564
565

      event_count++;

566
567
      continue_status = DBG_CONTINUE;

568
      switch (current_event.dwDebugEventCode)
569
570
	{
	case CREATE_THREAD_DEBUG_EVENT:
571
572
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
			current_event.dwProcessId, current_event.dwThreadId,
573
			"CREATE_THREAD_DEBUG_EVENT"));
574
575
576
577
578
579
	  /* Record the existence of this thread */
	  child_add_thread (current_event.dwThreadId,
			    current_event.u.CreateThread.hThread);
	  if (info_verbose)
	      printf_unfiltered ("[New %s]\n",
			       target_pid_to_str (current_event.dwThreadId));
580
	  break;
581

582
	case EXIT_THREAD_DEBUG_EVENT:
583
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
584
			current_event.dwProcessId, current_event.dwThreadId,
585
			"EXIT_THREAD_DEBUG_EVENT"));
586
	  child_delete_thread (current_event.dwThreadId);
587
	  break;
588

589
	case CREATE_PROCESS_DEBUG_EVENT:
590
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
591
			current_event.dwProcessId, current_event.dwThreadId,
592
			"CREATE_PROCESS_DEBUG_EVENT"));
593
594
595
596
597
598
	  current_process_handle = current_event.u.CreateProcessInfo.hProcess;

	  main_thread_id = inferior_pid = current_event.dwThreadId;
	  /* Add the main thread */
	  current_thread = child_add_thread (inferior_pid,
				current_event.u.CreateProcessInfo.hThread);
599
600
601
	  break;

	case EXIT_PROCESS_DEBUG_EVENT:
602
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
603
			current_event.dwProcessId, current_event.dwThreadId,
604
			"EXIT_PROCESS_DEBUG_EVENT"));
605
	  ourstatus->kind = TARGET_WAITKIND_EXITED;
606
607
608
	  ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
	  CloseHandle (current_process_handle);
	  return current_event.dwProcessId;
609
610
611
	  break;

	case LOAD_DLL_DEBUG_EVENT:
612
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
613
			current_event.dwProcessId, current_event.dwThreadId,
614
			"LOAD_DLL_DEBUG_EVENT"));
615
          catch_errors (handle_load_dll, NULL, "", RETURN_MASK_ALL);
616
	  registers_changed();          /* mark all regs invalid */
617
	  break;
618

619
620
	case UNLOAD_DLL_DEBUG_EVENT:
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
621
			current_event.dwProcessId, current_event.dwThreadId,
622
623
			"UNLOAD_DLL_DEBUG_EVENT"));
	  break;	/* FIXME: don't know what to do here */
624
625

	case EXCEPTION_DEBUG_EVENT:
626
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
627
			current_event.dwProcessId, current_event.dwThreadId,
628
			"EXCEPTION_DEBUG_EVENT"));
629
630
	  if (handle_exception (ourstatus))
	    return current_event.dwThreadId;
631
632
	  continue_status = DBG_EXCEPTION_NOT_HANDLED;
	  break;
633
634
635

	case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
	  DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
636
			current_event.dwProcessId, current_event.dwThreadId,
637
			"OUTPUT_DEBUG_STRING_EVENT"));
638
639
	  if (handle_output_debug_string (ourstatus))
	    return main_thread_id;
640
	  break;
641
	default:
642
	  printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
643
644
			     current_event.dwProcessId,
			     current_event.dwThreadId);
645
	  printf_unfiltered ("                 unknown event code %d\n",
646
			     current_event.dwDebugEventCode);
647
648
	  break;
	}
649
650

      CHECK (child_continue (continue_status, -1));
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    }
}

/* Attach to process PID, then initialize for debugging it.  */

static void
child_attach (args, from_tty)
     char *args;
     int from_tty;
{
  BOOL ok;

  if (!args)
    error_no_arg ("process-id to attach");

666
  current_event.dwProcessId = strtoul (args, 0, 0);
667

668
  ok = DebugActiveProcess (current_event.dwProcessId);
669
670
671
672
673
674
675
676
677
678
679
680
681

  if (!ok)
    error ("Can't attach to process.");

  exception_count = 0;
  event_count = 0;

  if (from_tty)
    {
      char *exec_file = (char *) get_exec_file (0);

      if (exec_file)
	printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
682
			   target_pid_to_str (current_event.dwProcessId));
683
684
      else
	printf_unfiltered ("Attaching to %s\n",
685
			   target_pid_to_str (current_event.dwProcessId));
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

      gdb_flush (gdb_stdout);
    }

  push_target (&child_ops);
}

static void
child_detach (args, from_tty)
     char *args;
     int from_tty;
{
  if (from_tty)
    {
      char *exec_file = get_exec_file (0);
      if (exec_file == 0)
	exec_file = "";
      printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
			 target_pid_to_str (inferior_pid));
      gdb_flush (gdb_stdout);
    }
  inferior_pid = 0;
  unpush_target (&child_ops);
}

/* Print status information about what we're accessing.  */

static void
child_files_info (ignore)
     struct target_ops *ignore;
{
  printf_unfiltered ("\tUsing the running image of %s %s.\n",
      attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
}

/* ARGSUSED */
static void
child_open (arg, from_tty)
     char *arg;
     int from_tty;
{
  error ("Use the \"run\" command to start a Unix child process.");
}

730
/* Start an inferior win32 child process and sets inferior_pid to its pid.
731
732
733
734
735
736
737
738
739
740
   EXEC_FILE is the file to run.
   ALLARGS is a string containing the arguments to the program.
   ENV is the environment vector to pass.  Errors reported with error().  */

static void
child_create_inferior (exec_file, allargs, env)
     char *exec_file;
     char *allargs;
     char **env;
{
741
742
743
744
745
746
  char real_path[MAXPATHLEN];
  char *winenv;
  char *temp;
  int  envlen;
  int i;

747
748
749
750
751
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  struct target_waitstatus dummy;
  BOOL ret;
  DWORD flags;
752
  char *args;
753
754
755
756
757
758
759
760
761

  if (!exec_file)
    {
      error ("No executable specified, use `target exec'.\n");
    }

  memset (&si, 0, sizeof (si));
  si.cb = sizeof (si);

762
  cygwin32_conv_to_win32_path (exec_file, real_path);
763

764
  flags = DEBUG_ONLY_THIS_PROCESS;
765
766
767
768
769
770
771

  if (new_group)
    flags |= CREATE_NEW_PROCESS_GROUP;

  if (new_console)
    flags |= CREATE_NEW_CONSOLE;

772
773
774
  args = alloca (strlen (real_path) + strlen (allargs) + 2);

  strcpy (args, real_path);
775
776
777
778

  strcat (args, " ");
  strcat (args, allargs);

779
780
781
782
  /* Prepare the environment vars for CreateProcess.  */
  {
    /* This code use to assume all env vars were file names and would
       translate them all to win32 style.  That obviously doesn't work in the
783
784
785
786
787
       general case.  The current rule is that we only translate PATH.
       We need to handle PATH because we're about to call CreateProcess and
       it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
       in both posix and win32 environments.  cygwin.dll will change it back
       to posix style if necessary.  */
788
789
790
791
792
793
794
795
796
797
798
799
800

    static const char *conv_path_names[] =
      {
	"PATH=",
	0
      };

    /* CreateProcess takes the environment list as a null terminated set of
       strings (i.e. two nulls terminate the list).  */

    /* Get total size for env strings.  */
    for (envlen = 0, i = 0; env[i] && *env[i]; i++)
      {
801
	int j, len;
802

803
804
805
806
	for (j = 0; conv_path_names[j]; j++)
	  {
	    len = strlen (conv_path_names[j]);
	    if (strncmp (conv_path_names[j], env[i], len) == 0)
807
	      {
808
		if (cygwin32_posix_path_list_p (env[i] + len))
809
		  envlen += len
810
		    + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
811
812
813
		else
		  envlen += strlen (env[i]) + 1;
		break;
814
815
	      }
	  }
816
	if (conv_path_names[j] == NULL)
817
818
819
820
821
822
	  envlen += strlen (env[i]) + 1;
      }

    winenv = alloca (envlen + 1);

    /* Copy env strings into new buffer.  */
823
    for (temp = winenv, i = 0; env[i] && *env[i]; i++)
824
      {
825
	int j, len;
826

827
828
829
830
	for (j = 0; conv_path_names[j]; j++)
	  {
	    len = strlen (conv_path_names[j]);
	    if (strncmp (conv_path_names[j], env[i], len) == 0)
831
	      {
832
		if (cygwin32_posix_path_list_p (env[i] + len))
833
834
		  {
		    memcpy (temp, env[i], len);
835
		    cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
836
		  }
837
838
839
		else
		  strcpy (temp, env[i]);
		break;
840
841
	      }
	  }
842
	if (conv_path_names[j] == NULL)
843
	  strcpy (temp, env[i]);
844

845
846
847
848
849
850
	temp += strlen (temp) + 1;
      }

    /* Final nil string to terminate new env.  */
    *temp = 0;
  }
851
852

  ret = CreateProcess (0,
853
		       args, 	/* command line */
854
855
856
857
		       NULL,	/* Security */
		       NULL,	/* thread */
		       TRUE,	/* inherit handles */
		       flags,	/* start flags */
858
		       winenv,
859
860
861
862
		       NULL,	/* current directory */
		       &si,
		       &pi);
  if (!ret)
863
    error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
864
865
866
867

  exception_count = 0;
  event_count = 0;

868
869
870
871
  current_process_handle = pi.hProcess;
  current_event.dwProcessId = pi.dwProcessId;
  memset (&current_event, 0, sizeof (current_event));
  inferior_pid = current_event.dwThreadId = pi.dwThreadId;
872
  push_target (&child_ops);
873
  child_init_thread_list ();
874
875
876
877
878
879
880
881
882
883
884
885
886
887
  init_wait_for_inferior ();
  clear_proceed_status ();
  target_terminal_init ();
  target_terminal_inferior ();

  /* Ignore the first trap */
  child_wait (inferior_pid, &dummy);

  proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
}

static void
child_mourn_inferior ()
{
888
  (void) child_continue (DBG_CONTINUE, -1);
889
890
891
892
893
894
895
  unpush_target (&child_ops);
  generic_mourn_inferior ();
}

/* Send a SIGINT to the process group.  This acts just like the user typed a
   ^C on the controlling terminal. */

896
static void
897
898
child_stop ()
{
899
  DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
900
  CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
901
  registers_changed();		/* refresh register state */
902
903
904
}

int
905
906
child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
		   int write, struct target_ops *target)
907
908
909
910
{
  DWORD done;
  if (write)
    {
911
912
      DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
		  len, memaddr));
913
914
915
      WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
			  len, &done);
      FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
916
917
918
    }
  else
    {
919
920
      DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
		  len, memaddr));
921
922
      ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
			 &done);
923
924
925
926
927
928
929
    }
  return done;
}

void
child_kill_inferior (void)
{
930
931
  CHECK (TerminateProcess (current_process_handle, 0));

932
933
  for (;;)
    {
934
      if (!child_continue (DBG_CONTINUE, -1))
935
	break;
936
      if (!WaitForDebugEvent (&current_event, INFINITE))
937
	break;
938
      if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
939
940
941
	break;
    }

942
943
944
945
  CHECK (CloseHandle (current_process_handle));

  /* this may fail in an attached process so don't check. */
  (void) CloseHandle (current_thread->h);
946
  target_mourn_inferior();	/* or just child_mourn_inferior? */
947
948
949
}

void
950
child_resume (int pid, int step, enum target_signal sig)
951
{
952
953
954
955
  int i;
  thread_info *th;
  DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
			  DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
956

957
958
959
960
961
  DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
	       pid, step, sig));

  /* Get context for currently selected thread */
  th = thread_rec (current_event.dwThreadId, FALSE);
962
963
  if (step)
    {
964
#ifdef i386
965
966
      /* Single step by setting t bit */
      child_fetch_inferior_registers (PS_REGNUM);
967
      th->context.EFlags |= FLAG_TRACE_BIT;
968
#endif
969
970
    }

971
  if (th->context.ContextFlags)
972
    {
973
974
      CHECK (SetThreadContext (th->h, &th->context));
      th->context.ContextFlags = 0;
975
976
    }

977
978
979
980
  /* Allow continuing with the same signal that interrupted us.
     Otherwise complain. */
  if (sig && sig != last_sig)
    fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.  signal %d\n", sig);
981

982
983
  last_sig = 0;
  child_continue (continue_status, pid);
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
}

static void
child_prepare_to_store ()
{
  /* Do nothing, since we can store individual regs */
}

static int
child_can_run ()
{
  return 1;
}

static void
child_close ()
{
1001
  DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1002
}
1003

1004
1005
struct target_ops child_ops ;

1006
1007
static void 
init_child_ops(void)
1008
{
1009
  child_ops.to_shortname =   "child";
1010
  child_ops.to_longname =   "Win32 child process";
1011
1012
1013
1014
1015
1016
1017
  child_ops.to_doc =   "Win32 child process (started by the \"run\" command).";
  child_ops.to_open =   child_open;
  child_ops.to_close =   child_close;
  child_ops.to_attach =   child_attach;
  child_ops.to_detach =   child_detach;
  child_ops.to_resume =   child_resume;
  child_ops.to_wait  =   child_wait;
1018
1019
  child_ops.to_fetch_registers  =   child_fetch_inferior_registers;
  child_ops.to_store_registers  =   child_store_inferior_registers;
1020
1021
1022
  child_ops.to_prepare_to_store =   child_prepare_to_store;
  child_ops.to_xfer_memory  =   child_xfer_memory;
  child_ops.to_files_info  =   child_files_info;
1023
1024
1025
  child_ops.to_insert_breakpoint =   memory_insert_breakpoint;
  child_ops.to_remove_breakpoint =   memory_remove_breakpoint;
  child_ops.to_terminal_init  =   terminal_init_inferior;
1026
  child_ops.to_terminal_inferior =   terminal_inferior;
1027
  child_ops.to_terminal_ours_for_output =   terminal_ours_for_output;
1028
1029
1030
1031
1032
  child_ops.to_terminal_ours  =   terminal_ours;
  child_ops.to_terminal_info  =   child_terminal_info;
  child_ops.to_kill  =   child_kill_inferior;
  child_ops.to_load  =   0;
  child_ops.to_lookup_symbol =   0;
1033
  child_ops.to_create_inferior =   child_create_inferior;
1034
1035
1036
  child_ops.to_mourn_inferior =   child_mourn_inferior;
  child_ops.to_can_run  =   child_can_run;
  child_ops.to_notice_signals =   0;
Andrew Cagney's avatar
Andrew Cagney committed
1037
  child_ops.to_thread_alive  =   win32_child_thread_alive;
1038
  child_ops.to_stop  =   child_stop;
1039
  child_ops.to_stratum =   process_stratum;
1040
1041
1042
1043
1044
1045
1046
1047
  child_ops.DONT_USE =   0;
  child_ops.to_has_all_memory =   1;
  child_ops.to_has_memory =   1;
  child_ops.to_has_stack =   1;
  child_ops.to_has_registers =   1;
  child_ops.to_has_execution =   1;
  child_ops.to_sections =   0;
  child_ops.to_sections_end =   0;
1048
1049
  child_ops.to_magic =   OPS_MAGIC;
}
1050
1051
1052
1053

void
_initialize_inftarg ()
{
1054
  struct cmd_list_element *c;
1055
  init_child_ops() ;
1056

1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
  add_show_from_set
    (add_set_cmd ("new-console", class_support, var_boolean,
		  (char *) &new_console,
		  "Set creation of new console when creating child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ("new-group", class_support, var_boolean,
		  (char *) &new_group,
		  "Set creation of new group when creating child process.",
		  &setlist),
     &showlist);

1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
  add_show_from_set
    (add_set_cmd ("debugexec", class_support, var_boolean,
		  (char *) &debug_exec,
		  "Set whether to display execution in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ("debugevents", class_support, var_boolean,
		  (char *) &debug_events,
		  "Set whether to display kernel events in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ("debugmemory", class_support, var_boolean,
		  (char *) &debug_memory,
		  "Set whether to display memory accesses in child process.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_cmd ("debugexceptions", class_support, var_boolean,
		  (char *) &debug_exceptions,
		  "Set whether to display kernel exceptions in child process.",
		  &setlist),
     &showlist);

1099
1100
  add_target (&child_ops);
}
1101
1102
1103
1104
1105

/* Determine if the thread referenced by "pid" is alive
   by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
   it means that the pid has died.  Otherwise it is assumed to be alive. */
static int
Andrew Cagney's avatar
Andrew Cagney committed
1106
win32_child_thread_alive (int pid)
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
{
  return WaitForSingleObject(thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
	 FALSE : TRUE;
}

/* Convert pid to printable format. */
char *
cygwin_pid_to_str (int pid)
{
  static char buf[80];
  if (pid == current_event.dwProcessId)
    sprintf (buf, "process %d", pid);
  else
    sprintf (buf, "thread %d.0x%x", current_event.dwProcessId, pid);
  return buf;
}