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 cygwin. */
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 /* 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
;
96 static thread_info thread_head
= {NULL
};
98 /* The process and thread handles for the above context. */
100 static DEBUG_EVENT current_event
; /* The current debug event from
102 static HANDLE current_process_handle
; /* Currently executing process */
103 static thread_info
*current_thread
; /* Info on currently selected thread */
104 static DWORD main_thread_id
; /* Thread ID of the main thread */
106 /* Counts of things. */
107 static int exception_count
= 0;
108 static int event_count
= 0;
111 static int new_console
= 0;
112 static int new_group
= 0;
113 static int debug_exec
= 0; /* show execution */
114 static int debug_events
= 0; /* show events from kernel */
115 static int debug_memory
= 0; /* show target memory accesses */
116 static int debug_exceptions
= 0; /* show target exceptions */
118 /* This vector maps GDB's idea of a register's number into an address
119 in the win32 exception context vector.
121 It also contains the bit mask needed to load the register in question.
123 One day we could read a reg, we could inspect the context we
124 already have loaded, if it doesn't have the bit set that we need,
125 we read that set of registers in using GetThreadContext. If the
126 context already contains what we need, we just unpack it. Then to
127 write a register, first we have to ensure that the context contains
128 the other regs of the group, and then we copy the info in and set
131 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
132 static const int mappings
[] =
143 context_offset(EFlags
),
144 context_offset(SegCs
),
145 context_offset(SegSs
),
146 context_offset(SegDs
),
147 context_offset(SegEs
),
148 context_offset(SegFs
),
149 context_offset(SegGs
),
150 context_offset(FloatSave
.RegisterArea
[0 * 10]),
151 context_offset(FloatSave
.RegisterArea
[1 * 10]),
152 context_offset(FloatSave
.RegisterArea
[2 * 10]),
153 context_offset(FloatSave
.RegisterArea
[3 * 10]),
154 context_offset(FloatSave
.RegisterArea
[4 * 10]),
155 context_offset(FloatSave
.RegisterArea
[5 * 10]),
156 context_offset(FloatSave
.RegisterArea
[6 * 10]),
157 context_offset(FloatSave
.RegisterArea
[7 * 10]),
160 /* This vector maps the target's idea of an exception (extracted
161 from the DEBUG_EVENT structure) to GDB's idea. */
163 struct xlate_exception
166 enum target_signal us
;
169 static const struct xlate_exception
172 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
173 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
174 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
175 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
176 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
179 /* Find a thread record given a thread id.
180 If get_context then also retrieve the context for this
183 thread_rec (DWORD id
, int get_context
)
187 for (th
= &thread_head
; (th
= th
->next
) != NULL
; )
190 if (!th
->suspend_count
&& get_context
)
193 th
->suspend_count
= SuspendThread (th
->h
) + 1;
194 else if (get_context
< 0)
195 th
->suspend_count
= -1;
197 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
198 GetThreadContext (th
->h
, &th
->context
);
206 /* Add a thread to the thread list */
208 child_add_thread(DWORD id
, HANDLE h
)
212 if ((th
= thread_rec (id
, FALSE
)))
215 th
= (thread_info
*) xmalloc (sizeof (*th
));
216 memset(th
, 0, sizeof (*th
));
219 th
->next
= thread_head
.next
;
220 thread_head
.next
= th
;
225 /* Clear out any old thread list and reintialize it to a
228 child_init_thread_list ()
230 thread_info
*th
= &thread_head
;
232 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
234 while (th
->next
!= NULL
)
236 thread_info
*here
= th
->next
;
237 th
->next
= here
->next
;
238 (void) CloseHandle (here
->h
);
243 /* Delete a thread from the list of threads */
245 child_delete_thread (DWORD id
)
250 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
253 for (th
= &thread_head
;
254 th
->next
!= NULL
&& th
->next
->id
!= id
;
258 if (th
->next
!= NULL
)
260 thread_info
*here
= th
->next
;
261 th
->next
= here
->next
;
262 CloseHandle (here
->h
);
268 check (BOOL ok
, const char *file
, int line
)
271 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
275 do_child_fetch_inferior_registers (int r
)
278 supply_register (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
281 for (r
= 0; r
< NUM_REGS
; r
++)
282 do_child_fetch_inferior_registers (r
);
287 child_fetch_inferior_registers (int r
)
289 current_thread
= thread_rec (inferior_pid
, TRUE
);
290 do_child_fetch_inferior_registers (r
);
294 do_child_store_inferior_registers (int r
)
297 read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
300 for (r
= 0; r
< NUM_REGS
; r
++)
301 do_child_store_inferior_registers (r
);
305 /* Store a new register value into the current thread context */
307 child_store_inferior_registers (int r
)
309 current_thread
= thread_rec (inferior_pid
, TRUE
);
310 do_child_store_inferior_registers (r
);
313 /* Wait for child to do something. Return pid of child, or -1 in case
314 of error; store status through argument pointer OURSTATUS. */
317 handle_load_dll (PTR dummy
)
319 LOAD_DLL_DEBUG_INFO
* event
= ¤t_event
.u
.LoadDll
;
322 char dll_buf
[MAX_PATH
+ 1];
323 char *p
, *dll_name
= NULL
, *dll_basename
;
324 struct objfile
*objfile
;
325 MEMORY_BASIC_INFORMATION minfo
;
327 dll_buf
[0] = dll_buf
[sizeof(dll_buf
) - 1] = '\0';
329 /* The following code attempts to find the name of the dll by reading the
330 name from the processes memory. Unfortunately it doesn't work right.
331 Doing this the "right way" for Windows is very difficult. FIXME */
333 memset (&minfo
, 0, sizeof minfo
);
334 if (VirtualQueryEx (current_process_handle
, (LPCVOID
) event
->lpBaseOfDll
,
335 &minfo
, sizeof(minfo
)) && minfo
.BaseAddress
) {
337 IMAGE_DOS_HEADER
*hmm0
= (IMAGE_DOS_HEADER
*) minfo
.BaseAddress
;
338 HMODULE hmm
= (HMODULE
) (((DWORD
) hmm0
) + hmm0
->e_lfanew
);
340 if ((len
= GetModuleFileName (hmm
, dll_buf
, MAX_PATH
)))
343 dll_name
[len
] = '\0';
348 /* Attempt to read the name of the dll that was detected.
349 This is documented to work only when actively debugging
350 a program. It will not work for attached processes. */
351 if (dll_name
== NULL
|| *dll_name
== '\0')
353 int size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
357 ReadProcessMemory (current_process_handle
,
358 (LPCVOID
) event
->lpImageName
,
359 (char *) &dll_name_ptr
,
360 sizeof (dll_name_ptr
), &done
);
362 /* See if we could read the address of a string, and that the
363 address isn't null. */
365 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
370 ReadProcessMemory (current_process_handle
,
371 (LPCVOID
) (dll_name_ptr
+ len
* size
),
377 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
379 dll_name
= alloca (len
);
383 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
384 ReadProcessMemory (current_process_handle
,
385 (LPCVOID
) dll_name_ptr
,
387 len
* sizeof (WCHAR
),
390 WideCharToMultiByte (CP_ACP
, 0,
391 unicode_dll_name
, len
,
392 dll_name
, len
, 0, 0);
396 ReadProcessMemory (current_process_handle
,
397 (LPCVOID
) dll_name_ptr
,
407 while ((p
= strchr (dll_name
, '\\')))
410 /* FIXME!! It would be nice to define one symbol which pointed to the
411 front of the dll if we can't find any symbols. */
413 if (!(dll_basename
= strrchr(dll_name
, '/')))
414 dll_basename
= dll_name
;
418 ALL_OBJFILES(objfile
)
420 char *objfile_basename
;
421 objfile_basename
= strrchr(objfile
->name
, '/');
423 if (objfile_basename
&&
424 strcmp(dll_basename
, objfile_basename
+ 1) == 0)
426 printf_unfiltered ("%x:%s (symbols previously loaded)\n",
427 event
->lpBaseOfDll
, dll_name
);
432 /* The symbols in a dll are offset by 0x1000, which is the
433 the offset from 0 of the first byte in an image - because
434 of the file header and the section alignment.
436 FIXME: Is this the real reason that we need the 0x1000 ? */
438 printf_unfiltered ("%x:%s", event
->lpBaseOfDll
, dll_name
);
439 symbol_file_add (dll_name
, 0, (int) event
->lpBaseOfDll
+ 0x1000, 0, 0, 0, 0, 1);
440 printf_unfiltered ("\n");
446 /* Handle DEBUG_STRING output from child process.
447 Cygwin prepends its messages with a "cygwin:". Interpret this as
448 a Cygwin signal. Otherwise just print the string as a warning. */
450 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
455 if (!target_read_string
456 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
460 if (strncmp(s
, CYGWIN_SIGNAL_STRING
, sizeof(CYGWIN_SIGNAL_STRING
) - 1))
467 /*last_sig = */strtol(s
+ sizeof(CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
468 gotasig
= target_signal_from_host (last_sig
);
469 ourstatus
->value
.sig
= gotasig
;
471 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
479 handle_exception (struct target_waitstatus
*ourstatus
)
485 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
487 /* Record the context of the current thread */
488 th
= thread_rec (current_event
.dwThreadId
, -1);
490 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
492 case EXCEPTION_ACCESS_VIOLATION
:
493 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
494 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
495 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
497 case STATUS_STACK_OVERFLOW
:
498 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
499 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
500 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
502 case EXCEPTION_BREAKPOINT
:
503 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
504 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
505 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
508 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
509 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
510 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
511 /* User typed CTRL-C. Continue with this status */
512 last_sig
= SIGINT
; /* FIXME - should check pass state */
514 case EXCEPTION_SINGLE_STEP
:
515 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
516 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
517 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
520 /* This may be a structured exception handling exception. In
521 that case, we want to let the program try to handle it, and
522 only break if we see the exception a second time. */
523 if (current_event
.u
.Exception
.dwFirstChance
)
526 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
527 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
528 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
529 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
536 /* Resume all artificially suspended threads if we are continuing
539 child_continue (DWORD continue_status
, int id
)
545 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
546 current_event
.dwProcessId
, current_event
.dwThreadId
));
547 res
= ContinueDebugEvent (current_event
.dwProcessId
,
548 current_event
.dwThreadId
,
551 for (th
= &thread_head
; (th
= th
->next
) != NULL
; )
552 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
554 for (i
= 0; i
< th
->suspend_count
; i
++)
555 (void) ResumeThread (th
->h
);
556 th
->suspend_count
= 0;
563 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
565 /* We loop when we get a non-standard exception rather than return
566 with a SPURIOUS because resume can try and step or modify things,
567 which needs a current_thread->h. But some of these exceptions mark
568 the birth or death of threads, which mean that the current thread
569 isn't necessarily what you think it is. */
573 DWORD continue_status
;
574 BOOL debug_event
= WaitForDebugEvent (¤t_event
, 20);
583 continue_status
= DBG_CONTINUE
;
585 switch (current_event
.dwDebugEventCode
)
587 case CREATE_THREAD_DEBUG_EVENT
:
588 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
589 current_event
.dwProcessId
, current_event
.dwThreadId
,
590 "CREATE_THREAD_DEBUG_EVENT"));
591 /* Record the existence of this thread */
592 child_add_thread (current_event
.dwThreadId
,
593 current_event
.u
.CreateThread
.hThread
);
595 printf_unfiltered ("[New %s]\n",
596 target_pid_to_str (current_event
.dwThreadId
));
599 case EXIT_THREAD_DEBUG_EVENT
:
600 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
601 current_event
.dwProcessId
, current_event
.dwThreadId
,
602 "EXIT_THREAD_DEBUG_EVENT"));
603 child_delete_thread (current_event
.dwThreadId
);
606 case CREATE_PROCESS_DEBUG_EVENT
:
607 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
608 current_event
.dwProcessId
, current_event
.dwThreadId
,
609 "CREATE_PROCESS_DEBUG_EVENT"));
610 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
612 main_thread_id
= inferior_pid
= current_event
.dwThreadId
;
613 /* Add the main thread */
614 current_thread
= child_add_thread (inferior_pid
,
615 current_event
.u
.CreateProcessInfo
.hThread
);
618 case EXIT_PROCESS_DEBUG_EVENT
:
619 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
620 current_event
.dwProcessId
, current_event
.dwThreadId
,
621 "EXIT_PROCESS_DEBUG_EVENT"));
622 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
623 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
624 CloseHandle (current_process_handle
);
625 return current_event
.dwProcessId
;
628 case LOAD_DLL_DEBUG_EVENT
:
629 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
630 current_event
.dwProcessId
, current_event
.dwThreadId
,
631 "LOAD_DLL_DEBUG_EVENT"));
632 catch_errors (handle_load_dll
, NULL
, "", RETURN_MASK_ALL
);
633 registers_changed(); /* mark all regs invalid */
636 case UNLOAD_DLL_DEBUG_EVENT
:
637 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
638 current_event
.dwProcessId
, current_event
.dwThreadId
,
639 "UNLOAD_DLL_DEBUG_EVENT"));
640 break; /* FIXME: don't know what to do here */
642 case EXCEPTION_DEBUG_EVENT
:
643 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
644 current_event
.dwProcessId
, current_event
.dwThreadId
,
645 "EXCEPTION_DEBUG_EVENT"));
646 if (handle_exception (ourstatus
))
647 return current_event
.dwThreadId
;
648 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
651 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
652 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
653 current_event
.dwProcessId
, current_event
.dwThreadId
,
654 "OUTPUT_DEBUG_STRING_EVENT"));
655 if (handle_output_debug_string (ourstatus
))
656 return main_thread_id
;
659 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
660 current_event
.dwProcessId
,
661 current_event
.dwThreadId
);
662 printf_unfiltered (" unknown event code %d\n",
663 current_event
.dwDebugEventCode
);
667 CHECK (child_continue (continue_status
, -1));
673 if (ui_loop_hook
!= NULL
)
674 detach
= ui_loop_hook (0);
677 child_kill_inferior ();
682 /* Attach to process PID, then initialize for debugging it. */
685 child_attach (args
, from_tty
)
692 error_no_arg ("process-id to attach");
694 current_event
.dwProcessId
= strtoul (args
, 0, 0);
696 ok
= DebugActiveProcess (current_event
.dwProcessId
);
699 error ("Can't attach to process.");
706 char *exec_file
= (char *) get_exec_file (0);
709 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
710 target_pid_to_str (current_event
.dwProcessId
));
712 printf_unfiltered ("Attaching to %s\n",
713 target_pid_to_str (current_event
.dwProcessId
));
715 gdb_flush (gdb_stdout
);
718 push_target (&child_ops
);
722 child_detach (args
, from_tty
)
728 char *exec_file
= get_exec_file (0);
731 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
732 target_pid_to_str (inferior_pid
));
733 gdb_flush (gdb_stdout
);
736 unpush_target (&child_ops
);
739 /* Print status information about what we're accessing. */
742 child_files_info (ignore
)
743 struct target_ops
*ignore
;
745 printf_unfiltered ("\tUsing the running image of %s %s.\n",
746 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
751 child_open (arg
, from_tty
)
755 error ("Use the \"run\" command to start a Unix child process.");
758 /* Start an inferior win32 child process and sets inferior_pid to its pid.
759 EXEC_FILE is the file to run.
760 ALLARGS is a string containing the arguments to the program.
761 ENV is the environment vector to pass. Errors reported with error(). */
764 child_create_inferior (exec_file
, allargs
, env
)
769 char real_path
[MAXPATHLEN
];
776 PROCESS_INFORMATION pi
;
777 struct target_waitstatus dummy
;
784 error ("No executable specified, use `target exec'.\n");
787 memset (&si
, 0, sizeof (si
));
790 cygwin32_conv_to_win32_path (exec_file
, real_path
);
792 flags
= DEBUG_ONLY_THIS_PROCESS
;
795 flags
|= CREATE_NEW_PROCESS_GROUP
;
798 flags
|= CREATE_NEW_CONSOLE
;
800 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
802 strcpy (args
, real_path
);
805 strcat (args
, allargs
);
807 /* Prepare the environment vars for CreateProcess. */
809 /* This code use to assume all env vars were file names and would
810 translate them all to win32 style. That obviously doesn't work in the
811 general case. The current rule is that we only translate PATH.
812 We need to handle PATH because we're about to call CreateProcess and
813 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
814 in both posix and win32 environments. cygwin.dll will change it back
815 to posix style if necessary. */
817 static const char *conv_path_names
[] =
823 /* CreateProcess takes the environment list as a null terminated set of
824 strings (i.e. two nulls terminate the list). */
826 /* Get total size for env strings. */
827 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
831 for (j
= 0; conv_path_names
[j
]; j
++)
833 len
= strlen (conv_path_names
[j
]);
834 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
836 if (cygwin32_posix_path_list_p (env
[i
] + len
))
838 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
840 envlen
+= strlen (env
[i
]) + 1;
844 if (conv_path_names
[j
] == NULL
)
845 envlen
+= strlen (env
[i
]) + 1;
848 winenv
= alloca (envlen
+ 1);
850 /* Copy env strings into new buffer. */
851 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
855 for (j
= 0; conv_path_names
[j
]; j
++)
857 len
= strlen (conv_path_names
[j
]);
858 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
860 if (cygwin32_posix_path_list_p (env
[i
] + len
))
862 memcpy (temp
, env
[i
], len
);
863 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
866 strcpy (temp
, env
[i
]);
870 if (conv_path_names
[j
] == NULL
)
871 strcpy (temp
, env
[i
]);
873 temp
+= strlen (temp
) + 1;
876 /* Final nil string to terminate new env. */
880 ret
= CreateProcess (0,
881 args
, /* command line */
884 TRUE
, /* inherit handles */
885 flags
, /* start flags */
887 NULL
, /* current directory */
891 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError());
896 current_process_handle
= pi
.hProcess
;
897 current_event
.dwProcessId
= pi
.dwProcessId
;
898 memset (¤t_event
, 0, sizeof (current_event
));
899 inferior_pid
= current_event
.dwThreadId
= pi
.dwThreadId
;
900 push_target (&child_ops
);
901 child_init_thread_list ();
902 init_wait_for_inferior ();
903 clear_proceed_status ();
904 target_terminal_init ();
905 target_terminal_inferior ();
907 /* Ignore the first trap */
908 child_wait (inferior_pid
, &dummy
);
910 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
914 child_mourn_inferior ()
916 (void) child_continue (DBG_CONTINUE
, -1);
917 unpush_target (&child_ops
);
918 generic_mourn_inferior ();
921 /* Send a SIGINT to the process group. This acts just like the user typed a
922 ^C on the controlling terminal. */
927 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
928 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0));
929 registers_changed(); /* refresh register state */
933 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
934 int write
, struct target_ops
*target
)
939 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
941 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
943 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
947 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
949 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
956 child_kill_inferior (void)
958 CHECK (TerminateProcess (current_process_handle
, 0));
962 if (!child_continue (DBG_CONTINUE
, -1))
964 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
966 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
970 CHECK (CloseHandle (current_process_handle
));
972 /* this may fail in an attached process so don't check. */
973 (void) CloseHandle (current_thread
->h
);
974 target_mourn_inferior(); /* or just child_mourn_inferior? */
978 child_resume (int pid
, int step
, enum target_signal sig
)
982 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
983 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
985 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
988 /* Get context for currently selected thread */
989 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
993 /* Single step by setting t bit */
994 child_fetch_inferior_registers (PS_REGNUM
);
995 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
999 if (th
->context
.ContextFlags
)
1001 CHECK (SetThreadContext (th
->h
, &th
->context
));
1002 th
->context
.ContextFlags
= 0;
1005 /* Allow continuing with the same signal that interrupted us.
1006 Otherwise complain. */
1007 if (sig
&& sig
!= last_sig
)
1008 fprintf_unfiltered (gdb_stderr
, "Can't send signals to the child. signal %d\n", sig
);
1011 child_continue (continue_status
, pid
);
1015 child_prepare_to_store ()
1017 /* Do nothing, since we can store individual regs */
1029 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1032 struct target_ops child_ops
;
1035 init_child_ops(void)
1037 child_ops
.to_shortname
= "child";
1038 child_ops
.to_longname
= "Win32 child process";
1039 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1040 child_ops
.to_open
= child_open
;
1041 child_ops
.to_close
= child_close
;
1042 child_ops
.to_attach
= child_attach
;
1043 child_ops
.to_detach
= child_detach
;
1044 child_ops
.to_resume
= child_resume
;
1045 child_ops
.to_wait
= child_wait
;
1046 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1047 child_ops
.to_store_registers
= child_store_inferior_registers
;
1048 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1049 child_ops
.to_xfer_memory
= child_xfer_memory
;
1050 child_ops
.to_files_info
= child_files_info
;
1051 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1052 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1053 child_ops
.to_terminal_init
= terminal_init_inferior
;
1054 child_ops
.to_terminal_inferior
= terminal_inferior
;
1055 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1056 child_ops
.to_terminal_ours
= terminal_ours
;
1057 child_ops
.to_terminal_info
= child_terminal_info
;
1058 child_ops
.to_kill
= child_kill_inferior
;
1059 child_ops
.to_load
= 0;
1060 child_ops
.to_lookup_symbol
= 0;
1061 child_ops
.to_create_inferior
= child_create_inferior
;
1062 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1063 child_ops
.to_can_run
= child_can_run
;
1064 child_ops
.to_notice_signals
= 0;
1065 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1066 child_ops
.to_stop
= child_stop
;
1067 child_ops
.to_stratum
= process_stratum
;
1068 child_ops
.DONT_USE
= 0;
1069 child_ops
.to_has_all_memory
= 1;
1070 child_ops
.to_has_memory
= 1;
1071 child_ops
.to_has_stack
= 1;
1072 child_ops
.to_has_registers
= 1;
1073 child_ops
.to_has_execution
= 1;
1074 child_ops
.to_sections
= 0;
1075 child_ops
.to_sections_end
= 0;
1076 child_ops
.to_magic
= OPS_MAGIC
;
1080 _initialize_inftarg ()
1082 struct cmd_list_element
*c
;
1086 (add_set_cmd ("new-console", class_support
, var_boolean
,
1087 (char *) &new_console
,
1088 "Set creation of new console when creating child process.",
1093 (add_set_cmd ("new-group", class_support
, var_boolean
,
1094 (char *) &new_group
,
1095 "Set creation of new group when creating child process.",
1100 (add_set_cmd ("debugexec", class_support
, var_boolean
,
1101 (char *) &debug_exec
,
1102 "Set whether to display execution in child process.",
1107 (add_set_cmd ("debugevents", class_support
, var_boolean
,
1108 (char *) &debug_events
,
1109 "Set whether to display kernel events in child process.",
1114 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1115 (char *) &debug_memory
,
1116 "Set whether to display memory accesses in child process.",
1121 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1122 (char *) &debug_exceptions
,
1123 "Set whether to display kernel exceptions in child process.",
1127 add_target (&child_ops
);
1130 /* Determine if the thread referenced by "pid" is alive
1131 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1132 it means that the pid has died. Otherwise it is assumed to be alive. */
1134 win32_child_thread_alive (int pid
)
1136 return WaitForSingleObject(thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1140 /* Convert pid to printable format. */
1142 cygwin_pid_to_str (int pid
)
1144 static char buf
[80];
1145 if (pid
== current_event
.dwProcessId
)
1146 sprintf (buf
, "process %d", pid
);
1148 sprintf (buf
, "thread %d.0x%x", current_event
.dwProcessId
, pid
);