1 /* Target-vector operations for controlling win32 child processes, for GDB.
2 Copyright 1995, 1996 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. */
21 /* by Steve Chamberlain, sac@cygnus.com */
23 /* We assume we're being built with and will be used for cygwin32. */
26 #include "frame.h" /* required by inferior.h */
33 #include <sys/types.h>
39 #include "gdb_string.h"
40 #include "gdbthread.h"
42 #include <sys/param.h>
45 #define CHECK(x) check (x, __FILE__,__LINE__)
46 #define DEBUG_EXEC(x) if (debug_exec) printf x
47 #define DEBUG_EVENTS(x) if (debug_events) printf x
48 #define DEBUG_MEM(x) if (debug_memory) printf x
49 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
51 /* Forward declaration */
52 extern struct target_ops child_ops
;
54 /* The most recently read context. Inspect ContextFlags to see what
57 static CONTEXT context
;
59 /* The process and thread handles for the above context. */
61 static HANDLE current_process
;
62 static HANDLE current_thread
;
63 static int current_process_id
;
64 static int current_thread_id
;
66 /* Counts of things. */
67 static int exception_count
= 0;
68 static int event_count
= 0;
71 static int new_console
= 0;
72 static int new_group
= 0;
73 static int debug_exec
= 0; /* show execution */
74 static int debug_events
= 0; /* show events from kernel */
75 static int debug_memory
= 0; /* show target memory accesses */
76 static int debug_exceptions
= 0; /* show target exceptions */
78 /* This vector maps GDB's idea of a register's number into an address
79 in the win32 exception context vector.
81 It also contains the bit mask needed to load the register in question.
83 One day we could read a reg, we could inspect the context we
84 already have loaded, if it doesn't have the bit set that we need,
85 we read that set of registers in using GetThreadContext. If the
86 context already contains what we need, we just unpack it. Then to
87 write a register, first we have to ensure that the context contains
88 the other regs of the group, and then we copy the info in and set
98 static const struct regmappings mappings
[] =
101 {(char *) &context
.Gpr0
, CONTEXT_INTEGER
},
102 {(char *) &context
.Gpr1
, CONTEXT_INTEGER
},
103 {(char *) &context
.Gpr2
, CONTEXT_INTEGER
},
104 {(char *) &context
.Gpr3
, CONTEXT_INTEGER
},
105 {(char *) &context
.Gpr4
, CONTEXT_INTEGER
},
106 {(char *) &context
.Gpr5
, CONTEXT_INTEGER
},
107 {(char *) &context
.Gpr6
, CONTEXT_INTEGER
},
108 {(char *) &context
.Gpr7
, CONTEXT_INTEGER
},
110 {(char *) &context
.Gpr8
, CONTEXT_INTEGER
},
111 {(char *) &context
.Gpr9
, CONTEXT_INTEGER
},
112 {(char *) &context
.Gpr10
, CONTEXT_INTEGER
},
113 {(char *) &context
.Gpr11
, CONTEXT_INTEGER
},
114 {(char *) &context
.Gpr12
, CONTEXT_INTEGER
},
115 {(char *) &context
.Gpr13
, CONTEXT_INTEGER
},
116 {(char *) &context
.Gpr14
, CONTEXT_INTEGER
},
117 {(char *) &context
.Gpr15
, CONTEXT_INTEGER
},
119 {(char *) &context
.Gpr16
, CONTEXT_INTEGER
},
120 {(char *) &context
.Gpr17
, CONTEXT_INTEGER
},
121 {(char *) &context
.Gpr18
, CONTEXT_INTEGER
},
122 {(char *) &context
.Gpr19
, CONTEXT_INTEGER
},
123 {(char *) &context
.Gpr20
, CONTEXT_INTEGER
},
124 {(char *) &context
.Gpr21
, CONTEXT_INTEGER
},
125 {(char *) &context
.Gpr22
, CONTEXT_INTEGER
},
126 {(char *) &context
.Gpr23
, CONTEXT_INTEGER
},
128 {(char *) &context
.Gpr24
, CONTEXT_INTEGER
},
129 {(char *) &context
.Gpr25
, CONTEXT_INTEGER
},
130 {(char *) &context
.Gpr26
, CONTEXT_INTEGER
},
131 {(char *) &context
.Gpr27
, CONTEXT_INTEGER
},
132 {(char *) &context
.Gpr28
, CONTEXT_INTEGER
},
133 {(char *) &context
.Gpr29
, CONTEXT_INTEGER
},
134 {(char *) &context
.Gpr30
, CONTEXT_INTEGER
},
135 {(char *) &context
.Gpr31
, CONTEXT_INTEGER
},
137 {(char *) &context
.Fpr0
, CONTEXT_FLOATING_POINT
},
138 {(char *) &context
.Fpr1
, CONTEXT_FLOATING_POINT
},
139 {(char *) &context
.Fpr2
, CONTEXT_FLOATING_POINT
},
140 {(char *) &context
.Fpr3
, CONTEXT_FLOATING_POINT
},
141 {(char *) &context
.Fpr4
, CONTEXT_FLOATING_POINT
},
142 {(char *) &context
.Fpr5
, CONTEXT_FLOATING_POINT
},
143 {(char *) &context
.Fpr6
, CONTEXT_FLOATING_POINT
},
144 {(char *) &context
.Fpr7
, CONTEXT_FLOATING_POINT
},
146 {(char *) &context
.Fpr8
, CONTEXT_FLOATING_POINT
},
147 {(char *) &context
.Fpr9
, CONTEXT_FLOATING_POINT
},
148 {(char *) &context
.Fpr10
, CONTEXT_FLOATING_POINT
},
149 {(char *) &context
.Fpr11
, CONTEXT_FLOATING_POINT
},
150 {(char *) &context
.Fpr12
, CONTEXT_FLOATING_POINT
},
151 {(char *) &context
.Fpr13
, CONTEXT_FLOATING_POINT
},
152 {(char *) &context
.Fpr14
, CONTEXT_FLOATING_POINT
},
153 {(char *) &context
.Fpr15
, CONTEXT_FLOATING_POINT
},
155 {(char *) &context
.Fpr16
, CONTEXT_FLOATING_POINT
},
156 {(char *) &context
.Fpr17
, CONTEXT_FLOATING_POINT
},
157 {(char *) &context
.Fpr18
, CONTEXT_FLOATING_POINT
},
158 {(char *) &context
.Fpr19
, CONTEXT_FLOATING_POINT
},
159 {(char *) &context
.Fpr20
, CONTEXT_FLOATING_POINT
},
160 {(char *) &context
.Fpr21
, CONTEXT_FLOATING_POINT
},
161 {(char *) &context
.Fpr22
, CONTEXT_FLOATING_POINT
},
162 {(char *) &context
.Fpr23
, CONTEXT_FLOATING_POINT
},
164 {(char *) &context
.Fpr24
, CONTEXT_FLOATING_POINT
},
165 {(char *) &context
.Fpr25
, CONTEXT_FLOATING_POINT
},
166 {(char *) &context
.Fpr26
, CONTEXT_FLOATING_POINT
},
167 {(char *) &context
.Fpr27
, CONTEXT_FLOATING_POINT
},
168 {(char *) &context
.Fpr28
, CONTEXT_FLOATING_POINT
},
169 {(char *) &context
.Fpr29
, CONTEXT_FLOATING_POINT
},
170 {(char *) &context
.Fpr30
, CONTEXT_FLOATING_POINT
},
171 {(char *) &context
.Fpr31
, CONTEXT_FLOATING_POINT
},
174 {(char *) &context
.Iar
, CONTEXT_CONTROL
},
175 {(char *) &context
.Msr
, CONTEXT_CONTROL
},
176 {(char *) &context
.Cr
, CONTEXT_INTEGER
},
177 {(char *) &context
.Lr
, CONTEXT_CONTROL
},
178 {(char *) &context
.Ctr
, CONTEXT_CONTROL
},
180 {(char *) &context
.Xer
, CONTEXT_INTEGER
},
181 {0,0}, /* MQ, but there isn't one */
183 {(char *) &context
.Eax
, CONTEXT_INTEGER
},
184 {(char *) &context
.Ecx
, CONTEXT_INTEGER
},
185 {(char *) &context
.Edx
, CONTEXT_INTEGER
},
186 {(char *) &context
.Ebx
, CONTEXT_INTEGER
},
187 {(char *) &context
.Esp
, CONTEXT_CONTROL
},
188 {(char *) &context
.Ebp
, CONTEXT_CONTROL
},
189 {(char *) &context
.Esi
, CONTEXT_INTEGER
},
190 {(char *) &context
.Edi
, CONTEXT_INTEGER
},
191 {(char *) &context
.Eip
, CONTEXT_CONTROL
},
192 {(char *) &context
.EFlags
, CONTEXT_CONTROL
},
193 {(char *) &context
.SegCs
, CONTEXT_SEGMENTS
},
194 {(char *) &context
.SegSs
, CONTEXT_SEGMENTS
},
195 {(char *) &context
.SegDs
, CONTEXT_SEGMENTS
},
196 {(char *) &context
.SegEs
, CONTEXT_SEGMENTS
},
197 {(char *) &context
.SegFs
, CONTEXT_SEGMENTS
},
198 {(char *) &context
.SegGs
, CONTEXT_SEGMENTS
},
199 {&context
.FloatSave
.RegisterArea
[0 * 10], CONTEXT_FLOATING_POINT
},
200 {&context
.FloatSave
.RegisterArea
[1 * 10], CONTEXT_FLOATING_POINT
},
201 {&context
.FloatSave
.RegisterArea
[2 * 10], CONTEXT_FLOATING_POINT
},
202 {&context
.FloatSave
.RegisterArea
[3 * 10], CONTEXT_FLOATING_POINT
},
203 {&context
.FloatSave
.RegisterArea
[4 * 10], CONTEXT_FLOATING_POINT
},
204 {&context
.FloatSave
.RegisterArea
[5 * 10], CONTEXT_FLOATING_POINT
},
205 {&context
.FloatSave
.RegisterArea
[6 * 10], CONTEXT_FLOATING_POINT
},
206 {&context
.FloatSave
.RegisterArea
[7 * 10], CONTEXT_FLOATING_POINT
},
211 /* This vector maps the target's idea of an exception (extracted
212 from the DEBUG_EVENT structure) to GDB's idea. */
214 struct xlate_exception
217 enum target_signal us
;
221 static const struct xlate_exception
224 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
225 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
226 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
227 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
228 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
233 check (BOOL ok
, const char *file
, int line
)
236 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
240 child_fetch_inferior_registers (int r
)
244 for (r
= 0; r
< NUM_REGS
; r
++)
245 child_fetch_inferior_registers (r
);
249 supply_register (r
, mappings
[r
].incontext
);
254 child_store_inferior_registers (int r
)
258 for (r
= 0; r
< NUM_REGS
; r
++)
259 child_store_inferior_registers (r
);
263 read_register_gen (r
, mappings
[r
].incontext
);
268 /* Wait for child to do something. Return pid of child, or -1 in case
269 of error; store status through argument pointer OURSTATUS. */
273 handle_load_dll (char *eventp
)
275 DEBUG_EVENT
* event
= (DEBUG_EVENT
*)eventp
;
279 ReadProcessMemory (current_process
,
280 (DWORD
) event
->u
.LoadDll
.lpImageName
,
281 (char *) &dll_name_ptr
,
282 sizeof (dll_name_ptr
), &done
);
284 /* See if we could read the address of a string, and that the
285 address isn't null. */
287 if (done
== sizeof (dll_name_ptr
) && dll_name_ptr
)
289 char *dll_name
, *dll_basename
;
290 struct objfile
*objfile
;
291 char unix_dll_name
[MAX_PATH
];
292 int size
= event
->u
.LoadDll
.fUnicode
? sizeof (WCHAR
) : sizeof (char);
297 ReadProcessMemory (current_process
,
298 dll_name_ptr
+ len
* size
,
304 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
306 dll_name
= alloca (len
);
308 if (event
->u
.LoadDll
.fUnicode
)
310 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
311 ReadProcessMemory (current_process
,
314 len
* sizeof (WCHAR
),
317 WideCharToMultiByte (CP_ACP
, 0,
318 unicode_dll_name
, len
,
319 dll_name
, len
, 0, 0);
323 ReadProcessMemory (current_process
,
331 dos_path_to_unix_path (dll_name
, unix_dll_name
);
333 /* FIXME!! It would be nice to define one symbol which pointed to the
334 front of the dll if we can't find any symbols. */
336 if (!(dll_basename
= strrchr(dll_name
, '\\')))
337 dll_basename
= strrchr(dll_name
, '/');
339 ALL_OBJFILES(objfile
)
341 char *objfile_basename
;
342 if (!(objfile_basename
= strrchr(objfile
->name
, '\\')))
343 objfile_basename
= strrchr(objfile
->name
, '/');
345 if (dll_basename
&& objfile_basename
&&
346 strcmp(dll_basename
+1, objfile_basename
+1) == 0)
348 printf_unfiltered ("%s (symbols previously loaded)\n",
355 context
.ContextFlags
= CONTEXT_FULL
| CONTEXT_FLOATING_POINT
;
356 GetThreadContext (current_thread
, &context
);
358 /* The symbols in a dll are offset by 0x1000, which is the
359 the offset from 0 of the first byte in an image - because
360 of the file header and the section alignment.
362 FIXME: Is this the real reason that we need the 0x1000 ? */
365 symbol_file_add (unix_dll_name
, 0,
366 (int) event
->u
.LoadDll
.lpBaseOfDll
+ 0x1000, 0, 0, 0);
368 printf_unfiltered ("%x:%s\n", event
->u
.LoadDll
.lpBaseOfDll
,
376 handle_exception (DEBUG_EVENT
* event
, struct target_waitstatus
*ourstatus
)
380 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
383 switch (event
->u
.Exception
.ExceptionRecord
.ExceptionCode
)
385 case EXCEPTION_ACCESS_VIOLATION
:
386 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
387 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
388 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
390 case STATUS_STACK_OVERFLOW
:
391 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
392 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
393 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
395 case EXCEPTION_BREAKPOINT
:
396 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
397 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
398 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
401 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
402 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
403 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
405 case EXCEPTION_SINGLE_STEP
:
406 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
407 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
));
408 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
411 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
412 event
->u
.Exception
.ExceptionRecord
.ExceptionCode
,
413 event
->u
.Exception
.ExceptionRecord
.ExceptionAddress
);
414 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
417 context
.ContextFlags
= CONTEXT_FULL
| CONTEXT_FLOATING_POINT
;
418 GetThreadContext (current_thread
, &context
);
423 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
425 /* We loop when we get a non-standard exception rather than return
426 with a SPURIOUS because resume can try and step or modify things,
427 which needs a current_thread. But some of these exceptions mark
428 the birth or death of threads, which mean that the current thread
429 isn't necessarily what you think it is. */
434 BOOL t
= WaitForDebugEvent (&event
, INFINITE
);
439 current_thread_id
= event
.dwThreadId
;
440 current_process_id
= event
.dwProcessId
;
442 switch (event
.dwDebugEventCode
)
444 case CREATE_THREAD_DEBUG_EVENT
:
445 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
446 event
.dwProcessId
, event
.dwThreadId
,
447 "CREATE_THREAD_DEBUG_EVENT"));
449 case EXIT_THREAD_DEBUG_EVENT
:
450 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
451 event
.dwProcessId
, event
.dwThreadId
,
452 "EXIT_THREAD_DEBUG_EVENT"));
454 case CREATE_PROCESS_DEBUG_EVENT
:
455 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
456 event
.dwProcessId
, event
.dwThreadId
,
457 "CREATE_PROCESS_DEBUG_EVENT"));
460 case EXIT_PROCESS_DEBUG_EVENT
:
461 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
462 event
.dwProcessId
, event
.dwThreadId
,
463 "EXIT_PROCESS_DEBUG_EVENT"));
464 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
465 ourstatus
->value
.integer
= event
.u
.ExitProcess
.dwExitCode
;
466 CloseHandle (current_process
);
467 CloseHandle (current_thread
);
468 return current_process_id
;
471 case LOAD_DLL_DEBUG_EVENT
:
472 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
473 event
.dwProcessId
, event
.dwThreadId
,
474 "LOAD_DLL_DEBUG_EVENT"));
475 catch_errors (handle_load_dll
,
477 "\n[failed reading symbols from DLL]\n",
479 registers_changed(); /* mark all regs invalid */
481 case UNLOAD_DLL_DEBUG_EVENT
:
482 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
483 event
.dwProcessId
, event
.dwThreadId
,
484 "UNLOAD_DLL_DEBUG_EVENT"));
485 break; /* FIXME: don't know what to do here */
486 case EXCEPTION_DEBUG_EVENT
:
487 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
488 event
.dwProcessId
, event
.dwThreadId
,
489 "EXCEPTION_DEBUG_EVENT"));
490 handle_exception (&event
, ourstatus
);
491 return current_process_id
;
493 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
494 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
495 event
.dwProcessId
, event
.dwThreadId
,
496 "OUTPUT_DEBUG_STRING_EVENT"));
497 if (target_read_string
498 ((CORE_ADDR
) event
.u
.DebugString
.lpDebugStringData
,
499 &p
, 1024, 0) && p
&& *p
)
506 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
507 event
.dwProcessId
, event
.dwThreadId
);
508 printf_unfiltered (" unknown event code %d\n",
509 event
.dwDebugEventCode
);
512 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
513 current_process_id
, current_thread_id
));
514 CHECK (ContinueDebugEvent (current_process_id
,
521 /* Attach to process PID, then initialize for debugging it. */
524 child_attach (args
, from_tty
)
531 error_no_arg ("process-id to attach");
533 current_process_id
= strtoul (args
, 0, 0);
535 ok
= DebugActiveProcess (current_process_id
);
538 error ("Can't attach to process.");
546 char *exec_file
= (char *) get_exec_file (0);
549 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
550 target_pid_to_str (current_process_id
));
552 printf_unfiltered ("Attaching to %s\n",
553 target_pid_to_str (current_process_id
));
555 gdb_flush (gdb_stdout
);
558 inferior_pid
= current_process_id
;
559 push_target (&child_ops
);
564 child_detach (args
, from_tty
)
570 char *exec_file
= get_exec_file (0);
573 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
574 target_pid_to_str (inferior_pid
));
575 gdb_flush (gdb_stdout
);
578 unpush_target (&child_ops
);
582 /* Print status information about what we're accessing. */
585 child_files_info (ignore
)
586 struct target_ops
*ignore
;
588 printf_unfiltered ("\tUsing the running image of %s %s.\n",
589 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
594 child_open (arg
, from_tty
)
598 error ("Use the \"run\" command to start a Unix child process.");
601 /* Start an inferior win32 child process and sets inferior_pid to its pid.
602 EXEC_FILE is the file to run.
603 ALLARGS is a string containing the arguments to the program.
604 ENV is the environment vector to pass. Errors reported with error(). */
607 child_create_inferior (exec_file
, allargs
, env
)
612 char real_path
[MAXPATHLEN
];
619 PROCESS_INFORMATION pi
;
620 struct target_waitstatus dummy
;
627 error ("No executable specified, use `target exec'.\n");
630 memset (&si
, 0, sizeof (si
));
633 unix_path_to_dos_path (exec_file
, real_path
);
635 flags
= DEBUG_ONLY_THIS_PROCESS
;
638 flags
|= CREATE_NEW_PROCESS_GROUP
;
641 flags
|= CREATE_NEW_CONSOLE
;
643 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
645 strcpy (args
, real_path
);
648 strcat (args
, allargs
);
650 /* Prepare the environment vars for CreateProcess. */
652 /* This code use to assume all env vars were file names and would
653 translate them all to win32 style. That obviously doesn't work in the
654 general case. The current rule is that the user either works solely
655 with win32 style path names or with posix style path names and that
656 all env vars are already set up appropriately. At any rate it is
657 wrong for us to willy-nilly change them.
659 However, we need to handle PATH because we're about to call
660 CreateProcess and it uses PATH to find DLL's. Fortunately PATH
661 has a well-defined value in both posix and win32 environments.
662 cygwin.dll will change it back to posix style if necessary. If we're
663 working with win32 style path names, we don't need to do anything at
666 static const char *conv_path_names
[] =
671 int posix_rules_p
= sysconf (_SC_PATH_RULES
) == _PATH_RULES_POSIX
;
673 /* CreateProcess takes the environment list as a null terminated set of
674 strings (i.e. two nulls terminate the list). */
676 /* Get total size for env strings. */
677 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
683 for (j
= 0; conv_path_names
[j
]; j
++)
685 len
= strlen (conv_path_names
[j
]);
686 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
689 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
693 if (conv_path_names
[j
] == NULL
)
694 envlen
+= strlen (env
[i
]) + 1;
697 envlen
+= strlen (env
[i
]) + 1;
700 winenv
= alloca (envlen
+ 1);
702 /* Copy env strings into new buffer. */
703 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 memcpy (temp
, env
[i
], len
);
715 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
719 if (conv_path_names
[j
] == NULL
)
720 strcpy (temp
, env
[i
]);
723 strcpy (temp
, env
[i
]);
724 temp
+= strlen (temp
) + 1;
727 /* Final nil string to terminate new env. */
731 ret
= CreateProcess (0,
732 args
, /* command line */
735 TRUE
, /* inherit handles */
736 flags
, /* start flags */
738 NULL
, /* current directory */
742 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError());
747 inferior_pid
= pi
.dwProcessId
;
748 current_process
= pi
.hProcess
;
749 current_thread
= pi
.hThread
;
750 current_process_id
= pi
.dwProcessId
;
751 current_thread_id
= pi
.dwThreadId
;
752 push_target (&child_ops
);
754 init_wait_for_inferior ();
755 clear_proceed_status ();
756 target_terminal_init ();
757 target_terminal_inferior ();
759 /* Ignore the first trap */
760 child_wait (inferior_pid
, &dummy
);
762 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
766 child_mourn_inferior ()
768 unpush_target (&child_ops
);
769 generic_mourn_inferior ();
773 /* Send a SIGINT to the process group. This acts just like the user typed a
774 ^C on the controlling terminal. */
779 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
780 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0));
781 registers_changed(); /* refresh register state */
785 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
786 int write
, struct target_ops
*target
)
791 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
793 WriteProcessMemory (current_process
, memaddr
, our
, len
, &done
);
794 FlushInstructionCache (current_process
, memaddr
, len
);
798 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
800 ReadProcessMemory (current_process
, memaddr
, our
, len
, &done
);
806 child_kill_inferior (void)
808 CHECK (TerminateProcess (current_process
, 0));
809 CHECK (CloseHandle (current_process
));
810 CHECK (CloseHandle (current_thread
));
811 target_mourn_inferior(); /* or just child_mourn_inferior? */
815 child_resume (int pid
, int step
, enum target_signal signal
)
817 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, signal=%d);\n",
823 warning ("Single stepping not done.\n");
826 /* Single step by setting t bit */
827 child_fetch_inferior_registers (PS_REGNUM
);
828 context
.EFlags
|= FLAG_TRACE_BIT
;
832 if (context
.ContextFlags
)
834 CHECK (SetThreadContext (current_thread
, &context
));
835 context
.ContextFlags
= 0;
840 fprintf_unfiltered (gdb_stderr
, "Can't send signals to the child.\n");
843 DEBUG_EVENTS (("gdb: ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
844 current_process_id
, current_thread_id
));
845 CHECK (ContinueDebugEvent (current_process_id
,
851 child_prepare_to_store ()
853 /* Do nothing, since we can store individual regs */
865 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
868 struct target_ops child_ops
=
870 "child", /* to_shortname */
871 "Win32 child process", /* to_longname */
872 "Win32 child process (started by the \"run\" command).", /* to_doc */
873 child_open
, /* to_open */
874 child_close
, /* to_close */
875 child_attach
, /* to_attach */
876 child_detach
, /* to_detach */
877 child_resume
, /* to_resume */
878 child_wait
, /* to_wait */
879 child_fetch_inferior_registers
,/* to_fetch_registers */
880 child_store_inferior_registers
,/* to_store_registers */
881 child_prepare_to_store
, /* to_child_prepare_to_store */
882 child_xfer_memory
, /* to_xfer_memory */
883 child_files_info
, /* to_files_info */
884 memory_insert_breakpoint
, /* to_insert_breakpoint */
885 memory_remove_breakpoint
, /* to_remove_breakpoint */
886 terminal_init_inferior
, /* to_terminal_init */
887 terminal_inferior
, /* to_terminal_inferior */
888 terminal_ours_for_output
, /* to_terminal_ours_for_output */
889 terminal_ours
, /* to_terminal_ours */
890 child_terminal_info
, /* to_terminal_info */
891 child_kill_inferior
, /* to_kill */
893 0, /* to_lookup_symbol */
894 child_create_inferior
, /* to_create_inferior */
895 child_mourn_inferior
, /* to_mourn_inferior */
896 child_can_run
, /* to_can_run */
897 0, /* to_notice_signals */
898 0, /* to_thread_alive */
899 child_stop
, /* to_stop */
900 process_stratum
, /* to_stratum */
902 1, /* to_has_all_memory */
903 1, /* to_has_memory */
904 1, /* to_has_stack */
905 1, /* to_has_registers */
906 1, /* to_has_execution */
908 0, /* to_sections_end */
909 OPS_MAGIC
/* to_magic */
913 _initialize_inftarg ()
915 struct cmd_list_element
*c
;
918 (add_set_cmd ("new-console", class_support
, var_boolean
,
919 (char *) &new_console
,
920 "Set creation of new console when creating child process.",
925 (add_set_cmd ("new-group", class_support
, var_boolean
,
927 "Set creation of new group when creating child process.",
932 (add_set_cmd ("debugexec", class_support
, var_boolean
,
933 (char *) &debug_exec
,
934 "Set whether to display execution in child process.",
939 (add_set_cmd ("debugevents", class_support
, var_boolean
,
940 (char *) &debug_events
,
941 "Set whether to display kernel events in child process.",
946 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
947 (char *) &debug_memory
,
948 "Set whether to display memory accesses in child process.",
953 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
954 (char *) &debug_exceptions
,
955 "Set whether to display kernel exceptions in child process.",
959 add_target (&child_ops
);