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.
5 This file is part of GDB.
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.
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.
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
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /* by Steve Chamberlain, sac@cygnus.com */
24 /* We assume we're being built with and will be used for cygwin32. */
27 #include "frame.h" /* required by inferior.h */
34 #include <sys/types.h>
40 #else /* other WIN32 compiler */
47 #include "gdb_string.h"
48 #include "gdbthread.h"
50 #include <sys/param.h>
53 #define CHECK(x) check (x, __FILE__,__LINE__)
54 #define DEBUG_EXEC(x) if (debug_exec) printf x
55 #define DEBUG_EVENTS(x) if (debug_events) printf x
56 #define DEBUG_MEM(x) if (debug_memory) printf x
57 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
59 /* Forward declaration */
60 extern struct target_ops child_ops
;
62 static void child_stop
PARAMS ((void));
64 /* The most recently read context. Inspect ContextFlags to see what
67 static CONTEXT context
;
69 /* The process and thread handles for the above context. */
71 static HANDLE current_process
;
72 static HANDLE current_thread
;
73 static int current_process_id
;
74 static int current_thread_id
;
76 /* Counts of things. */
77 static int exception_count
= 0;
78 static int event_count
= 0;
81 static int new_console
= 0;
82 static int new_group
= 0;
83 static int debug_exec
= 0; /* show execution */
84 static int debug_events
= 0; /* show events from kernel */
85 static int debug_memory
= 0; /* show target memory accesses */
86 static int debug_exceptions
= 0; /* show target exceptions */
88 /* This vector maps GDB's idea of a register's number into an address
89 in the win32 exception context vector.
91 It also contains the bit mask needed to load the register in question.
93 One day we could read a reg, we could inspect the context we
94 already have loaded, if it doesn't have the bit set that we need,
95 we read that set of registers in using GetThreadContext. If the
96 context already contains what we need, we just unpack it. Then to
97 write a register, first we have to ensure that the context contains
98 the other regs of the group, and then we copy the info in and set
107 static const struct regmappings mappings
[] =
110 {(char *) &context
.Gpr0
, CONTEXT_INTEGER
},
111 {(char *) &context
.Gpr1
, CONTEXT_INTEGER
},
112 {(char *) &context
.Gpr2
, CONTEXT_INTEGER
},
113 {(char *) &context
.Gpr3
, CONTEXT_INTEGER
},
114 {(char *) &context
.Gpr4
, CONTEXT_INTEGER
},
115 {(char *) &context
.Gpr5
, CONTEXT_INTEGER
},
116 {(char *) &context
.Gpr6
, CONTEXT_INTEGER
},
117 {(char *) &context
.Gpr7
, CONTEXT_INTEGER
},
119 {(char *) &context
.Gpr8
, CONTEXT_INTEGER
},
120 {(char *) &context
.Gpr9
, CONTEXT_INTEGER
},
121 {(char *) &context
.Gpr10
, CONTEXT_INTEGER
},
122 {(char *) &context
.Gpr11
, CONTEXT_INTEGER
},
123 {(char *) &context
.Gpr12
, CONTEXT_INTEGER
},
124 {(char *) &context
.Gpr13
, CONTEXT_INTEGER
},
125 {(char *) &context
.Gpr14
, CONTEXT_INTEGER
},
126 {(char *) &context
.Gpr15
, CONTEXT_INTEGER
},
128 {(char *) &context
.Gpr16
, CONTEXT_INTEGER
},
129 {(char *) &context
.Gpr17
, CONTEXT_INTEGER
},
130 {(char *) &context
.Gpr18
, CONTEXT_INTEGER
},
131 {(char *) &context
.Gpr19
, CONTEXT_INTEGER
},
132 {(char *) &context
.Gpr20
, CONTEXT_INTEGER
},
133 {(char *) &context
.Gpr21
, CONTEXT_INTEGER
},
134 {(char *) &context
.Gpr22
, CONTEXT_INTEGER
},
135 {(char *) &context
.Gpr23
, CONTEXT_INTEGER
},
137 {(char *) &context
.Gpr24
, CONTEXT_INTEGER
},
138 {(char *) &context
.Gpr25
, CONTEXT_INTEGER
},
139 {(char *) &context
.Gpr26
, CONTEXT_INTEGER
},
140 {(char *) &context
.Gpr27
, CONTEXT_INTEGER
},
141 {(char *) &context
.Gpr28
, CONTEXT_INTEGER
},
142 {(char *) &context
.Gpr29
, CONTEXT_INTEGER
},
143 {(char *) &context
.Gpr30
, CONTEXT_INTEGER
},
144 {(char *) &context
.Gpr31
, CONTEXT_INTEGER
},
146 {(char *) &context
.Fpr0
, CONTEXT_FLOATING_POINT
},
147 {(char *) &context
.Fpr1
, CONTEXT_FLOATING_POINT
},
148 {(char *) &context
.Fpr2
, CONTEXT_FLOATING_POINT
},
149 {(char *) &context
.Fpr3
, CONTEXT_FLOATING_POINT
},
150 {(char *) &context
.Fpr4
, CONTEXT_FLOATING_POINT
},
151 {(char *) &context
.Fpr5
, CONTEXT_FLOATING_POINT
},
152 {(char *) &context
.Fpr6
, CONTEXT_FLOATING_POINT
},
153 {(char *) &context
.Fpr7
, CONTEXT_FLOATING_POINT
},
155 {(char *) &context
.Fpr8
, CONTEXT_FLOATING_POINT
},
156 {(char *) &context
.Fpr9
, CONTEXT_FLOATING_POINT
},
157 {(char *) &context
.Fpr10
, CONTEXT_FLOATING_POINT
},
158 {(char *) &context
.Fpr11
, CONTEXT_FLOATING_POINT
},
159 {(char *) &context
.Fpr12
, CONTEXT_FLOATING_POINT
},
160 {(char *) &context
.Fpr13
, CONTEXT_FLOATING_POINT
},
161 {(char *) &context
.Fpr14
, CONTEXT_FLOATING_POINT
},
162 {(char *) &context
.Fpr15
, CONTEXT_FLOATING_POINT
},
164 {(char *) &context
.Fpr16
, CONTEXT_FLOATING_POINT
},
165 {(char *) &context
.Fpr17
, CONTEXT_FLOATING_POINT
},
166 {(char *) &context
.Fpr18
, CONTEXT_FLOATING_POINT
},
167 {(char *) &context
.Fpr19
, CONTEXT_FLOATING_POINT
},
168 {(char *) &context
.Fpr20
, CONTEXT_FLOATING_POINT
},
169 {(char *) &context
.Fpr21
, CONTEXT_FLOATING_POINT
},
170 {(char *) &context
.Fpr22
, CONTEXT_FLOATING_POINT
},
171 {(char *) &context
.Fpr23
, CONTEXT_FLOATING_POINT
},
173 {(char *) &context
.Fpr24
, CONTEXT_FLOATING_POINT
},
174 {(char *) &context
.Fpr25
, CONTEXT_FLOATING_POINT
},
175 {(char *) &context
.Fpr26
, CONTEXT_FLOATING_POINT
},
176 {(char *) &context
.Fpr27
, CONTEXT_FLOATING_POINT
},
177 {(char *) &context
.Fpr28
, CONTEXT_FLOATING_POINT
},
178 {(char *) &context
.Fpr29
, CONTEXT_FLOATING_POINT
},
179 {(char *) &context
.Fpr30
, CONTEXT_FLOATING_POINT
},
180 {(char *) &context
.Fpr31
, CONTEXT_FLOATING_POINT
},
182 {(char *) &context
.Iar
, CONTEXT_CONTROL
},
183 {(char *) &context
.Msr
, CONTEXT_CONTROL
},
184 {(char *) &context
.Cr
, CONTEXT_INTEGER
},
185 {(char *) &context
.Lr
, CONTEXT_CONTROL
},
186 {(char *) &context
.Ctr
, CONTEXT_CONTROL
},
188 {(char *) &context
.Xer
, CONTEXT_INTEGER
},
189 {0,0}, /* MQ, but there isn't one */
191 {(char *) &context
.Eax
, CONTEXT_INTEGER
},
192 {(char *) &context
.Ecx
, CONTEXT_INTEGER
},
193 {(char *) &context
.Edx
, CONTEXT_INTEGER
},
194 {(char *) &context
.Ebx
, CONTEXT_INTEGER
},
195 {(char *) &context
.Esp
, CONTEXT_CONTROL
},
196 {(char *) &context
.Ebp
, CONTEXT_CONTROL
},
197 {(char *) &context
.Esi
, CONTEXT_INTEGER
},
198 {(char *) &context
.Edi
, CONTEXT_INTEGER
},
199 {(char *) &context
.Eip
, CONTEXT_CONTROL
},
200 {(char *) &context
.EFlags
, CONTEXT_CONTROL
},
201 {(char *) &context
.SegCs
, CONTEXT_SEGMENTS
},
202 {(char *) &context
.SegSs
, CONTEXT_SEGMENTS
},
203 {(char *) &context
.SegDs
, CONTEXT_SEGMENTS
},
204 {(char *) &context
.SegEs
, CONTEXT_SEGMENTS
},
205 {(char *) &context
.SegFs
, CONTEXT_SEGMENTS
},
206 {(char *) &context
.SegGs
, CONTEXT_SEGMENTS
},
207 {&context
.FloatSave
.RegisterArea
[0 * 10], CONTEXT_FLOATING_POINT
},
208 {&context
.FloatSave
.RegisterArea
[1 * 10], CONTEXT_FLOATING_POINT
},
209 {&context
.FloatSave
.RegisterArea
[2 * 10], CONTEXT_FLOATING_POINT
},
210 {&context
.FloatSave
.RegisterArea
[3 * 10], CONTEXT_FLOATING_POINT
},
211 {&context
.FloatSave
.RegisterArea
[4 * 10], CONTEXT_FLOATING_POINT
},
212 {&context
.FloatSave
.RegisterArea
[5 * 10], CONTEXT_FLOATING_POINT
},
213 {&context
.FloatSave
.RegisterArea
[6 * 10], CONTEXT_FLOATING_POINT
},
214 {&context
.FloatSave
.RegisterArea
[7 * 10], CONTEXT_FLOATING_POINT
},
218 /* This vector maps the target's idea of an exception (extracted
219 from the DEBUG_EVENT structure) to GDB's idea. */
221 struct xlate_exception
224 enum target_signal us
;
227 static const struct xlate_exception
230 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
231 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
232 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
233 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
234 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
238 check (BOOL ok
, const char *file
, int line
)
241 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
245 child_fetch_inferior_registers (int r
)
249 for (r
= 0; r
< NUM_REGS
; r
++)
250 child_fetch_inferior_registers (r
);
254 supply_register (r
, mappings
[r
].incontext
);
259 child_store_inferior_registers (int r
)
263 for (r
= 0; r
< NUM_REGS
; r
++)
264 child_store_inferior_registers (r
);
268 read_register_gen (r
, mappings
[r
].incontext
);
273 /* Wait for child to do something. Return pid of child, or -1 in case
274 of error; store status through argument pointer OURSTATUS. */
277 handle_load_dll (char *eventp
)
279 DEBUG_EVENT
* event
= (DEBUG_EVENT
*)eventp
;
283 ReadProcessMemory (current_process
,
284 (DWORD
) event
->u
.LoadDll
.lpImageName
,
285 (char *) &dll_name_ptr
,
286 sizeof (dll_name_ptr
), &done
);
288 /* See if we could read the address of a string, and that the
289 address isn't null. */
291 if (done
== sizeof (dll_name_ptr
) && dll_name_ptr
)
293 char *dll_name
, *dll_basename
;
294 struct objfile
*objfile
;
295 char unix_dll_name
[MAX_PATH
];
296 int size
= event
->u
.LoadDll
.fUnicode
? sizeof (WCHAR
) : sizeof (char);
301 ReadProcessMemory (current_process
,
302 dll_name_ptr
+ len
* size
,
308 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
310 dll_name
= alloca (len
);
312 if (event
->u
.LoadDll
.fUnicode
)
314 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
315 ReadProcessMemory (current_process
,
318 len
* sizeof (WCHAR
),
321 WideCharToMultiByte (CP_ACP
, 0,
322 unicode_dll_name
, len
,
323 dll_name
, len
, 0, 0);
327 ReadProcessMemory (current_process
,
334 /* FIXME: Can we delete this call? */
335 cygwin32_conv_to_posix_path (dll_name
, unix_dll_name
);
337 /* FIXME!! It would be nice to define one symbol which pointed to the
338 front of the dll if we can't find any symbols. */
340 if (!(dll_basename
= strrchr(dll_name
, '\\')))
341 dll_basename
= strrchr(dll_name
, '/');
343 ALL_OBJFILES(objfile
)
345 char *objfile_basename
;
346 if (!(objfile_basename
= strrchr(objfile
->name
, '\\')))
347 objfile_basename
= strrchr(objfile
->name
, '/');
349 if (dll_basename
&& objfile_basename
&&
350 strcmp(dll_basename
+1, objfile_basename
+1) == 0)
352 printf_unfiltered ("%s (symbols previously loaded)\n",
358 context
.ContextFlags
= CONTEXT_FULL
| CONTEXT_FLOATING_POINT
;
359 GetThreadContext (current_thread
, &context
);
361 /* The symbols in a dll are offset by 0x1000, which is the
362 the offset from 0 of the first byte in an image - because
363 of the file header and the section alignment.
365 FIXME: Is this the real reason that we need the 0x1000 ? */
368 symbol_file_add (unix_dll_name
, 0,
369 (int) event
->u
.LoadDll
.lpBaseOfDll
+ 0x1000, 0, 0, 0);
371 printf_unfiltered ("%x:%s\n", event
->u
.LoadDll
.lpBaseOfDll
,
379 handle_exception (DEBUG_EVENT
* event
, struct target_waitstatus
*ourstatus
)
383 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
386 switch (event
->u
.Exception
.ExceptionRecord
.ExceptionCode
)
388 case EXCEPTION_ACCESS_VIOLATION
:
389 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
390 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
391 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
393 case STATUS_STACK_OVERFLOW
:
394 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
395 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
396 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
398 case EXCEPTION_BREAKPOINT
:
399 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
400 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
401 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
404 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
405 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
406 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
408 case EXCEPTION_SINGLE_STEP
:
409 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
410 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
411 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
414 /* This may be a structured exception handling exception. In
415 that case, we want to let the program try to handle it, and
416 only break if we see the exception a second time. */
417 if (event
->u
.Exception
.dwFirstChance
)
420 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
421 event
->u
.Exception
.ExceptionRecord
.ExceptionCode
,
422 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
);
423 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
426 context
.ContextFlags
= CONTEXT_FULL
| CONTEXT_FLOATING_POINT
;
427 GetThreadContext (current_thread
, &context
);
433 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
435 /* We loop when we get a non-standard exception rather than return
436 with a SPURIOUS because resume can try and step or modify things,
437 which needs a current_thread. But some of these exceptions mark
438 the birth or death of threads, which mean that the current thread
439 isn't necessarily what you think it is. */
444 BOOL t
= WaitForDebugEvent (&event
, INFINITE
);
446 DWORD continue_status
;
450 current_thread_id
= event
.dwThreadId
;
451 current_process_id
= event
.dwProcessId
;
453 continue_status
= DBG_CONTINUE
;
455 switch (event
.dwDebugEventCode
)
457 case CREATE_THREAD_DEBUG_EVENT
:
458 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
459 event
.dwProcessId
, event
.dwThreadId
,
460 "CREATE_THREAD_DEBUG_EVENT"));
462 case EXIT_THREAD_DEBUG_EVENT
:
463 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
464 event
.dwProcessId
, event
.dwThreadId
,
465 "EXIT_THREAD_DEBUG_EVENT"));
467 case CREATE_PROCESS_DEBUG_EVENT
:
468 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
469 event
.dwProcessId
, event
.dwThreadId
,
470 "CREATE_PROCESS_DEBUG_EVENT"));
473 case EXIT_PROCESS_DEBUG_EVENT
:
474 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
475 event
.dwProcessId
, event
.dwThreadId
,
476 "EXIT_PROCESS_DEBUG_EVENT"));
477 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
478 ourstatus
->value
.integer
= event
.u
.ExitProcess
.dwExitCode
;
479 CloseHandle (current_process
);
480 CloseHandle (current_thread
);
481 return current_process_id
;
484 case LOAD_DLL_DEBUG_EVENT
:
485 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
486 event
.dwProcessId
, event
.dwThreadId
,
487 "LOAD_DLL_DEBUG_EVENT"));
488 catch_errors (handle_load_dll
,
490 "\n[failed reading symbols from DLL]\n",
492 registers_changed(); /* mark all regs invalid */
494 case UNLOAD_DLL_DEBUG_EVENT
:
495 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
496 event
.dwProcessId
, event
.dwThreadId
,
497 "UNLOAD_DLL_DEBUG_EVENT"));
498 break; /* FIXME: don't know what to do here */
499 case EXCEPTION_DEBUG_EVENT
:
500 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
501 event
.dwProcessId
, event
.dwThreadId
,
502 "EXCEPTION_DEBUG_EVENT"));
503 if (handle_exception (&event
, ourstatus
))
504 return current_process_id
;
505 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
508 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
509 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
510 event
.dwProcessId
, event
.dwThreadId
,
511 "OUTPUT_DEBUG_STRING_EVENT"));
512 if (target_read_string
513 ((CORE_ADDR
) event
.u
.DebugString
.lpDebugStringData
,
514 &p
, 1024, 0) && p
&& *p
)
521 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
522 event
.dwProcessId
, event
.dwThreadId
);
523 printf_unfiltered (" unknown event code %d\n",
524 event
.dwDebugEventCode
);
527 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
528 current_process_id
, current_thread_id
));
529 CHECK (ContinueDebugEvent (current_process_id
,
535 /* Attach to process PID, then initialize for debugging it. */
538 child_attach (args
, from_tty
)
545 error_no_arg ("process-id to attach");
547 current_process_id
= strtoul (args
, 0, 0);
549 ok
= DebugActiveProcess (current_process_id
);
552 error ("Can't attach to process.");
559 char *exec_file
= (char *) get_exec_file (0);
562 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
563 target_pid_to_str (current_process_id
));
565 printf_unfiltered ("Attaching to %s\n",
566 target_pid_to_str (current_process_id
));
568 gdb_flush (gdb_stdout
);
571 inferior_pid
= current_process_id
;
572 push_target (&child_ops
);
576 child_detach (args
, from_tty
)
582 char *exec_file
= get_exec_file (0);
585 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
586 target_pid_to_str (inferior_pid
));
587 gdb_flush (gdb_stdout
);
590 unpush_target (&child_ops
);
593 /* Print status information about what we're accessing. */
596 child_files_info (ignore
)
597 struct target_ops
*ignore
;
599 printf_unfiltered ("\tUsing the running image of %s %s.\n",
600 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
605 child_open (arg
, from_tty
)
609 error ("Use the \"run\" command to start a Unix child process.");
612 /* Start an inferior win32 child process and sets inferior_pid to its pid.
613 EXEC_FILE is the file to run.
614 ALLARGS is a string containing the arguments to the program.
615 ENV is the environment vector to pass. Errors reported with error(). */
618 child_create_inferior (exec_file
, allargs
, env
)
623 char real_path
[MAXPATHLEN
];
630 PROCESS_INFORMATION pi
;
631 struct target_waitstatus dummy
;
638 error ("No executable specified, use `target exec'.\n");
641 memset (&si
, 0, sizeof (si
));
644 cygwin32_conv_to_win32_path (exec_file
, real_path
);
646 flags
= DEBUG_ONLY_THIS_PROCESS
;
649 flags
|= CREATE_NEW_PROCESS_GROUP
;
652 flags
|= CREATE_NEW_CONSOLE
;
654 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
656 strcpy (args
, real_path
);
659 strcat (args
, allargs
);
661 /* Prepare the environment vars for CreateProcess. */
663 /* This code use to assume all env vars were file names and would
664 translate them all to win32 style. That obviously doesn't work in the
665 general case. The current rule is that we only translate PATH.
666 We need to handle PATH because we're about to call CreateProcess and
667 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
668 in both posix and win32 environments. cygwin.dll will change it back
669 to posix style if necessary. */
671 static const char *conv_path_names
[] =
677 /* CreateProcess takes the environment list as a null terminated set of
678 strings (i.e. two nulls terminate the list). */
680 /* Get total size for env strings. */
681 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
685 for (j
= 0; conv_path_names
[j
]; j
++)
687 len
= strlen (conv_path_names
[j
]);
688 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
690 if (cygwin32_posix_path_list_p (env
[i
] + len
))
692 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
694 envlen
+= strlen (env
[i
]) + 1;
698 if (conv_path_names
[j
] == NULL
)
699 envlen
+= strlen (env
[i
]) + 1;
702 winenv
= alloca (envlen
+ 1);
704 /* Copy env strings into new buffer. */
705 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
709 for (j
= 0; conv_path_names
[j
]; j
++)
711 len
= strlen (conv_path_names
[j
]);
712 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
714 if (cygwin32_posix_path_list_p (env
[i
] + len
))
716 memcpy (temp
, env
[i
], len
);
717 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
720 strcpy (temp
, env
[i
]);
724 if (conv_path_names
[j
] == NULL
)
725 strcpy (temp
, env
[i
]);
727 temp
+= strlen (temp
) + 1;
730 /* Final nil string to terminate new env. */
734 ret
= CreateProcess (0,
735 args
, /* command line */
738 TRUE
, /* inherit handles */
739 flags
, /* start flags */
741 NULL
, /* current directory */
745 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError());
750 inferior_pid
= pi
.dwProcessId
;
751 current_process
= pi
.hProcess
;
752 current_thread
= pi
.hThread
;
753 current_process_id
= pi
.dwProcessId
;
754 current_thread_id
= pi
.dwThreadId
;
755 push_target (&child_ops
);
757 init_wait_for_inferior ();
758 clear_proceed_status ();
759 target_terminal_init ();
760 target_terminal_inferior ();
762 /* Ignore the first trap */
763 child_wait (inferior_pid
, &dummy
);
765 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
769 child_mourn_inferior ()
771 (void) ContinueDebugEvent (current_process_id
,
774 unpush_target (&child_ops
);
775 generic_mourn_inferior ();
778 /* Send a SIGINT to the process group. This acts just like the user typed a
779 ^C on the controlling terminal. */
784 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
785 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0));
786 registers_changed(); /* refresh register state */
790 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
791 int write
, struct target_ops
*target
)
796 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
798 WriteProcessMemory (current_process
, memaddr
, our
, len
, &done
);
799 FlushInstructionCache (current_process
, memaddr
, len
);
803 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
805 ReadProcessMemory (current_process
, memaddr
, our
, len
, &done
);
811 child_kill_inferior (void)
813 CHECK (TerminateProcess (current_process
, 0));
818 if (!ContinueDebugEvent (current_process_id
,
822 if (!WaitForDebugEvent (&event
, INFINITE
))
824 current_thread_id
= event
.dwThreadId
;
825 current_process_id
= event
.dwProcessId
;
826 if (event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
830 CHECK (CloseHandle (current_process
));
831 CHECK (CloseHandle (current_thread
));
832 target_mourn_inferior(); /* or just child_mourn_inferior? */
836 child_resume (int pid
, int step
, enum target_signal signal
)
838 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, signal=%d);\n",
844 warning ("Single stepping not done.\n");
847 /* Single step by setting t bit */
848 child_fetch_inferior_registers (PS_REGNUM
);
849 context
.EFlags
|= FLAG_TRACE_BIT
;
853 if (context
.ContextFlags
)
855 CHECK (SetThreadContext (current_thread
, &context
));
856 context
.ContextFlags
= 0;
861 fprintf_unfiltered (gdb_stderr
, "Can't send signals to the child.\n");
864 DEBUG_EVENTS (("gdb: ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
865 current_process_id
, current_thread_id
));
866 CHECK (ContinueDebugEvent (current_process_id
,
872 child_prepare_to_store ()
874 /* Do nothing, since we can store individual regs */
886 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
889 struct target_ops child_ops
;
891 static void init_child_ops(void)
893 child_ops
.to_shortname
= "child";
894 child_ops
.to_longname
= "Win32 child process";
895 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
896 child_ops
.to_open
= child_open
;
897 child_ops
.to_close
= child_close
;
898 child_ops
.to_attach
= child_attach
;
899 child_ops
.to_detach
= child_detach
;
900 child_ops
.to_resume
= child_resume
;
901 child_ops
.to_wait
= child_wait
;
902 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
903 child_ops
.to_store_registers
= child_store_inferior_registers
;
904 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
905 child_ops
.to_xfer_memory
= child_xfer_memory
;
906 child_ops
.to_files_info
= child_files_info
;
907 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
908 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
909 child_ops
.to_terminal_init
= terminal_init_inferior
;
910 child_ops
.to_terminal_inferior
= terminal_inferior
;
911 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
912 child_ops
.to_terminal_ours
= terminal_ours
;
913 child_ops
.to_terminal_info
= child_terminal_info
;
914 child_ops
.to_kill
= child_kill_inferior
;
915 child_ops
.to_load
= 0;
916 child_ops
.to_lookup_symbol
= 0;
917 child_ops
.to_create_inferior
= child_create_inferior
;
918 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
919 child_ops
.to_can_run
= child_can_run
;
920 child_ops
.to_notice_signals
= 0;
921 child_ops
.to_thread_alive
= 0;
922 child_ops
.to_stop
= child_stop
;
923 child_ops
.to_stratum
= process_stratum
;
924 child_ops
.DONT_USE
= 0;
925 child_ops
.to_has_all_memory
= 1;
926 child_ops
.to_has_memory
= 1;
927 child_ops
.to_has_stack
= 1;
928 child_ops
.to_has_registers
= 1;
929 child_ops
.to_has_execution
= 1;
930 child_ops
.to_sections
= 0;
931 child_ops
.to_sections_end
= 0;
932 child_ops
.to_magic
= OPS_MAGIC
;
936 _initialize_inftarg ()
938 struct cmd_list_element
*c
;
942 (add_set_cmd ("new-console", class_support
, var_boolean
,
943 (char *) &new_console
,
944 "Set creation of new console when creating child process.",
949 (add_set_cmd ("new-group", class_support
, var_boolean
,
951 "Set creation of new group when creating child process.",
956 (add_set_cmd ("debugexec", class_support
, var_boolean
,
957 (char *) &debug_exec
,
958 "Set whether to display execution in child process.",
963 (add_set_cmd ("debugevents", class_support
, var_boolean
,
964 (char *) &debug_events
,
965 "Set whether to display kernel events in child process.",
970 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
971 (char *) &debug_memory
,
972 "Set whether to display memory accesses in child process.",
977 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
978 (char *) &debug_exceptions
,
979 "Set whether to display kernel exceptions in child process.",
983 add_target (&child_ops
);