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
;
328 struct section_addr_info section_addrs
;
330 memset (§ion_addrs
, 0, sizeof (section_addrs
));
331 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
333 /* The following code attempts to find the name of the dll by reading the
334 name from the processes memory. Unfortunately it doesn't work right.
335 Doing this the "right way" for Windows is very difficult. FIXME */
337 memset (&minfo
, 0, sizeof minfo
);
338 if (VirtualQueryEx (current_process_handle
, (LPCVOID
) event
->lpBaseOfDll
,
339 &minfo
, sizeof (minfo
)) && minfo
.BaseAddress
)
342 IMAGE_DOS_HEADER
*hmm0
= (IMAGE_DOS_HEADER
*) minfo
.BaseAddress
;
343 HMODULE hmm
= (HMODULE
) (((DWORD
) hmm0
) + hmm0
->e_lfanew
);
345 if ((len
= GetModuleFileName (hmm
, dll_buf
, MAX_PATH
)))
348 dll_name
[len
] = '\0';
353 /* Attempt to read the name of the dll that was detected.
354 This is documented to work only when actively debugging
355 a program. It will not work for attached processes. */
356 if (dll_name
== NULL
|| *dll_name
== '\0')
358 int size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
362 ReadProcessMemory (current_process_handle
,
363 (LPCVOID
) event
->lpImageName
,
364 (char *) &dll_name_ptr
,
365 sizeof (dll_name_ptr
), &done
);
367 /* See if we could read the address of a string, and that the
368 address isn't null. */
370 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
375 ReadProcessMemory (current_process_handle
,
376 (LPCVOID
) (dll_name_ptr
+ len
* size
),
382 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
384 dll_name
= alloca (len
);
388 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
389 ReadProcessMemory (current_process_handle
,
390 (LPCVOID
) dll_name_ptr
,
392 len
* sizeof (WCHAR
),
395 WideCharToMultiByte (CP_ACP
, 0,
396 unicode_dll_name
, len
,
397 dll_name
, len
, 0, 0);
401 ReadProcessMemory (current_process_handle
,
402 (LPCVOID
) dll_name_ptr
,
412 while ((p
= strchr (dll_name
, '\\')))
415 /* The symbols in a dll are offset by 0x1000, which is the
416 the offset from 0 of the first byte in an image - because
417 of the file header and the section alignment.
419 FIXME: Is this the real reason that we need the 0x1000 ? */
421 printf_unfiltered ("%x:%s", event
->lpBaseOfDll
, dll_name
);
422 section_addrs
.text_addr
= (int) event
->lpBaseOfDll
+ 0x1000;
423 symbol_file_add (dll_name
, 0, §ion_addrs
, 0, 0, 0, 1);
424 printf_unfiltered ("\n");
429 /* Handle DEBUG_STRING output from child process.
430 Cygwin prepends its messages with a "cygwin:". Interpret this as
431 a Cygwin signal. Otherwise just print the string as a warning. */
433 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
438 if (!target_read_string
439 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
443 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1))
450 /*last_sig = */ strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
451 gotasig
= target_signal_from_host (last_sig
);
452 ourstatus
->value
.sig
= gotasig
;
454 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
462 handle_exception (struct target_waitstatus
*ourstatus
)
468 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
470 /* Record the context of the current thread */
471 th
= thread_rec (current_event
.dwThreadId
, -1);
473 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
475 case EXCEPTION_ACCESS_VIOLATION
:
476 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
477 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
478 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
480 case STATUS_STACK_OVERFLOW
:
481 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
482 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
483 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
485 case EXCEPTION_BREAKPOINT
:
486 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
487 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
488 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
491 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
492 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
493 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
494 /* User typed CTRL-C. Continue with this status */
495 last_sig
= SIGINT
; /* FIXME - should check pass state */
497 case EXCEPTION_SINGLE_STEP
:
498 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
499 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
500 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
503 /* This may be a structured exception handling exception. In
504 that case, we want to let the program try to handle it, and
505 only break if we see the exception a second time. */
506 if (current_event
.u
.Exception
.dwFirstChance
)
509 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
510 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
511 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
512 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
519 /* Resume all artificially suspended threads if we are continuing
522 child_continue (DWORD continue_status
, int id
)
528 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
529 current_event
.dwProcessId
, current_event
.dwThreadId
));
530 res
= ContinueDebugEvent (current_event
.dwProcessId
,
531 current_event
.dwThreadId
,
534 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
535 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
537 for (i
= 0; i
< th
->suspend_count
; i
++)
538 (void) ResumeThread (th
->h
);
539 th
->suspend_count
= 0;
546 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
548 /* We loop when we get a non-standard exception rather than return
549 with a SPURIOUS because resume can try and step or modify things,
550 which needs a current_thread->h. But some of these exceptions mark
551 the birth or death of threads, which mean that the current thread
552 isn't necessarily what you think it is. */
556 DWORD continue_status
;
557 BOOL debug_event
= WaitForDebugEvent (¤t_event
, 20);
566 continue_status
= DBG_CONTINUE
;
568 switch (current_event
.dwDebugEventCode
)
570 case CREATE_THREAD_DEBUG_EVENT
:
571 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
572 current_event
.dwProcessId
, current_event
.dwThreadId
,
573 "CREATE_THREAD_DEBUG_EVENT"));
574 /* Record the existence of this thread */
575 child_add_thread (current_event
.dwThreadId
,
576 current_event
.u
.CreateThread
.hThread
);
578 printf_unfiltered ("[New %s]\n",
579 target_pid_to_str (current_event
.dwThreadId
));
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
);
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 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
595 main_thread_id
= inferior_pid
= current_event
.dwThreadId
;
596 /* Add the main thread */
597 current_thread
= child_add_thread (inferior_pid
,
598 current_event
.u
.CreateProcessInfo
.hThread
);
601 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 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
607 CloseHandle (current_process_handle
);
608 return current_event
.dwProcessId
;
611 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 */
619 case UNLOAD_DLL_DEBUG_EVENT
:
620 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
621 current_event
.dwProcessId
, current_event
.dwThreadId
,
622 "UNLOAD_DLL_DEBUG_EVENT"));
623 break; /* FIXME: don't know what to do here */
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 if (handle_exception (ourstatus
))
630 return current_event
.dwThreadId
;
631 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
634 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
635 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 if (handle_output_debug_string (ourstatus
))
639 return main_thread_id
;
642 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
643 current_event
.dwProcessId
,
644 current_event
.dwThreadId
);
645 printf_unfiltered (" unknown event code %d\n",
646 current_event
.dwDebugEventCode
);
650 CHECK (child_continue (continue_status
, -1));
656 if (ui_loop_hook
!= NULL
)
657 detach
= ui_loop_hook (0);
660 child_kill_inferior ();
665 /* Attach to process PID, then initialize for debugging it. */
668 child_attach (args
, from_tty
)
675 error_no_arg ("process-id to attach");
677 current_event
.dwProcessId
= strtoul (args
, 0, 0);
679 ok
= DebugActiveProcess (current_event
.dwProcessId
);
682 error ("Can't attach to process.");
689 char *exec_file
= (char *) get_exec_file (0);
692 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
693 target_pid_to_str (current_event
.dwProcessId
));
695 printf_unfiltered ("Attaching to %s\n",
696 target_pid_to_str (current_event
.dwProcessId
));
698 gdb_flush (gdb_stdout
);
701 push_target (&child_ops
);
705 child_detach (args
, from_tty
)
711 char *exec_file
= get_exec_file (0);
714 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
715 target_pid_to_str (inferior_pid
));
716 gdb_flush (gdb_stdout
);
719 unpush_target (&child_ops
);
722 /* Print status information about what we're accessing. */
725 child_files_info (ignore
)
726 struct target_ops
*ignore
;
728 printf_unfiltered ("\tUsing the running image of %s %s.\n",
729 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
734 child_open (arg
, from_tty
)
738 error ("Use the \"run\" command to start a Unix child process.");
741 /* Start an inferior win32 child process and sets inferior_pid to its pid.
742 EXEC_FILE is the file to run.
743 ALLARGS is a string containing the arguments to the program.
744 ENV is the environment vector to pass. Errors reported with error(). */
747 child_create_inferior (exec_file
, allargs
, env
)
752 char real_path
[MAXPATHLEN
];
759 PROCESS_INFORMATION pi
;
760 struct target_waitstatus dummy
;
767 error ("No executable specified, use `target exec'.\n");
770 memset (&si
, 0, sizeof (si
));
773 cygwin32_conv_to_win32_path (exec_file
, real_path
);
775 flags
= DEBUG_ONLY_THIS_PROCESS
;
778 flags
|= CREATE_NEW_PROCESS_GROUP
;
781 flags
|= CREATE_NEW_CONSOLE
;
783 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
785 strcpy (args
, real_path
);
788 strcat (args
, allargs
);
790 /* Prepare the environment vars for CreateProcess. */
792 /* This code use to assume all env vars were file names and would
793 translate them all to win32 style. That obviously doesn't work in the
794 general case. The current rule is that we only translate PATH.
795 We need to handle PATH because we're about to call CreateProcess and
796 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
797 in both posix and win32 environments. cygwin.dll will change it back
798 to posix style if necessary. */
800 static const char *conv_path_names
[] =
806 /* CreateProcess takes the environment list as a null terminated set of
807 strings (i.e. two nulls terminate the list). */
809 /* Get total size for env strings. */
810 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
814 for (j
= 0; conv_path_names
[j
]; j
++)
816 len
= strlen (conv_path_names
[j
]);
817 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
819 if (cygwin32_posix_path_list_p (env
[i
] + len
))
821 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
823 envlen
+= strlen (env
[i
]) + 1;
827 if (conv_path_names
[j
] == NULL
)
828 envlen
+= strlen (env
[i
]) + 1;
831 winenv
= alloca (envlen
+ 1);
833 /* Copy env strings into new buffer. */
834 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
838 for (j
= 0; conv_path_names
[j
]; j
++)
840 len
= strlen (conv_path_names
[j
]);
841 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
843 if (cygwin32_posix_path_list_p (env
[i
] + len
))
845 memcpy (temp
, env
[i
], len
);
846 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
849 strcpy (temp
, env
[i
]);
853 if (conv_path_names
[j
] == NULL
)
854 strcpy (temp
, env
[i
]);
856 temp
+= strlen (temp
) + 1;
859 /* Final nil string to terminate new env. */
863 ret
= CreateProcess (0,
864 args
, /* command line */
867 TRUE
, /* inherit handles */
868 flags
, /* start flags */
870 NULL
, /* current directory */
874 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError ());
879 current_process_handle
= pi
.hProcess
;
880 current_event
.dwProcessId
= pi
.dwProcessId
;
881 memset (¤t_event
, 0, sizeof (current_event
));
882 inferior_pid
= current_event
.dwThreadId
= pi
.dwThreadId
;
883 push_target (&child_ops
);
884 child_init_thread_list ();
885 init_wait_for_inferior ();
886 clear_proceed_status ();
887 target_terminal_init ();
888 target_terminal_inferior ();
890 /* Ignore the first trap */
891 child_wait (inferior_pid
, &dummy
);
893 proceed ((CORE_ADDR
) -1, TARGET_SIGNAL_0
, 0);
897 child_mourn_inferior ()
899 (void) child_continue (DBG_CONTINUE
, -1);
900 unpush_target (&child_ops
);
901 generic_mourn_inferior ();
904 /* Send a SIGINT to the process group. This acts just like the user typed a
905 ^C on the controlling terminal. */
910 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
911 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0));
912 registers_changed (); /* refresh register state */
916 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
917 int write
, struct target_ops
*target
)
922 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
924 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
926 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
930 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
932 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
939 child_kill_inferior (void)
941 CHECK (TerminateProcess (current_process_handle
, 0));
945 if (!child_continue (DBG_CONTINUE
, -1))
947 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
949 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
953 CHECK (CloseHandle (current_process_handle
));
955 /* this may fail in an attached process so don't check. */
956 (void) CloseHandle (current_thread
->h
);
957 target_mourn_inferior (); /* or just child_mourn_inferior? */
961 child_resume (int pid
, int step
, enum target_signal sig
)
965 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
966 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
968 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
971 /* Get context for currently selected thread */
972 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
976 /* Single step by setting t bit */
977 child_fetch_inferior_registers (PS_REGNUM
);
978 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
982 if (th
->context
.ContextFlags
)
984 CHECK (SetThreadContext (th
->h
, &th
->context
));
985 th
->context
.ContextFlags
= 0;
988 /* Allow continuing with the same signal that interrupted us.
989 Otherwise complain. */
990 if (sig
&& sig
!= last_sig
)
991 fprintf_unfiltered (gdb_stderr
, "Can't send signals to the child. signal %d\n", sig
);
994 child_continue (continue_status
, pid
);
998 child_prepare_to_store ()
1000 /* Do nothing, since we can store individual regs */
1012 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1015 struct target_ops child_ops
;
1018 init_child_ops (void)
1020 child_ops
.to_shortname
= "child";
1021 child_ops
.to_longname
= "Win32 child process";
1022 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1023 child_ops
.to_open
= child_open
;
1024 child_ops
.to_close
= child_close
;
1025 child_ops
.to_attach
= child_attach
;
1026 child_ops
.to_detach
= child_detach
;
1027 child_ops
.to_resume
= child_resume
;
1028 child_ops
.to_wait
= child_wait
;
1029 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1030 child_ops
.to_store_registers
= child_store_inferior_registers
;
1031 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1032 child_ops
.to_xfer_memory
= child_xfer_memory
;
1033 child_ops
.to_files_info
= child_files_info
;
1034 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1035 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1036 child_ops
.to_terminal_init
= terminal_init_inferior
;
1037 child_ops
.to_terminal_inferior
= terminal_inferior
;
1038 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1039 child_ops
.to_terminal_ours
= terminal_ours
;
1040 child_ops
.to_terminal_info
= child_terminal_info
;
1041 child_ops
.to_kill
= child_kill_inferior
;
1042 child_ops
.to_load
= 0;
1043 child_ops
.to_lookup_symbol
= 0;
1044 child_ops
.to_create_inferior
= child_create_inferior
;
1045 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1046 child_ops
.to_can_run
= child_can_run
;
1047 child_ops
.to_notice_signals
= 0;
1048 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1049 child_ops
.to_stop
= child_stop
;
1050 child_ops
.to_stratum
= process_stratum
;
1051 child_ops
.DONT_USE
= 0;
1052 child_ops
.to_has_all_memory
= 1;
1053 child_ops
.to_has_memory
= 1;
1054 child_ops
.to_has_stack
= 1;
1055 child_ops
.to_has_registers
= 1;
1056 child_ops
.to_has_execution
= 1;
1057 child_ops
.to_sections
= 0;
1058 child_ops
.to_sections_end
= 0;
1059 child_ops
.to_magic
= OPS_MAGIC
;
1063 _initialize_inftarg ()
1065 struct cmd_list_element
*c
;
1069 (add_set_cmd ("new-console", class_support
, var_boolean
,
1070 (char *) &new_console
,
1071 "Set creation of new console when creating child process.",
1076 (add_set_cmd ("new-group", class_support
, var_boolean
,
1077 (char *) &new_group
,
1078 "Set creation of new group when creating child process.",
1083 (add_set_cmd ("debugexec", class_support
, var_boolean
,
1084 (char *) &debug_exec
,
1085 "Set whether to display execution in child process.",
1090 (add_set_cmd ("debugevents", class_support
, var_boolean
,
1091 (char *) &debug_events
,
1092 "Set whether to display kernel events in child process.",
1097 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1098 (char *) &debug_memory
,
1099 "Set whether to display memory accesses in child process.",
1104 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1105 (char *) &debug_exceptions
,
1106 "Set whether to display kernel exceptions in child process.",
1110 add_target (&child_ops
);
1113 /* Determine if the thread referenced by "pid" is alive
1114 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1115 it means that the pid has died. Otherwise it is assumed to be alive. */
1117 win32_child_thread_alive (int pid
)
1119 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1123 /* Convert pid to printable format. */
1125 cygwin_pid_to_str (int pid
)
1127 static char buf
[80];
1128 if (pid
== current_event
.dwProcessId
)
1129 sprintf (buf
, "process %d", pid
);
1131 sprintf (buf
, "thread %d.0x%x", current_event
.dwProcessId
, pid
);