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,
20 Boston, MA 02111-1307, USA.
23 /* by Steve Chamberlain, sac@cygnus.com */
25 /* We assume we're being built with and will be used for cygwin. */
28 #include "frame.h" /* required by inferior.h */
35 #include <sys/types.h>
41 #else /* other WIN32 compiler */
48 #include "gdb_string.h"
49 #include "gdbthread.h"
51 #include <sys/param.h>
53 /* The ui's event loop. */
54 extern int (*ui_loop_hook
) PARAMS ((int signo
));
56 /* If we're not using the old Cygwin header file set, define the
57 following which never should have been in the generic Win32 API
58 headers in the first place since they were our own invention... */
59 #ifndef _GNU_H_WINDOWS_H
60 #define FLAG_TRACE_BIT 0x100
61 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
64 /* The string sent by cygwin when it processes a signal.
65 FIXME: This should be in a cygwin include file. */
66 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
68 #define CHECK(x) check (x, __FILE__,__LINE__)
69 #define DEBUG_EXEC(x) if (debug_exec) printf x
70 #define DEBUG_EVENTS(x) if (debug_events) printf x
71 #define DEBUG_MEM(x) if (debug_memory) printf x
72 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
74 /* Forward declaration */
75 extern struct target_ops child_ops
;
77 static void child_stop
PARAMS ((void));
78 static int win32_child_thread_alive
PARAMS ((int));
79 void child_kill_inferior
PARAMS ((void));
81 static int last_sig
= 0; /* Set if a signal was received from the
84 /* Thread information structure used to track information that is
85 not available in gdb's thread structure. */
86 typedef struct thread_info_struct
88 struct thread_info_struct
*next
;
97 static thread_info thread_head
=
100 /* The process and thread handles for the above context. */
102 static DEBUG_EVENT current_event
; /* The current debug event from
104 static HANDLE current_process_handle
; /* Currently executing process */
105 static thread_info
*current_thread
; /* Info on currently selected thread */
106 static DWORD main_thread_id
; /* Thread ID of the main thread */
108 /* Counts of things. */
109 static int exception_count
= 0;
110 static int event_count
= 0;
113 static int new_console
= 0;
114 static int new_group
= 0;
115 static int debug_exec
= 0; /* show execution */
116 static int debug_events
= 0; /* show events from kernel */
117 static int debug_memory
= 0; /* show target memory accesses */
118 static int debug_exceptions
= 0; /* show target exceptions */
120 /* This vector maps GDB's idea of a register's number into an address
121 in the win32 exception context vector.
123 It also contains the bit mask needed to load the register in question.
125 One day we could read a reg, we could inspect the context we
126 already have loaded, if it doesn't have the bit set that we need,
127 we read that set of registers in using GetThreadContext. If the
128 context already contains what we need, we just unpack it. Then to
129 write a register, first we have to ensure that the context contains
130 the other regs of the group, and then we copy the info in and set
133 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
134 static const int mappings
[] =
136 context_offset (Eax
),
137 context_offset (Ecx
),
138 context_offset (Edx
),
139 context_offset (Ebx
),
140 context_offset (Esp
),
141 context_offset (Ebp
),
142 context_offset (Esi
),
143 context_offset (Edi
),
144 context_offset (Eip
),
145 context_offset (EFlags
),
146 context_offset (SegCs
),
147 context_offset (SegSs
),
148 context_offset (SegDs
),
149 context_offset (SegEs
),
150 context_offset (SegFs
),
151 context_offset (SegGs
),
152 context_offset (FloatSave
.RegisterArea
[0 * 10]),
153 context_offset (FloatSave
.RegisterArea
[1 * 10]),
154 context_offset (FloatSave
.RegisterArea
[2 * 10]),
155 context_offset (FloatSave
.RegisterArea
[3 * 10]),
156 context_offset (FloatSave
.RegisterArea
[4 * 10]),
157 context_offset (FloatSave
.RegisterArea
[5 * 10]),
158 context_offset (FloatSave
.RegisterArea
[6 * 10]),
159 context_offset (FloatSave
.RegisterArea
[7 * 10]),
162 /* This vector maps the target's idea of an exception (extracted
163 from the DEBUG_EVENT structure) to GDB's idea. */
165 struct xlate_exception
168 enum target_signal us
;
171 static const struct xlate_exception
174 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
175 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
176 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
177 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
178 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
181 /* Find a thread record given a thread id.
182 If get_context then also retrieve the context for this
185 thread_rec (DWORD id
, int get_context
)
189 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
192 if (!th
->suspend_count
&& get_context
)
195 th
->suspend_count
= SuspendThread (th
->h
) + 1;
196 else if (get_context
< 0)
197 th
->suspend_count
= -1;
199 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
200 GetThreadContext (th
->h
, &th
->context
);
208 /* Add a thread to the thread list */
210 child_add_thread (DWORD id
, HANDLE h
)
214 if ((th
= thread_rec (id
, FALSE
)))
217 th
= (thread_info
*) xmalloc (sizeof (*th
));
218 memset (th
, 0, sizeof (*th
));
221 th
->next
= thread_head
.next
;
222 thread_head
.next
= th
;
227 /* Clear out any old thread list and reintialize it to a
230 child_init_thread_list ()
232 thread_info
*th
= &thread_head
;
234 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
236 while (th
->next
!= NULL
)
238 thread_info
*here
= th
->next
;
239 th
->next
= here
->next
;
240 (void) CloseHandle (here
->h
);
245 /* Delete a thread from the list of threads */
247 child_delete_thread (DWORD id
)
252 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
255 for (th
= &thread_head
;
256 th
->next
!= NULL
&& th
->next
->id
!= id
;
260 if (th
->next
!= NULL
)
262 thread_info
*here
= th
->next
;
263 th
->next
= here
->next
;
264 CloseHandle (here
->h
);
270 check (BOOL ok
, const char *file
, int line
)
273 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
277 do_child_fetch_inferior_registers (int r
)
280 supply_register (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
283 for (r
= 0; r
< NUM_REGS
; r
++)
284 do_child_fetch_inferior_registers (r
);
289 child_fetch_inferior_registers (int r
)
291 current_thread
= thread_rec (inferior_pid
, TRUE
);
292 do_child_fetch_inferior_registers (r
);
296 do_child_store_inferior_registers (int r
)
299 read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
302 for (r
= 0; r
< NUM_REGS
; r
++)
303 do_child_store_inferior_registers (r
);
307 /* Store a new register value into the current thread context */
309 child_store_inferior_registers (int r
)
311 current_thread
= thread_rec (inferior_pid
, TRUE
);
312 do_child_store_inferior_registers (r
);
315 /* Wait for child to do something. Return pid of child, or -1 in case
316 of error; store status through argument pointer OURSTATUS. */
319 handle_load_dll (PTR dummy
)
321 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
324 char dll_buf
[MAX_PATH
+ 1];
325 char *p
, *dll_name
= NULL
;
326 struct objfile
*objfile
;
327 MEMORY_BASIC_INFORMATION minfo
;
329 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
331 /* The following code attempts to find the name of the dll by reading the
332 name from the processes memory. Unfortunately it doesn't work right.
333 Doing this the "right way" for Windows is very difficult. FIXME */
335 memset (&minfo
, 0, sizeof minfo
);
336 if (VirtualQueryEx (current_process_handle
, (LPCVOID
) event
->lpBaseOfDll
,
337 &minfo
, sizeof (minfo
)) && minfo
.BaseAddress
)
340 IMAGE_DOS_HEADER
*hmm0
= (IMAGE_DOS_HEADER
*) minfo
.BaseAddress
;
341 HMODULE hmm
= (HMODULE
) (((DWORD
) hmm0
) + hmm0
->e_lfanew
);
343 if ((len
= GetModuleFileName (hmm
, dll_buf
, MAX_PATH
)))
346 dll_name
[len
] = '\0';
351 /* Attempt to read the name of the dll that was detected.
352 This is documented to work only when actively debugging
353 a program. It will not work for attached processes. */
354 if (dll_name
== NULL
|| *dll_name
== '\0')
356 int size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
360 ReadProcessMemory (current_process_handle
,
361 (LPCVOID
) event
->lpImageName
,
362 (char *) &dll_name_ptr
,
363 sizeof (dll_name_ptr
), &done
);
365 /* See if we could read the address of a string, and that the
366 address isn't null. */
368 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
373 ReadProcessMemory (current_process_handle
,
374 (LPCVOID
) (dll_name_ptr
+ len
* size
),
380 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
382 dll_name
= alloca (len
);
386 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
387 ReadProcessMemory (current_process_handle
,
388 (LPCVOID
) dll_name_ptr
,
390 len
* sizeof (WCHAR
),
393 WideCharToMultiByte (CP_ACP
, 0,
394 unicode_dll_name
, len
,
395 dll_name
, len
, 0, 0);
399 ReadProcessMemory (current_process_handle
,
400 (LPCVOID
) dll_name_ptr
,
410 while ((p
= strchr (dll_name
, '\\')))
413 /* The symbols in a dll are offset by 0x1000, which is the
414 the offset from 0 of the first byte in an image - because
415 of the file header and the section alignment.
417 FIXME: Is this the real reason that we need the 0x1000 ? */
419 printf_unfiltered ("%x:%s", event
->lpBaseOfDll
, dll_name
);
420 symbol_file_add (dll_name
, 0, (int) event
->lpBaseOfDll
+ 0x1000, 0, 0, 0, 0, 1);
421 printf_unfiltered ("\n");
426 /* Handle DEBUG_STRING output from child process.
427 Cygwin prepends its messages with a "cygwin:". Interpret this as
428 a Cygwin signal. Otherwise just print the string as a warning. */
430 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
435 if (!target_read_string
436 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
440 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1))
447 /*last_sig = */ strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
448 gotasig
= target_signal_from_host (last_sig
);
449 ourstatus
->value
.sig
= gotasig
;
451 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
459 handle_exception (struct target_waitstatus
*ourstatus
)
465 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
467 /* Record the context of the current thread */
468 th
= thread_rec (current_event
.dwThreadId
, -1);
470 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
472 case EXCEPTION_ACCESS_VIOLATION
:
473 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
474 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
475 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
477 case STATUS_STACK_OVERFLOW
:
478 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
479 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
480 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
482 case EXCEPTION_BREAKPOINT
:
483 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
484 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
485 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
488 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
489 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
490 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
491 /* User typed CTRL-C. Continue with this status */
492 last_sig
= SIGINT
; /* FIXME - should check pass state */
494 case EXCEPTION_SINGLE_STEP
:
495 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
496 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
497 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
500 /* This may be a structured exception handling exception. In
501 that case, we want to let the program try to handle it, and
502 only break if we see the exception a second time. */
503 if (current_event
.u
.Exception
.dwFirstChance
)
506 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
507 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
508 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
509 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
516 /* Resume all artificially suspended threads if we are continuing
519 child_continue (DWORD continue_status
, int id
)
525 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
526 current_event
.dwProcessId
, current_event
.dwThreadId
));
527 res
= ContinueDebugEvent (current_event
.dwProcessId
,
528 current_event
.dwThreadId
,
531 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
532 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
534 for (i
= 0; i
< th
->suspend_count
; i
++)
535 (void) ResumeThread (th
->h
);
536 th
->suspend_count
= 0;
543 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
545 /* We loop when we get a non-standard exception rather than return
546 with a SPURIOUS because resume can try and step or modify things,
547 which needs a current_thread->h. But some of these exceptions mark
548 the birth or death of threads, which mean that the current thread
549 isn't necessarily what you think it is. */
553 DWORD continue_status
;
554 BOOL debug_event
= WaitForDebugEvent (¤t_event
, 20);
563 continue_status
= DBG_CONTINUE
;
565 switch (current_event
.dwDebugEventCode
)
567 case CREATE_THREAD_DEBUG_EVENT
:
568 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
569 current_event
.dwProcessId
, current_event
.dwThreadId
,
570 "CREATE_THREAD_DEBUG_EVENT"));
571 /* Record the existence of this thread */
572 child_add_thread (current_event
.dwThreadId
,
573 current_event
.u
.CreateThread
.hThread
);
575 printf_unfiltered ("[New %s]\n",
576 target_pid_to_str (current_event
.dwThreadId
));
579 case EXIT_THREAD_DEBUG_EVENT
:
580 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
581 current_event
.dwProcessId
, current_event
.dwThreadId
,
582 "EXIT_THREAD_DEBUG_EVENT"));
583 child_delete_thread (current_event
.dwThreadId
);
586 case CREATE_PROCESS_DEBUG_EVENT
:
587 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
588 current_event
.dwProcessId
, current_event
.dwThreadId
,
589 "CREATE_PROCESS_DEBUG_EVENT"));
590 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
592 main_thread_id
= inferior_pid
= current_event
.dwThreadId
;
593 /* Add the main thread */
594 current_thread
= child_add_thread (inferior_pid
,
595 current_event
.u
.CreateProcessInfo
.hThread
);
598 case EXIT_PROCESS_DEBUG_EVENT
:
599 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
600 current_event
.dwProcessId
, current_event
.dwThreadId
,
601 "EXIT_PROCESS_DEBUG_EVENT"));
602 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
603 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
604 CloseHandle (current_process_handle
);
605 return current_event
.dwProcessId
;
608 case LOAD_DLL_DEBUG_EVENT
:
609 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
610 current_event
.dwProcessId
, current_event
.dwThreadId
,
611 "LOAD_DLL_DEBUG_EVENT"));
612 catch_errors (handle_load_dll
, NULL
, "", RETURN_MASK_ALL
);
613 registers_changed (); /* mark all regs invalid */
616 case UNLOAD_DLL_DEBUG_EVENT
:
617 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
618 current_event
.dwProcessId
, current_event
.dwThreadId
,
619 "UNLOAD_DLL_DEBUG_EVENT"));
620 break; /* FIXME: don't know what to do here */
622 case EXCEPTION_DEBUG_EVENT
:
623 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
624 current_event
.dwProcessId
, current_event
.dwThreadId
,
625 "EXCEPTION_DEBUG_EVENT"));
626 if (handle_exception (ourstatus
))
627 return current_event
.dwThreadId
;
628 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
631 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
632 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
633 current_event
.dwProcessId
, current_event
.dwThreadId
,
634 "OUTPUT_DEBUG_STRING_EVENT"));
635 if (handle_output_debug_string (ourstatus
))
636 return main_thread_id
;
639 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
640 current_event
.dwProcessId
,
641 current_event
.dwThreadId
);
642 printf_unfiltered (" unknown event code %d\n",
643 current_event
.dwDebugEventCode
);
647 CHECK (child_continue (continue_status
, -1));
653 if (ui_loop_hook
!= NULL
)
654 detach
= ui_loop_hook (0);
657 child_kill_inferior ();
662 /* Attach to process PID, then initialize for debugging it. */
665 child_attach (args
, from_tty
)
672 error_no_arg ("process-id to attach");
674 current_event
.dwProcessId
= strtoul (args
, 0, 0);
676 ok
= DebugActiveProcess (current_event
.dwProcessId
);
679 error ("Can't attach to process.");
686 char *exec_file
= (char *) get_exec_file (0);
689 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
690 target_pid_to_str (current_event
.dwProcessId
));
692 printf_unfiltered ("Attaching to %s\n",
693 target_pid_to_str (current_event
.dwProcessId
));
695 gdb_flush (gdb_stdout
);
698 push_target (&child_ops
);
702 child_detach (args
, from_tty
)
708 char *exec_file
= get_exec_file (0);
711 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
712 target_pid_to_str (inferior_pid
));
713 gdb_flush (gdb_stdout
);
716 unpush_target (&child_ops
);
719 /* Print status information about what we're accessing. */
722 child_files_info (ignore
)
723 struct target_ops
*ignore
;
725 printf_unfiltered ("\tUsing the running image of %s %s.\n",
726 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
731 child_open (arg
, from_tty
)
735 error ("Use the \"run\" command to start a Unix child process.");
738 /* Start an inferior win32 child process and sets inferior_pid to its pid.
739 EXEC_FILE is the file to run.
740 ALLARGS is a string containing the arguments to the program.
741 ENV is the environment vector to pass. Errors reported with error(). */
744 child_create_inferior (exec_file
, allargs
, env
)
749 char real_path
[MAXPATHLEN
];
756 PROCESS_INFORMATION pi
;
757 struct target_waitstatus dummy
;
764 error ("No executable specified, use `target exec'.\n");
767 memset (&si
, 0, sizeof (si
));
770 cygwin32_conv_to_win32_path (exec_file
, real_path
);
772 flags
= DEBUG_ONLY_THIS_PROCESS
;
775 flags
|= CREATE_NEW_PROCESS_GROUP
;
778 flags
|= CREATE_NEW_CONSOLE
;
780 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
782 strcpy (args
, real_path
);
785 strcat (args
, allargs
);
787 /* Prepare the environment vars for CreateProcess. */
789 /* This code use to assume all env vars were file names and would
790 translate them all to win32 style. That obviously doesn't work in the
791 general case. The current rule is that we only translate PATH.
792 We need to handle PATH because we're about to call CreateProcess and
793 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
794 in both posix and win32 environments. cygwin.dll will change it back
795 to posix style if necessary. */
797 static const char *conv_path_names
[] =
803 /* CreateProcess takes the environment list as a null terminated set of
804 strings (i.e. two nulls terminate the list). */
806 /* Get total size for env strings. */
807 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
811 for (j
= 0; conv_path_names
[j
]; j
++)
813 len
= strlen (conv_path_names
[j
]);
814 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
816 if (cygwin32_posix_path_list_p (env
[i
] + len
))
818 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
820 envlen
+= strlen (env
[i
]) + 1;
824 if (conv_path_names
[j
] == NULL
)
825 envlen
+= strlen (env
[i
]) + 1;
828 winenv
= alloca (envlen
+ 1);
830 /* Copy env strings into new buffer. */
831 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
835 for (j
= 0; conv_path_names
[j
]; j
++)
837 len
= strlen (conv_path_names
[j
]);
838 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
840 if (cygwin32_posix_path_list_p (env
[i
] + len
))
842 memcpy (temp
, env
[i
], len
);
843 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
846 strcpy (temp
, env
[i
]);
850 if (conv_path_names
[j
] == NULL
)
851 strcpy (temp
, env
[i
]);
853 temp
+= strlen (temp
) + 1;
856 /* Final nil string to terminate new env. */
860 ret
= CreateProcess (0,
861 args
, /* command line */
864 TRUE
, /* inherit handles */
865 flags
, /* start flags */
867 NULL
, /* current directory */
871 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError ());
876 current_process_handle
= pi
.hProcess
;
877 current_event
.dwProcessId
= pi
.dwProcessId
;
878 memset (¤t_event
, 0, sizeof (current_event
));
879 inferior_pid
= current_event
.dwThreadId
= pi
.dwThreadId
;
880 push_target (&child_ops
);
881 child_init_thread_list ();
882 init_wait_for_inferior ();
883 clear_proceed_status ();
884 target_terminal_init ();
885 target_terminal_inferior ();
887 /* Ignore the first trap */
888 child_wait (inferior_pid
, &dummy
);
890 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
894 child_mourn_inferior ()
896 (void) child_continue (DBG_CONTINUE
, -1);
897 unpush_target (&child_ops
);
898 generic_mourn_inferior ();
901 /* Send a SIGINT to the process group. This acts just like the user typed a
902 ^C on the controlling terminal. */
907 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
908 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0));
909 registers_changed (); /* refresh register state */
913 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
914 int write
, struct target_ops
*target
)
919 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
921 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
923 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
927 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
929 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
936 child_kill_inferior (void)
938 CHECK (TerminateProcess (current_process_handle
, 0));
942 if (!child_continue (DBG_CONTINUE
, -1))
944 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
946 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
950 CHECK (CloseHandle (current_process_handle
));
952 /* this may fail in an attached process so don't check. */
953 (void) CloseHandle (current_thread
->h
);
954 target_mourn_inferior (); /* or just child_mourn_inferior? */
958 child_resume (int pid
, int step
, enum target_signal sig
)
962 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
963 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
965 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
968 /* Get context for currently selected thread */
969 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
973 /* Single step by setting t bit */
974 child_fetch_inferior_registers (PS_REGNUM
);
975 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
979 if (th
->context
.ContextFlags
)
981 CHECK (SetThreadContext (th
->h
, &th
->context
));
982 th
->context
.ContextFlags
= 0;
985 /* Allow continuing with the same signal that interrupted us.
986 Otherwise complain. */
987 if (sig
&& sig
!= last_sig
)
988 fprintf_unfiltered (gdb_stderr
, "Can't send signals to the child. signal %d\n", sig
);
991 child_continue (continue_status
, pid
);
995 child_prepare_to_store ()
997 /* Do nothing, since we can store individual regs */
1009 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1012 struct target_ops child_ops
;
1015 init_child_ops (void)
1017 child_ops
.to_shortname
= "child";
1018 child_ops
.to_longname
= "Win32 child process";
1019 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1020 child_ops
.to_open
= child_open
;
1021 child_ops
.to_close
= child_close
;
1022 child_ops
.to_attach
= child_attach
;
1023 child_ops
.to_detach
= child_detach
;
1024 child_ops
.to_resume
= child_resume
;
1025 child_ops
.to_wait
= child_wait
;
1026 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1027 child_ops
.to_store_registers
= child_store_inferior_registers
;
1028 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1029 child_ops
.to_xfer_memory
= child_xfer_memory
;
1030 child_ops
.to_files_info
= child_files_info
;
1031 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1032 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1033 child_ops
.to_terminal_init
= terminal_init_inferior
;
1034 child_ops
.to_terminal_inferior
= terminal_inferior
;
1035 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1036 child_ops
.to_terminal_ours
= terminal_ours
;
1037 child_ops
.to_terminal_info
= child_terminal_info
;
1038 child_ops
.to_kill
= child_kill_inferior
;
1039 child_ops
.to_load
= 0;
1040 child_ops
.to_lookup_symbol
= 0;
1041 child_ops
.to_create_inferior
= child_create_inferior
;
1042 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1043 child_ops
.to_can_run
= child_can_run
;
1044 child_ops
.to_notice_signals
= 0;
1045 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1046 child_ops
.to_stop
= child_stop
;
1047 child_ops
.to_stratum
= process_stratum
;
1048 child_ops
.DONT_USE
= 0;
1049 child_ops
.to_has_all_memory
= 1;
1050 child_ops
.to_has_memory
= 1;
1051 child_ops
.to_has_stack
= 1;
1052 child_ops
.to_has_registers
= 1;
1053 child_ops
.to_has_execution
= 1;
1054 child_ops
.to_sections
= 0;
1055 child_ops
.to_sections_end
= 0;
1056 child_ops
.to_magic
= OPS_MAGIC
;
1060 _initialize_inftarg ()
1062 struct cmd_list_element
*c
;
1066 (add_set_cmd ("new-console", class_support
, var_boolean
,
1067 (char *) &new_console
,
1068 "Set creation of new console when creating child process.",
1073 (add_set_cmd ("new-group", class_support
, var_boolean
,
1074 (char *) &new_group
,
1075 "Set creation of new group when creating child process.",
1080 (add_set_cmd ("debugexec", class_support
, var_boolean
,
1081 (char *) &debug_exec
,
1082 "Set whether to display execution in child process.",
1087 (add_set_cmd ("debugevents", class_support
, var_boolean
,
1088 (char *) &debug_events
,
1089 "Set whether to display kernel events in child process.",
1094 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1095 (char *) &debug_memory
,
1096 "Set whether to display memory accesses in child process.",
1101 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1102 (char *) &debug_exceptions
,
1103 "Set whether to display kernel exceptions in child process.",
1107 add_target (&child_ops
);
1110 /* Determine if the thread referenced by "pid" is alive
1111 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1112 it means that the pid has died. Otherwise it is assumed to be alive. */
1114 win32_child_thread_alive (int pid
)
1116 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1120 /* Convert pid to printable format. */
1122 cygwin_pid_to_str (int pid
)
1124 static char buf
[80];
1125 if (pid
== current_event
.dwProcessId
)
1126 sprintf (buf
, "process %d", pid
);
1128 sprintf (buf
, "thread %d.0x%x", current_event
.dwProcessId
, pid
);