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 */
49 #include "gdb_string.h"
50 #include "gdbthread.h"
52 #include <sys/param.h>
55 /* The ui's event loop. */
56 extern int (*ui_loop_hook
) PARAMS ((int signo
));
58 /* If we're not using the old Cygwin header file set, define the
59 following which never should have been in the generic Win32 API
60 headers in the first place since they were our own invention... */
61 #ifndef _GNU_H_WINDOWS_H
62 #define FLAG_TRACE_BIT 0x100
63 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
66 /* The string sent by cygwin when it processes a signal.
67 FIXME: This should be in a cygwin include file. */
68 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
70 #define CHECK(x) check (x, __FILE__,__LINE__)
71 #define DEBUG_EXEC(x) if (debug_exec) printf x
72 #define DEBUG_EVENTS(x) if (debug_events) printf x
73 #define DEBUG_MEM(x) if (debug_memory) printf x
74 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
76 /* Forward declaration */
77 extern struct target_ops child_ops
;
79 static void child_stop
PARAMS ((void));
80 static int win32_child_thread_alive
PARAMS ((int));
81 void child_kill_inferior
PARAMS ((void));
83 /* Thread information structure used to track information that is
84 not available in gdb's thread structure. */
85 typedef struct thread_info_struct
87 struct thread_info_struct
*next
;
96 static thread_info thread_head
= {NULL
};
98 /* The saved state for a continue after breaking back to gdb. */
99 static DWORD continue_status
;
101 /* The process and thread handles for the above context. */
103 static DEBUG_EVENT current_event
; /* The current debug event from
105 static HANDLE current_process_handle
; /* Currently executing process */
106 static thread_info
*current_thread
; /* Info on currently selected thread */
107 static DWORD main_thread_id
; /* Thread ID of the main thread */
109 /* Counts of things. */
110 static int exception_count
= 0;
111 static int event_count
= 0;
114 static int new_console
= 0;
115 static int new_group
= 1;
116 static int debug_exec
= 0; /* show execution */
117 static int debug_events
= 0; /* show events from kernel */
118 static int debug_memory
= 0; /* show target memory accesses */
119 static int debug_exceptions
= 0; /* show target exceptions */
121 /* This vector maps GDB's idea of a register's number into an address
122 in the win32 exception context vector.
124 It also contains the bit mask needed to load the register in question.
126 One day we could read a reg, we could inspect the context we
127 already have loaded, if it doesn't have the bit set that we need,
128 we read that set of registers in using GetThreadContext. If the
129 context already contains what we need, we just unpack it. Then to
130 write a register, first we have to ensure that the context contains
131 the other regs of the group, and then we copy the info in and set
134 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
135 static const int mappings
[] =
137 context_offset (Eax
),
138 context_offset (Ecx
),
139 context_offset (Edx
),
140 context_offset (Ebx
),
141 context_offset (Esp
),
142 context_offset (Ebp
),
143 context_offset (Esi
),
144 context_offset (Edi
),
145 context_offset (Eip
),
146 context_offset (EFlags
),
147 context_offset (SegCs
),
148 context_offset (SegSs
),
149 context_offset (SegDs
),
150 context_offset (SegEs
),
151 context_offset (SegFs
),
152 context_offset (SegGs
),
153 context_offset (FloatSave
.RegisterArea
[0 * 10]),
154 context_offset (FloatSave
.RegisterArea
[1 * 10]),
155 context_offset (FloatSave
.RegisterArea
[2 * 10]),
156 context_offset (FloatSave
.RegisterArea
[3 * 10]),
157 context_offset (FloatSave
.RegisterArea
[4 * 10]),
158 context_offset (FloatSave
.RegisterArea
[5 * 10]),
159 context_offset (FloatSave
.RegisterArea
[6 * 10]),
160 context_offset (FloatSave
.RegisterArea
[7 * 10]),
161 context_offset (FloatSave
.ControlWord
),
162 context_offset (FloatSave
.StatusWord
),
163 context_offset (FloatSave
.TagWord
),
164 context_offset (FloatSave
.ErrorSelector
),
165 context_offset (FloatSave
.ErrorOffset
),
166 context_offset (FloatSave
.DataSelector
),
167 context_offset (FloatSave
.DataOffset
),
168 context_offset (FloatSave
.ErrorSelector
)
171 #undef context_offset
173 /* This vector maps the target's idea of an exception (extracted
174 from the DEBUG_EVENT structure) to GDB's idea. */
176 struct xlate_exception
179 enum target_signal us
;
182 static const struct xlate_exception
185 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
186 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
187 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
188 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
189 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
192 /* Find a thread record given a thread id.
193 If get_context then also retrieve the context for this
196 thread_rec (DWORD id
, int get_context
)
200 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
203 if (!th
->suspend_count
&& get_context
)
206 th
->suspend_count
= SuspendThread (th
->h
) + 1;
207 else if (get_context
< 0)
208 th
->suspend_count
= -1;
210 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
211 GetThreadContext (th
->h
, &th
->context
);
219 /* Add a thread to the thread list */
221 child_add_thread (DWORD id
, HANDLE h
)
225 if ((th
= thread_rec (id
, FALSE
)))
228 th
= (thread_info
*) xmalloc (sizeof (*th
));
229 memset (th
, 0, sizeof (*th
));
232 th
->next
= thread_head
.next
;
233 thread_head
.next
= th
;
238 /* Clear out any old thread list and reintialize it to a
241 child_init_thread_list ()
243 thread_info
*th
= &thread_head
;
245 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
247 while (th
->next
!= NULL
)
249 thread_info
*here
= th
->next
;
250 th
->next
= here
->next
;
251 (void) CloseHandle (here
->h
);
256 /* Delete a thread from the list of threads */
258 child_delete_thread (DWORD id
)
263 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
266 for (th
= &thread_head
;
267 th
->next
!= NULL
&& th
->next
->id
!= id
;
271 if (th
->next
!= NULL
)
273 thread_info
*here
= th
->next
;
274 th
->next
= here
->next
;
275 CloseHandle (here
->h
);
281 check (BOOL ok
, const char *file
, int line
)
284 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
288 do_child_fetch_inferior_registers (int r
)
290 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
294 l
= *((long *)context_offset
) & 0xffff;
295 supply_register (r
, (char *) &l
);
297 else if (r
== FOP_REGNUM
)
299 l
= (*((long *)context_offset
) >> 16) & ((1 << 11) - 1);
300 supply_register (r
, (char *) &l
);
303 supply_register (r
, context_offset
);
306 for (r
= 0; r
< NUM_REGS
; r
++)
307 do_child_fetch_inferior_registers (r
);
312 child_fetch_inferior_registers (int r
)
314 current_thread
= thread_rec (inferior_pid
, TRUE
);
315 do_child_fetch_inferior_registers (r
);
319 do_child_store_inferior_registers (int r
)
322 read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
325 for (r
= 0; r
< NUM_REGS
; r
++)
326 do_child_store_inferior_registers (r
);
330 /* Store a new register value into the current thread context */
332 child_store_inferior_registers (int r
)
334 current_thread
= thread_rec (inferior_pid
, TRUE
);
335 do_child_store_inferior_registers (r
);
339 static int psapi_loaded
= 0;
340 static HMODULE psapi_module_handle
= NULL
;
341 static BOOL
WINAPI (*psapi_EnumProcessModules
)(HANDLE
, HMODULE
*, DWORD
, LPDWORD
)= NULL
;
342 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
)= NULL
;
343 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
)= NULL
;
345 int psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
350 HMODULE dh_buf
[ 1 ];
351 HMODULE
* DllHandle
= dh_buf
;
356 psapi_EnumProcessModules
== NULL
||
357 psapi_GetModuleInformation
== NULL
||
358 psapi_GetModuleFileNameExA
== NULL
)
360 if (psapi_loaded
)goto failed
;
362 psapi_module_handle
= LoadLibrary ("psapi.dll");
363 if (!psapi_module_handle
)
365 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
368 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules" );
369 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
370 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
371 "GetModuleFileNameExA");
372 if (psapi_EnumProcessModules
== NULL
||
373 psapi_GetModuleInformation
== NULL
||
374 psapi_GetModuleFileNameExA
== NULL
)
379 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
384 if (!ok
|| !cbNeeded
)
387 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
391 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
398 for (i
= 0; i
< cbNeeded
/ sizeof (HMODULE
); i
++)
400 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
404 error ("Can't get module info");
406 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
411 error ("Error getting dll name: %u\n", GetLastError ());
413 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
418 dll_name_ret
[0] = '\0';
422 /* Wait for child to do something. Return pid of child, or -1 in case
423 of error; store status through argument pointer OURSTATUS. */
426 handle_load_dll (PTR dummy
)
428 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
431 char dll_buf
[MAX_PATH
+ 1];
432 char *p
, *dll_name
= NULL
;
433 struct objfile
*objfile
;
434 MEMORY_BASIC_INFORMATION minfo
;
435 struct section_addr_info section_addrs
;
437 memset (§ion_addrs
, 0, sizeof (section_addrs
));
438 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
440 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
441 dll_buf
[0] = dll_buf
[sizeof(dll_buf
) - 1] = '\0';
445 /* Attempt to read the name of the dll that was detected.
446 This is documented to work only when actively debugging
447 a program. It will not work for attached processes. */
448 if (dll_name
== NULL
|| *dll_name
== '\0')
450 int size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
454 ReadProcessMemory (current_process_handle
,
455 (LPCVOID
) event
->lpImageName
,
456 (char *) &dll_name_ptr
,
457 sizeof (dll_name_ptr
), &done
);
459 /* See if we could read the address of a string, and that the
460 address isn't null. */
462 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
467 ReadProcessMemory (current_process_handle
,
468 (LPCVOID
) (dll_name_ptr
+ len
* size
),
474 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
476 dll_name
= alloca (len
);
480 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
481 ReadProcessMemory (current_process_handle
,
482 (LPCVOID
) dll_name_ptr
,
484 len
* sizeof (WCHAR
),
487 WideCharToMultiByte (CP_ACP
, 0,
488 unicode_dll_name
, len
,
489 dll_name
, len
, 0, 0);
493 ReadProcessMemory (current_process_handle
,
494 (LPCVOID
) dll_name_ptr
,
504 while ((p
= strchr (dll_name
, '\\')))
507 /* The symbols in a dll are offset by 0x1000, which is the
508 the offset from 0 of the first byte in an image - because
509 of the file header and the section alignment.
511 FIXME: Is this the real reason that we need the 0x1000 ? */
513 printf_unfiltered ("%x:%s", event
->lpBaseOfDll
, dll_name
);
514 section_addrs
.text_addr
= (int) event
->lpBaseOfDll
+ 0x1000;
515 symbol_file_add (dll_name
, 0, §ion_addrs
, 0, OBJF_SHARED
);
516 printf_unfiltered ("\n");
521 /* Handle DEBUG_STRING output from child process.
522 Cygwin prepends its messages with a "cygwin:". Interpret this as
523 a Cygwin signal. Otherwise just print the string as a warning. */
525 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
530 if (!target_read_string
531 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
535 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
537 if (strncmp (s
, "cYg", 3) != 0)
543 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
544 gotasig
= target_signal_from_host (sig
);
545 ourstatus
->value
.sig
= gotasig
;
547 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
555 handle_exception (struct target_waitstatus
*ourstatus
)
561 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
563 /* Record the context of the current thread */
564 th
= thread_rec (current_event
.dwThreadId
, -1);
566 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
568 case EXCEPTION_ACCESS_VIOLATION
:
569 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
570 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
571 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
572 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
574 case STATUS_FLOAT_UNDERFLOW
:
575 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
576 case STATUS_FLOAT_OVERFLOW
:
577 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
578 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
579 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
580 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
581 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
583 case STATUS_STACK_OVERFLOW
:
584 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
585 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
586 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
587 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
589 case EXCEPTION_BREAKPOINT
:
590 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
591 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
592 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
595 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
596 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
597 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
598 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
600 case EXCEPTION_SINGLE_STEP
:
601 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
602 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
603 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
606 /* This may be a structured exception handling exception. In
607 that case, we want to let the program try to handle it, and
608 only break if we see the exception a second time.
609 if (current_event.u.Exception.dwFirstChance)
614 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
615 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
616 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
617 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
618 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
625 /* Resume all artificially suspended threads if we are continuing
628 child_continue (int id
)
634 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
635 current_event
.dwProcessId
, current_event
.dwThreadId
));
636 res
= ContinueDebugEvent (current_event
.dwProcessId
,
637 current_event
.dwThreadId
,
641 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
642 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
644 for (i
= 0; i
< th
->suspend_count
; i
++)
645 (void) ResumeThread (th
->h
);
646 th
->suspend_count
= 0;
653 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
,
654 DWORD
*event_code
, int *retval
)
659 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 20)))
661 breakout
= *retval
= *event_code
= 0;
666 continue_status
= DBG_CONTINUE
;
669 switch (*event_code
= current_event
.dwDebugEventCode
)
671 case CREATE_THREAD_DEBUG_EVENT
:
672 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
673 (unsigned) current_event
.dwProcessId
,
674 (unsigned) current_event
.dwThreadId
,
675 "CREATE_THREAD_DEBUG_EVENT"));
676 /* Record the existence of this thread */
677 child_add_thread (current_event
.dwThreadId
,
678 current_event
.u
.CreateThread
.hThread
);
680 printf_unfiltered ("[New %s]\n",
681 target_pid_to_str (current_event
.dwThreadId
));
684 case EXIT_THREAD_DEBUG_EVENT
:
685 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
686 (unsigned) current_event
.dwProcessId
,
687 (unsigned) current_event
.dwThreadId
,
688 "EXIT_THREAD_DEBUG_EVENT"));
689 child_delete_thread (current_event
.dwThreadId
);
692 case CREATE_PROCESS_DEBUG_EVENT
:
693 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
694 (unsigned) current_event
.dwProcessId
,
695 (unsigned) current_event
.dwThreadId
,
696 "CREATE_PROCESS_DEBUG_EVENT"));
697 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
699 main_thread_id
= inferior_pid
= current_event
.dwThreadId
;
700 /* Add the main thread */
701 current_thread
= child_add_thread (inferior_pid
,
702 current_event
.u
.CreateProcessInfo
.hThread
);
705 case EXIT_PROCESS_DEBUG_EVENT
:
706 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
707 (unsigned) current_event
.dwProcessId
,
708 (unsigned) current_event
.dwThreadId
,
709 "EXIT_PROCESS_DEBUG_EVENT"));
710 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
711 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
712 CloseHandle (current_process_handle
);
713 *retval
= current_event
.dwProcessId
;
716 case LOAD_DLL_DEBUG_EVENT
:
717 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
718 (unsigned) current_event
.dwProcessId
,
719 (unsigned) current_event
.dwThreadId
,
720 "LOAD_DLL_DEBUG_EVENT"));
721 catch_errors (handle_load_dll
, NULL
, "", RETURN_MASK_ALL
);
722 registers_changed (); /* mark all regs invalid */
725 case UNLOAD_DLL_DEBUG_EVENT
:
726 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
727 (unsigned) current_event
.dwProcessId
,
728 (unsigned) current_event
.dwThreadId
,
729 "UNLOAD_DLL_DEBUG_EVENT"));
730 break; /* FIXME: don't know what to do here */
732 case EXCEPTION_DEBUG_EVENT
:
733 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
734 (unsigned) current_event
.dwProcessId
,
735 (unsigned) current_event
.dwThreadId
,
736 "EXCEPTION_DEBUG_EVENT"));
737 if (handle_exception (ourstatus
)) /* sets continue_status */
739 *retval
= current_event
.dwThreadId
;
744 case OUTPUT_DEBUG_STRING_EVENT
:
745 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
746 (unsigned) current_event
.dwProcessId
,
747 (unsigned) current_event
.dwThreadId
,
748 "OUTPUT_DEBUG_STRING_EVENT"));
749 if (handle_output_debug_string (ourstatus
))
751 *retval
= main_thread_id
;
756 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
757 current_event
.dwProcessId
,
758 current_event
.dwThreadId
);
759 printf_unfiltered (" unknown event code %d\n",
760 current_event
.dwDebugEventCode
);
765 CHECK (child_continue (-1));
773 /* Wait for interesting events to occur in the target process. */
775 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
780 /* We loop when we get a non-standard exception rather than return
781 with a SPURIOUS because resume can try and step or modify things,
782 which needs a current_thread->h. But some of these exceptions mark
783 the birth or death of threads, which mean that the current thread
784 isn't necessarily what you think it is. */
788 if (continue_status
!= 0)
789 CHECK (child_continue (-1));
790 if (get_child_debug_event (pid
, ourstatus
, &event_code
, &retval
))
796 if (ui_loop_hook
!= NULL
)
797 detach
= ui_loop_hook (0);
800 child_kill_inferior ();
805 /* Attach to process PID, then initialize for debugging it. */
808 child_attach (args
, from_tty
)
815 error_no_arg ("process-id to attach");
817 current_event
.dwProcessId
= strtoul (args
, 0, 0);
819 ok
= DebugActiveProcess (current_event
.dwProcessId
);
822 error ("Can't attach to process.");
829 char *exec_file
= (char *) get_exec_file (0);
832 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
833 target_pid_to_str (current_event
.dwProcessId
));
835 printf_unfiltered ("Attaching to %s\n",
836 target_pid_to_str (current_event
.dwProcessId
));
838 gdb_flush (gdb_stdout
);
841 push_target (&child_ops
);
845 child_detach (args
, from_tty
)
851 char *exec_file
= get_exec_file (0);
854 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
855 target_pid_to_str (inferior_pid
));
856 gdb_flush (gdb_stdout
);
859 unpush_target (&child_ops
);
862 /* Print status information about what we're accessing. */
865 child_files_info (ignore
)
866 struct target_ops
*ignore
;
868 printf_unfiltered ("\tUsing the running image of %s %s.\n",
869 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
874 child_open (arg
, from_tty
)
878 error ("Use the \"run\" command to start a Unix child process.");
881 /* Start an inferior win32 child process and sets inferior_pid to its pid.
882 EXEC_FILE is the file to run.
883 ALLARGS is a string containing the arguments to the program.
884 ENV is the environment vector to pass. Errors reported with error(). */
887 child_create_inferior (exec_file
, allargs
, env
)
892 char real_path
[MAXPATHLEN
];
898 PROCESS_INFORMATION pi
;
899 struct target_waitstatus dummy
;
907 error ("No executable specified, use `target exec'.\n");
910 memset (&si
, 0, sizeof (si
));
913 cygwin32_conv_to_win32_path (exec_file
, real_path
);
915 flags
= DEBUG_ONLY_THIS_PROCESS
;
918 flags
|= CREATE_NEW_PROCESS_GROUP
;
921 flags
|= CREATE_NEW_CONSOLE
;
923 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
925 strcpy (args
, real_path
);
928 strcat (args
, allargs
);
930 /* Prepare the environment vars for CreateProcess. */
932 /* This code use to assume all env vars were file names and would
933 translate them all to win32 style. That obviously doesn't work in the
934 general case. The current rule is that we only translate PATH.
935 We need to handle PATH because we're about to call CreateProcess and
936 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
937 in both posix and win32 environments. cygwin.dll will change it back
938 to posix style if necessary. */
940 static const char *conv_path_names
[] =
946 /* CreateProcess takes the environment list as a null terminated set of
947 strings (i.e. two nulls terminate the list). */
949 /* Get total size for env strings. */
950 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
954 for (j
= 0; conv_path_names
[j
]; j
++)
956 len
= strlen (conv_path_names
[j
]);
957 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
959 if (cygwin32_posix_path_list_p (env
[i
] + len
))
961 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
963 envlen
+= strlen (env
[i
]) + 1;
967 if (conv_path_names
[j
] == NULL
)
968 envlen
+= strlen (env
[i
]) + 1;
971 winenv
= alloca (envlen
+ 1);
973 /* Copy env strings into new buffer. */
974 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
978 for (j
= 0; conv_path_names
[j
]; j
++)
980 len
= strlen (conv_path_names
[j
]);
981 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
983 if (cygwin32_posix_path_list_p (env
[i
] + len
))
985 memcpy (temp
, env
[i
], len
);
986 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
989 strcpy (temp
, env
[i
]);
993 if (conv_path_names
[j
] == NULL
)
994 strcpy (temp
, env
[i
]);
996 temp
+= strlen (temp
) + 1;
999 /* Final nil string to terminate new env. */
1003 ret
= CreateProcess (0,
1004 args
, /* command line */
1005 NULL
, /* Security */
1007 TRUE
, /* inherit handles */
1008 flags
, /* start flags */
1010 NULL
, /* current directory */
1014 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError ());
1016 exception_count
= 0;
1019 current_process_handle
= pi
.hProcess
;
1020 current_event
.dwProcessId
= pi
.dwProcessId
;
1021 memset (¤t_event
, 0, sizeof (current_event
));
1022 inferior_pid
= current_event
.dwThreadId
= pi
.dwThreadId
;
1023 push_target (&child_ops
);
1024 child_init_thread_list ();
1025 init_wait_for_inferior ();
1026 clear_proceed_status ();
1027 target_terminal_init ();
1028 target_terminal_inferior ();
1030 /* Run until process and threads are loaded */
1032 get_child_debug_event (inferior_pid
, &dummy
, &event_code
, &ret
);
1033 while (event_code
!= EXCEPTION_DEBUG_EVENT
);
1035 SymSetOptions (SYMOPT_DEFERRED_LOADS
);
1036 SymInitialize (current_process_handle
, NULL
, TRUE
);
1038 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1042 child_mourn_inferior ()
1044 continue_status
= DBG_CONTINUE
;
1045 (void) child_continue (-1);
1046 unpush_target (&child_ops
);
1047 generic_mourn_inferior ();
1050 /* Send a SIGINT to the process group. This acts just like the user typed a
1051 ^C on the controlling terminal. */
1056 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1057 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1058 registers_changed (); /* refresh register state */
1062 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1063 int write
, struct target_ops
*target
)
1068 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
1070 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1072 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1076 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
1078 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
1085 child_kill_inferior (void)
1087 CHECK (TerminateProcess (current_process_handle
, 0));
1091 continue_status
= DBG_CONTINUE
;
1092 if (!child_continue (-1))
1094 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1096 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1100 CHECK (CloseHandle (current_process_handle
));
1102 /* this may fail in an attached process so don't check. */
1103 (void) CloseHandle (current_thread
->h
);
1104 target_mourn_inferior (); /* or just child_mourn_inferior? */
1108 child_resume (int pid
, int step
, enum target_signal sig
)
1113 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1116 /* Get context for currently selected thread */
1117 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1121 /* Single step by setting t bit */
1122 child_fetch_inferior_registers (PS_REGNUM
);
1123 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1127 if (th
->context
.ContextFlags
)
1129 CHECK (SetThreadContext (th
->h
, &th
->context
));
1130 th
->context
.ContextFlags
= 0;
1133 /* Allow continuing with the same signal that interrupted us.
1134 Otherwise complain. */
1136 child_continue (pid
);
1140 child_prepare_to_store ()
1142 /* Do nothing, since we can store individual regs */
1154 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1157 struct target_ops child_ops
;
1160 init_child_ops (void)
1162 child_ops
.to_shortname
= "child";
1163 child_ops
.to_longname
= "Win32 child process";
1164 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1165 child_ops
.to_open
= child_open
;
1166 child_ops
.to_close
= child_close
;
1167 child_ops
.to_attach
= child_attach
;
1168 child_ops
.to_detach
= child_detach
;
1169 child_ops
.to_resume
= child_resume
;
1170 child_ops
.to_wait
= child_wait
;
1171 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1172 child_ops
.to_store_registers
= child_store_inferior_registers
;
1173 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1174 child_ops
.to_xfer_memory
= child_xfer_memory
;
1175 child_ops
.to_files_info
= child_files_info
;
1176 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1177 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1178 child_ops
.to_terminal_init
= terminal_init_inferior
;
1179 child_ops
.to_terminal_inferior
= terminal_inferior
;
1180 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1181 child_ops
.to_terminal_ours
= terminal_ours
;
1182 child_ops
.to_terminal_info
= child_terminal_info
;
1183 child_ops
.to_kill
= child_kill_inferior
;
1184 child_ops
.to_load
= 0;
1185 child_ops
.to_lookup_symbol
= 0;
1186 child_ops
.to_create_inferior
= child_create_inferior
;
1187 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1188 child_ops
.to_can_run
= child_can_run
;
1189 child_ops
.to_notice_signals
= 0;
1190 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1191 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
1192 child_ops
.to_stop
= child_stop
;
1193 child_ops
.to_stratum
= process_stratum
;
1194 child_ops
.DONT_USE
= 0;
1195 child_ops
.to_has_all_memory
= 1;
1196 child_ops
.to_has_memory
= 1;
1197 child_ops
.to_has_stack
= 1;
1198 child_ops
.to_has_registers
= 1;
1199 child_ops
.to_has_execution
= 1;
1200 child_ops
.to_sections
= 0;
1201 child_ops
.to_sections_end
= 0;
1202 child_ops
.to_magic
= OPS_MAGIC
;
1206 _initialize_inftarg ()
1208 struct cmd_list_element
*c
;
1212 (add_set_cmd ("new-console", class_support
, var_boolean
,
1213 (char *) &new_console
,
1214 "Set creation of new console when creating child process.",
1219 (add_set_cmd ("new-group", class_support
, var_boolean
,
1220 (char *) &new_group
,
1221 "Set creation of new group when creating child process.",
1226 (add_set_cmd ("debugexec", class_support
, var_boolean
,
1227 (char *) &debug_exec
,
1228 "Set whether to display execution in child process.",
1233 (add_set_cmd ("debugevents", class_support
, var_boolean
,
1234 (char *) &debug_events
,
1235 "Set whether to display kernel events in child process.",
1240 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1241 (char *) &debug_memory
,
1242 "Set whether to display memory accesses in child process.",
1247 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1248 (char *) &debug_exceptions
,
1249 "Set whether to display kernel exceptions in child process.",
1253 add_target (&child_ops
);
1256 /* Determine if the thread referenced by "pid" is alive
1257 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1258 it means that the pid has died. Otherwise it is assumed to be alive. */
1260 win32_child_thread_alive (int pid
)
1262 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1266 /* Convert pid to printable format. */
1268 cygwin_pid_to_str (int pid
)
1270 static char buf
[80];
1271 if (pid
== current_event
.dwProcessId
)
1272 sprintf (buf
, "process %d", pid
);
1274 sprintf (buf
, "thread %d.0x%x", current_event
.dwProcessId
, pid
);
1278 static LPVOID __stdcall
1279 sfta(HANDLE h
, DWORD d
)
1284 static DWORD __stdcall
1285 sgmb(HANDLE h
, DWORD d
)
1290 return SymGetModuleBase (h
, d
) ?: 4;
1295 child_frame_chain(struct frame_info
*f
)
1297 STACKFRAME
*sf
= (STACKFRAME
*) f
->extra_info
;
1298 if (!StackWalk (IMAGE_FILE_MACHINE_I386
, current_process_handle
,
1299 current_thread
->h
, sf
, NULL
, NULL
, SymFunctionTableAccess
, sgmb
, NULL
) ||
1300 !sf
->AddrReturn
.Offset
)
1302 return sf
->AddrFrame
.Offset
;
1306 child_frame_saved_pc(struct frame_info
*f
)
1308 STACKFRAME
*sf
= (STACKFRAME
*) f
->extra_info
;
1309 return sf
->AddrReturn
.Offset
;
1313 child_init_frame(int leaf
, struct frame_info
*f
)
1317 if (f
->next
&& f
->next
->extra_info
)
1318 f
->extra_info
= f
->next
->extra_info
;
1319 else if (f
->prev
&& f
->prev
->extra_info
)
1320 f
->extra_info
= f
->prev
->extra_info
;
1323 sf
= (STACKFRAME
*) frame_obstack_alloc (sizeof (*sf
));
1324 f
->extra_info
= (struct frame_extra_info
*) sf
;
1325 memset (sf
, 0, sizeof(*sf
));
1326 sf
->AddrPC
.Offset
= f
->pc
;
1327 sf
->AddrPC
.Mode
= AddrModeFlat
;
1328 sf
->AddrStack
.Offset
= current_thread
->context
.Esp
;
1329 sf
->AddrStack
.Mode
= AddrModeFlat
;
1330 sf
->AddrFrame
.Offset
= f
->frame
;
1331 sf
->AddrFrame
.Mode
= AddrModeFlat
;