1 /* Target-vector operations for controlling win32 child processes, for GDB.
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
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 */
34 #include <sys/types.h>
40 #else /* other WIN32 compiler */
48 #include "gdb_string.h"
49 #include "gdbthread.h"
51 #include <sys/param.h>
54 /* The ui's event loop. */
55 extern int (*ui_loop_hook
) PARAMS ((int signo
));
57 /* If we're not using the old Cygwin header file set, define the
58 following which never should have been in the generic Win32 API
59 headers in the first place since they were our own invention... */
60 #ifndef _GNU_H_WINDOWS_H
61 #define FLAG_TRACE_BIT 0x100
62 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
65 /* The string sent by cygwin when it processes a signal.
66 FIXME: This should be in a cygwin include file. */
67 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
69 #define CHECK(x) check (x, __FILE__,__LINE__)
70 #define DEBUG_EXEC(x) if (debug_exec) printf x
71 #define DEBUG_EVENTS(x) if (debug_events) printf x
72 #define DEBUG_MEM(x) if (debug_memory) printf x
73 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
75 /* Forward declaration */
76 extern struct target_ops child_ops
;
78 static void child_stop (void);
79 static int win32_child_thread_alive (int);
80 void child_kill_inferior (void);
82 static int last_sig
= 0; /* Set if a signal was received from the
85 /* Thread information structure used to track information that is
86 not available in gdb's thread structure. */
87 typedef struct thread_info_struct
89 struct thread_info_struct
*next
;
98 static thread_info thread_head
= {NULL
};
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 */
107 static int ignore_first_first_chance
= 0; /* True if we should ignore the
108 first first chance exception that we get. */
110 /* Counts of things. */
111 static int exception_count
= 0;
112 static int event_count
= 0;
115 static int new_console
= 0;
116 static int new_group
= 1;
117 static int debug_exec
= 0; /* show execution */
118 static int debug_events
= 0; /* show events from kernel */
119 static int debug_memory
= 0; /* show target memory accesses */
120 static int debug_exceptions
= 0; /* show target exceptions */
122 /* This vector maps GDB's idea of a register's number into an address
123 in the win32 exception context vector.
125 It also contains the bit mask needed to load the register in question.
127 One day we could read a reg, we could inspect the context we
128 already have loaded, if it doesn't have the bit set that we need,
129 we read that set of registers in using GetThreadContext. If the
130 context already contains what we need, we just unpack it. Then to
131 write a register, first we have to ensure that the context contains
132 the other regs of the group, and then we copy the info in and set
135 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
136 static const int mappings
[] =
138 context_offset (Eax
),
139 context_offset (Ecx
),
140 context_offset (Edx
),
141 context_offset (Ebx
),
142 context_offset (Esp
),
143 context_offset (Ebp
),
144 context_offset (Esi
),
145 context_offset (Edi
),
146 context_offset (Eip
),
147 context_offset (EFlags
),
148 context_offset (SegCs
),
149 context_offset (SegSs
),
150 context_offset (SegDs
),
151 context_offset (SegEs
),
152 context_offset (SegFs
),
153 context_offset (SegGs
),
154 context_offset (FloatSave
.RegisterArea
[0 * 10]),
155 context_offset (FloatSave
.RegisterArea
[1 * 10]),
156 context_offset (FloatSave
.RegisterArea
[2 * 10]),
157 context_offset (FloatSave
.RegisterArea
[3 * 10]),
158 context_offset (FloatSave
.RegisterArea
[4 * 10]),
159 context_offset (FloatSave
.RegisterArea
[5 * 10]),
160 context_offset (FloatSave
.RegisterArea
[6 * 10]),
161 context_offset (FloatSave
.RegisterArea
[7 * 10]),
162 context_offset (FloatSave
.ControlWord
),
163 context_offset (FloatSave
.StatusWord
),
164 context_offset (FloatSave
.TagWord
),
165 context_offset (FloatSave
.ErrorSelector
),
166 context_offset (FloatSave
.ErrorOffset
),
167 context_offset (FloatSave
.DataSelector
),
168 context_offset (FloatSave
.DataOffset
),
169 context_offset (FloatSave
.ErrorSelector
)
172 #undef context_offset
174 /* This vector maps the target's idea of an exception (extracted
175 from the DEBUG_EVENT structure) to GDB's idea. */
177 struct xlate_exception
180 enum target_signal us
;
183 static const struct xlate_exception
186 {EXCEPTION_ACCESS_VIOLATION
, TARGET_SIGNAL_SEGV
},
187 {STATUS_STACK_OVERFLOW
, TARGET_SIGNAL_SEGV
},
188 {EXCEPTION_BREAKPOINT
, TARGET_SIGNAL_TRAP
},
189 {DBG_CONTROL_C
, TARGET_SIGNAL_INT
},
190 {EXCEPTION_SINGLE_STEP
, TARGET_SIGNAL_TRAP
},
193 /* Find a thread record given a thread id.
194 If get_context then also retrieve the context for this
197 thread_rec (DWORD id
, int get_context
)
201 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
204 if (!th
->suspend_count
&& get_context
)
206 if (get_context
> 0 && id
!= current_event
.dwThreadId
)
207 th
->suspend_count
= SuspendThread (th
->h
) + 1;
208 else if (get_context
< 0)
209 th
->suspend_count
= -1;
211 th
->context
.ContextFlags
= CONTEXT_DEBUGGER
;
212 GetThreadContext (th
->h
, &th
->context
);
220 /* Add a thread to the thread list */
222 child_add_thread (DWORD id
, HANDLE h
)
226 if ((th
= thread_rec (id
, FALSE
)))
229 th
= (thread_info
*) xmalloc (sizeof (*th
));
230 memset (th
, 0, sizeof (*th
));
233 th
->next
= thread_head
.next
;
234 thread_head
.next
= th
;
239 /* Clear out any old thread list and reintialize it to a
242 child_init_thread_list ()
244 thread_info
*th
= &thread_head
;
246 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
248 while (th
->next
!= NULL
)
250 thread_info
*here
= th
->next
;
251 th
->next
= here
->next
;
252 (void) CloseHandle (here
->h
);
257 /* Delete a thread from the list of threads */
259 child_delete_thread (DWORD id
)
264 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id
));
267 for (th
= &thread_head
;
268 th
->next
!= NULL
&& th
->next
->id
!= id
;
272 if (th
->next
!= NULL
)
274 thread_info
*here
= th
->next
;
275 th
->next
= here
->next
;
276 CloseHandle (here
->h
);
282 check (BOOL ok
, const char *file
, int line
)
285 printf_filtered ("error return %s:%d was %d\n", file
, line
, GetLastError ());
289 do_child_fetch_inferior_registers (int r
)
291 char *context_offset
= ((char *) ¤t_thread
->context
) + mappings
[r
];
295 l
= *((long *)context_offset
) & 0xffff;
296 supply_register (r
, (char *) &l
);
298 else if (r
== FOP_REGNUM
)
300 l
= (*((long *)context_offset
) >> 16) & ((1 << 11) - 1);
301 supply_register (r
, (char *) &l
);
304 supply_register (r
, context_offset
);
307 for (r
= 0; r
< NUM_REGS
; r
++)
308 do_child_fetch_inferior_registers (r
);
313 child_fetch_inferior_registers (int r
)
315 current_thread
= thread_rec (inferior_pid
, TRUE
);
316 do_child_fetch_inferior_registers (r
);
320 do_child_store_inferior_registers (int r
)
323 read_register_gen (r
, ((char *) ¤t_thread
->context
) + mappings
[r
]);
326 for (r
= 0; r
< NUM_REGS
; r
++)
327 do_child_store_inferior_registers (r
);
331 /* Store a new register value into the current thread context */
333 child_store_inferior_registers (int r
)
335 current_thread
= thread_rec (inferior_pid
, TRUE
);
336 do_child_store_inferior_registers (r
);
340 static int psapi_loaded
= 0;
341 static HMODULE psapi_module_handle
= NULL
;
342 static BOOL
WINAPI (*psapi_EnumProcessModules
)(HANDLE
, HMODULE
*, DWORD
, LPDWORD
)= NULL
;
343 static BOOL
WINAPI (*psapi_GetModuleInformation
) (HANDLE
, HMODULE
, LPMODULEINFO
, DWORD
)= NULL
;
344 static DWORD
WINAPI (*psapi_GetModuleFileNameExA
) (HANDLE
, HMODULE
, LPSTR
, DWORD
)= NULL
;
346 int psapi_get_dll_name (DWORD BaseAddress
, char *dll_name_ret
)
351 HMODULE dh_buf
[ 1 ];
352 HMODULE
* DllHandle
= dh_buf
;
357 psapi_EnumProcessModules
== NULL
||
358 psapi_GetModuleInformation
== NULL
||
359 psapi_GetModuleFileNameExA
== NULL
)
361 if (psapi_loaded
)goto failed
;
363 psapi_module_handle
= LoadLibrary ("psapi.dll");
364 if (!psapi_module_handle
)
366 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
369 psapi_EnumProcessModules
= GetProcAddress (psapi_module_handle
, "EnumProcessModules" );
370 psapi_GetModuleInformation
= GetProcAddress (psapi_module_handle
, "GetModuleInformation");
371 psapi_GetModuleFileNameExA
= (void *) GetProcAddress (psapi_module_handle
,
372 "GetModuleFileNameExA");
373 if (psapi_EnumProcessModules
== NULL
||
374 psapi_GetModuleInformation
== NULL
||
375 psapi_GetModuleFileNameExA
== NULL
)
380 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
385 if (!ok
|| !cbNeeded
)
388 DllHandle
= (HMODULE
*) alloca (cbNeeded
);
392 ok
= (*psapi_EnumProcessModules
) (current_process_handle
,
399 for (i
= 0; i
< cbNeeded
/ sizeof (HMODULE
); i
++)
401 if (!(*psapi_GetModuleInformation
) (current_process_handle
,
405 error ("Can't get module info");
407 len
= (*psapi_GetModuleFileNameExA
) (current_process_handle
,
412 error ("Error getting dll name: %u\n", GetLastError ());
414 if ((DWORD
) (mi
.lpBaseOfDll
) == BaseAddress
)
419 dll_name_ret
[0] = '\0';
423 struct safe_symbol_file_add_args
427 struct section_addr_info
*addrs
;
434 safe_symbol_file_add_stub (void *argv
)
436 #define p ((struct safe_symbol_file_add_args *)argv)
437 p
->ret
= symbol_file_add (p
->name
, p
->from_tty
, p
->addrs
, p
->mainline
, p
->flags
);
443 safe_symbol_file_add_cleanup (void *gdb_stderrv
)
445 ui_file_delete (gdb_stderr
);
446 gdb_stderr
= (struct ui_file
*)gdb_stderrv
;
449 static struct objfile
*
450 safe_symbol_file_add (char *name
, int from_tty
,
451 struct section_addr_info
*addrs
,
452 int mainline
, int flags
)
455 struct safe_symbol_file_add_args p
;
456 struct cleanup
*cleanup
;
458 cleanup
= make_cleanup (safe_symbol_file_add_cleanup
, gdb_stderr
);
460 gdb_stderr
= ui_file_new ();
462 p
.from_tty
= from_tty
;
464 p
.mainline
= mainline
;
466 catch_errors (safe_symbol_file_add_stub
, &p
, "", RETURN_MASK_ERROR
);
468 do_cleanups (cleanup
);
472 /* Wait for child to do something. Return pid of child, or -1 in case
473 of error; store status through argument pointer OURSTATUS. */
476 handle_load_dll (PTR dummy
)
478 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
481 char dll_buf
[MAX_PATH
+ 1];
482 char *p
, *dll_name
= NULL
;
483 struct objfile
*objfile
;
484 MEMORY_BASIC_INFORMATION minfo
;
485 struct section_addr_info section_addrs
;
487 memset (§ion_addrs
, 0, sizeof (section_addrs
));
488 dll_buf
[0] = dll_buf
[sizeof (dll_buf
) - 1] = '\0';
490 if (!psapi_get_dll_name ((DWORD
) (event
->lpBaseOfDll
), dll_buf
))
491 dll_buf
[0] = dll_buf
[sizeof(dll_buf
) - 1] = '\0';
495 /* Attempt to read the name of the dll that was detected.
496 This is documented to work only when actively debugging
497 a program. It will not work for attached processes. */
498 if (dll_name
== NULL
|| *dll_name
== '\0')
500 int size
= event
->fUnicode
? sizeof (WCHAR
) : sizeof (char);
504 ReadProcessMemory (current_process_handle
,
505 (LPCVOID
) event
->lpImageName
,
506 (char *) &dll_name_ptr
,
507 sizeof (dll_name_ptr
), &done
);
509 /* See if we could read the address of a string, and that the
510 address isn't null. */
512 if (done
!= sizeof (dll_name_ptr
) || !dll_name_ptr
)
517 ReadProcessMemory (current_process_handle
,
518 (LPCVOID
) (dll_name_ptr
+ len
* size
),
524 while ((b
[0] != 0 || b
[size
- 1] != 0) && done
== size
);
526 dll_name
= alloca (len
);
530 WCHAR
*unicode_dll_name
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
531 ReadProcessMemory (current_process_handle
,
532 (LPCVOID
) dll_name_ptr
,
534 len
* sizeof (WCHAR
),
537 WideCharToMultiByte (CP_ACP
, 0,
538 unicode_dll_name
, len
,
539 dll_name
, len
, 0, 0);
543 ReadProcessMemory (current_process_handle
,
544 (LPCVOID
) dll_name_ptr
,
554 while ((p
= strchr (dll_name
, '\\')))
557 /* The symbols in a dll are offset by 0x1000, which is the
558 the offset from 0 of the first byte in an image - because
559 of the file header and the section alignment. */
561 section_addrs
.other
[0].name
= ".text";
562 section_addrs
.other
[0].addr
= (int) event
->lpBaseOfDll
+ 0x1000;
563 safe_symbol_file_add (dll_name
, 0, §ion_addrs
, 0, OBJF_SHARED
);
564 printf_unfiltered ("%x:%s\n", event
->lpBaseOfDll
, dll_name
);
569 /* Handle DEBUG_STRING output from child process.
570 Cygwin prepends its messages with a "cygwin:". Interpret this as
571 a Cygwin signal. Otherwise just print the string as a warning. */
573 handle_output_debug_string (struct target_waitstatus
*ourstatus
)
578 if (!target_read_string
579 ((CORE_ADDR
) current_event
.u
.DebugString
.lpDebugStringData
, &s
, 1024, 0)
583 if (strncmp (s
, CYGWIN_SIGNAL_STRING
, sizeof (CYGWIN_SIGNAL_STRING
) - 1) != 0)
585 if (strncmp (s
, "cYg", 3) != 0)
591 int sig
= strtol (s
+ sizeof (CYGWIN_SIGNAL_STRING
) - 1, &p
, 0);
592 gotasig
= target_signal_from_host (sig
);
593 ourstatus
->value
.sig
= gotasig
;
595 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
603 handle_exception (struct target_waitstatus
*ourstatus
)
608 int fc
= ignore_first_first_chance
;
610 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
612 ignore_first_first_chance
= 0;
614 /* Record the context of the current thread */
615 th
= thread_rec (current_event
.dwThreadId
, -1);
619 switch (current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
)
621 case EXCEPTION_ACCESS_VIOLATION
:
622 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
623 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
624 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
627 case STATUS_FLOAT_UNDERFLOW
:
628 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
629 case STATUS_FLOAT_OVERFLOW
:
630 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
631 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
632 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
633 ourstatus
->value
.sig
= TARGET_SIGNAL_FPE
;
635 case STATUS_STACK_OVERFLOW
:
636 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
637 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
638 ourstatus
->value
.sig
= TARGET_SIGNAL_SEGV
;
640 case EXCEPTION_BREAKPOINT
:
641 if (fc
&& current_event
.u
.Exception
.dwFirstChance
&&
642 ((DWORD
) current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
& 0xc0000000))
647 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
648 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
649 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
652 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
653 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
654 ourstatus
->value
.sig
= TARGET_SIGNAL_INT
;
655 last_sig
= SIGINT
; /* FIXME - should check pass state */
657 case EXCEPTION_SINGLE_STEP
:
658 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
659 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
660 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
662 case EXCEPTION_ILLEGAL_INSTRUCTION
:
663 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08x\n",
664 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
665 ourstatus
->value
.sig
= TARGET_SIGNAL_ILL
;
669 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
670 current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
671 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
);
672 ourstatus
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
679 /* Resume all artificially suspended threads if we are continuing
682 child_continue (DWORD continue_status
, int id
)
688 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
689 current_event
.dwProcessId
, current_event
.dwThreadId
));
690 res
= ContinueDebugEvent (current_event
.dwProcessId
,
691 current_event
.dwThreadId
,
695 for (th
= &thread_head
; (th
= th
->next
) != NULL
;)
696 if (((id
== -1) || (id
== th
->id
)) && th
->suspend_count
)
698 for (i
= 0; i
< th
->suspend_count
; i
++)
699 (void) ResumeThread (th
->h
);
700 th
->suspend_count
= 0;
706 /* Get the next event from the child. Return 1 if the event requires
707 handling by WFI (or whatever).
710 get_child_debug_event (int pid
, struct target_waitstatus
*ourstatus
,
711 DWORD target_event_code
, int *retval
)
715 DWORD continue_status
, event_code
;
716 thread_info
*th
= NULL
;
717 static thread_info dummy_thread_info
;
719 if (!(debug_event
= WaitForDebugEvent (¤t_event
, 1000)))
726 continue_status
= DBG_CONTINUE
;
729 event_code
= current_event
.dwDebugEventCode
;
730 breakout
= event_code
== target_event_code
;
734 case CREATE_THREAD_DEBUG_EVENT
:
735 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
736 (unsigned) current_event
.dwProcessId
,
737 (unsigned) current_event
.dwThreadId
,
738 "CREATE_THREAD_DEBUG_EVENT"));
739 /* Record the existence of this thread */
740 th
= child_add_thread (current_event
.dwThreadId
,
741 current_event
.u
.CreateThread
.hThread
);
743 printf_unfiltered ("[New %s]\n",
744 target_pid_to_str (current_event
.dwThreadId
));
747 case EXIT_THREAD_DEBUG_EVENT
:
748 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
749 (unsigned) current_event
.dwProcessId
,
750 (unsigned) current_event
.dwThreadId
,
751 "EXIT_THREAD_DEBUG_EVENT"));
752 child_delete_thread (current_event
.dwThreadId
);
753 th
= &dummy_thread_info
;
756 case CREATE_PROCESS_DEBUG_EVENT
:
757 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
758 (unsigned) current_event
.dwProcessId
,
759 (unsigned) current_event
.dwThreadId
,
760 "CREATE_PROCESS_DEBUG_EVENT"));
761 current_process_handle
= current_event
.u
.CreateProcessInfo
.hProcess
;
763 main_thread_id
= inferior_pid
= current_event
.dwThreadId
;
764 /* Add the main thread */
765 th
= child_add_thread (inferior_pid
,
766 current_event
.u
.CreateProcessInfo
.hThread
);
769 case EXIT_PROCESS_DEBUG_EVENT
:
770 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
771 (unsigned) current_event
.dwProcessId
,
772 (unsigned) current_event
.dwThreadId
,
773 "EXIT_PROCESS_DEBUG_EVENT"));
774 ourstatus
->kind
= TARGET_WAITKIND_EXITED
;
775 ourstatus
->value
.integer
= current_event
.u
.ExitProcess
.dwExitCode
;
776 CloseHandle (current_process_handle
);
777 *retval
= current_event
.dwProcessId
;
781 case LOAD_DLL_DEBUG_EVENT
:
782 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
783 (unsigned) current_event
.dwProcessId
,
784 (unsigned) current_event
.dwThreadId
,
785 "LOAD_DLL_DEBUG_EVENT"));
786 catch_errors (handle_load_dll
, NULL
, (char *) "", RETURN_MASK_ALL
);
787 registers_changed (); /* mark all regs invalid */
790 case UNLOAD_DLL_DEBUG_EVENT
:
791 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
792 (unsigned) current_event
.dwProcessId
,
793 (unsigned) current_event
.dwThreadId
,
794 "UNLOAD_DLL_DEBUG_EVENT"));
795 break; /* FIXME: don't know what to do here */
797 case EXCEPTION_DEBUG_EVENT
:
798 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
799 (unsigned) current_event
.dwProcessId
,
800 (unsigned) current_event
.dwThreadId
,
801 "EXCEPTION_DEBUG_EVENT"));
802 if (handle_exception (ourstatus
))
803 *retval
= current_event
.dwThreadId
;
807 continue_status
= DBG_EXCEPTION_NOT_HANDLED
;
812 case OUTPUT_DEBUG_STRING_EVENT
: /* message from the kernel */
813 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
814 (unsigned) current_event
.dwProcessId
,
815 (unsigned) current_event
.dwThreadId
,
816 "OUTPUT_DEBUG_STRING_EVENT"));
817 handle_output_debug_string ( ourstatus
);
820 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
821 current_event
.dwProcessId
,
822 current_event
.dwThreadId
);
823 printf_unfiltered (" unknown event code %d\n",
824 current_event
.dwDebugEventCode
);
829 current_thread
= th
?: thread_rec (current_event
.dwThreadId
, TRUE
);
831 CHECK (child_continue (continue_status
, -1));
837 /* Wait for interesting events to occur in the target process. */
839 child_wait (int pid
, struct target_waitstatus
*ourstatus
)
844 /* We loop when we get a non-standard exception rather than return
845 with a SPURIOUS because resume can try and step or modify things,
846 which needs a current_thread->h. But some of these exceptions mark
847 the birth or death of threads, which mean that the current thread
848 isn't necessarily what you think it is. */
851 if (get_child_debug_event (pid
, ourstatus
, EXCEPTION_DEBUG_EVENT
, &retval
))
857 if (ui_loop_hook
!= NULL
)
858 detach
= ui_loop_hook (0);
861 child_kill_inferior ();
865 /* Attach to process PID, then initialize for debugging it. */
868 child_attach (args
, from_tty
)
875 error_no_arg ("process-id to attach");
877 current_event
.dwProcessId
= strtoul (args
, 0, 0);
879 ok
= DebugActiveProcess (current_event
.dwProcessId
);
882 error ("Can't attach to process.");
889 char *exec_file
= (char *) get_exec_file (0);
892 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file
,
893 target_pid_to_str (current_event
.dwProcessId
));
895 printf_unfiltered ("Attaching to %s\n",
896 target_pid_to_str (current_event
.dwProcessId
));
898 gdb_flush (gdb_stdout
);
901 push_target (&child_ops
);
905 child_detach (args
, from_tty
)
911 char *exec_file
= get_exec_file (0);
914 printf_unfiltered ("Detaching from program: %s %s\n", exec_file
,
915 target_pid_to_str (inferior_pid
));
916 gdb_flush (gdb_stdout
);
919 unpush_target (&child_ops
);
922 /* Print status information about what we're accessing. */
925 child_files_info (ignore
)
926 struct target_ops
*ignore
;
928 printf_unfiltered ("\tUsing the running image of %s %s.\n",
929 attach_flag
? "attached" : "child", target_pid_to_str (inferior_pid
));
934 child_open (arg
, from_tty
)
938 error ("Use the \"run\" command to start a Unix child process.");
941 /* Start an inferior win32 child process and sets inferior_pid to its pid.
942 EXEC_FILE is the file to run.
943 ALLARGS is a string containing the arguments to the program.
944 ENV is the environment vector to pass. Errors reported with error(). */
947 child_create_inferior (exec_file
, allargs
, env
)
952 char real_path
[MAXPATHLEN
];
958 PROCESS_INFORMATION pi
;
959 struct target_waitstatus dummy
;
967 error ("No executable specified, use `target exec'.\n");
970 memset (&si
, 0, sizeof (si
));
973 cygwin32_conv_to_win32_path (exec_file
, real_path
);
975 flags
= DEBUG_ONLY_THIS_PROCESS
;
978 flags
|= CREATE_NEW_PROCESS_GROUP
;
981 flags
|= CREATE_NEW_CONSOLE
;
983 args
= alloca (strlen (real_path
) + strlen (allargs
) + 2);
985 strcpy (args
, real_path
);
988 strcat (args
, allargs
);
990 /* Prepare the environment vars for CreateProcess. */
992 /* This code use to assume all env vars were file names and would
993 translate them all to win32 style. That obviously doesn't work in the
994 general case. The current rule is that we only translate PATH.
995 We need to handle PATH because we're about to call CreateProcess and
996 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
997 in both posix and win32 environments. cygwin.dll will change it back
998 to posix style if necessary. */
1000 static const char *conv_path_names
[] =
1006 /* CreateProcess takes the environment list as a null terminated set of
1007 strings (i.e. two nulls terminate the list). */
1009 /* Get total size for env strings. */
1010 for (envlen
= 0, i
= 0; env
[i
] && *env
[i
]; i
++)
1014 for (j
= 0; conv_path_names
[j
]; j
++)
1016 len
= strlen (conv_path_names
[j
]);
1017 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1019 if (cygwin32_posix_path_list_p (env
[i
] + len
))
1021 + cygwin32_posix_to_win32_path_list_buf_size (env
[i
] + len
);
1023 envlen
+= strlen (env
[i
]) + 1;
1027 if (conv_path_names
[j
] == NULL
)
1028 envlen
+= strlen (env
[i
]) + 1;
1031 winenv
= alloca (envlen
+ 1);
1033 /* Copy env strings into new buffer. */
1034 for (temp
= winenv
, i
= 0; env
[i
] && *env
[i
]; i
++)
1038 for (j
= 0; conv_path_names
[j
]; j
++)
1040 len
= strlen (conv_path_names
[j
]);
1041 if (strncmp (conv_path_names
[j
], env
[i
], len
) == 0)
1043 if (cygwin32_posix_path_list_p (env
[i
] + len
))
1045 memcpy (temp
, env
[i
], len
);
1046 cygwin32_posix_to_win32_path_list (env
[i
] + len
, temp
+ len
);
1049 strcpy (temp
, env
[i
]);
1053 if (conv_path_names
[j
] == NULL
)
1054 strcpy (temp
, env
[i
]);
1056 temp
+= strlen (temp
) + 1;
1059 /* Final nil string to terminate new env. */
1063 ret
= CreateProcess (0,
1064 args
, /* command line */
1065 NULL
, /* Security */
1067 TRUE
, /* inherit handles */
1068 flags
, /* start flags */
1070 NULL
, /* current directory */
1074 error ("Error creating process %s, (error %d)\n", exec_file
, GetLastError ());
1076 exception_count
= 0;
1079 current_process_handle
= pi
.hProcess
;
1080 current_event
.dwProcessId
= pi
.dwProcessId
;
1081 memset (¤t_event
, 0, sizeof (current_event
));
1082 inferior_pid
= current_event
.dwThreadId
= pi
.dwThreadId
;
1083 push_target (&child_ops
);
1084 child_init_thread_list ();
1085 init_wait_for_inferior ();
1086 clear_proceed_status ();
1087 target_terminal_init ();
1088 target_terminal_inferior ();
1090 ignore_first_first_chance
= 1;
1092 /* Run until process and threads are loaded */
1093 while (!get_child_debug_event (inferior_pid
, &dummy
,
1094 CREATE_PROCESS_DEBUG_EVENT
, &ret
))
1097 /* child_continue (DBG_CONTINUE, -1);*/
1098 proceed ((CORE_ADDR
) - 1, TARGET_SIGNAL_0
, 0);
1102 child_mourn_inferior ()
1104 (void) child_continue (DBG_CONTINUE
, -1);
1105 unpush_target (&child_ops
);
1106 generic_mourn_inferior ();
1109 /* Send a SIGINT to the process group. This acts just like the user typed a
1110 ^C on the controlling terminal. */
1115 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1116 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT
, current_event
.dwProcessId
));
1117 registers_changed (); /* refresh register state */
1121 child_xfer_memory (CORE_ADDR memaddr
, char *our
, int len
,
1122 int write
, struct target_ops
*target
)
1127 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
1129 WriteProcessMemory (current_process_handle
, (LPVOID
) memaddr
, our
,
1131 FlushInstructionCache (current_process_handle
, (LPCVOID
) memaddr
, len
);
1135 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
1137 ReadProcessMemory (current_process_handle
, (LPCVOID
) memaddr
, our
, len
,
1144 child_kill_inferior (void)
1146 CHECK (TerminateProcess (current_process_handle
, 0));
1150 if (!child_continue (DBG_CONTINUE
, -1))
1152 if (!WaitForDebugEvent (¤t_event
, INFINITE
))
1154 if (current_event
.dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
1158 CHECK (CloseHandle (current_process_handle
));
1160 /* this may fail in an attached process so don't check. */
1161 (void) CloseHandle (current_thread
->h
);
1162 target_mourn_inferior (); /* or just child_mourn_inferior? */
1166 child_resume (int pid
, int step
, enum target_signal sig
)
1169 DWORD continue_status
= last_sig
> 0 && last_sig
< NSIG
?
1170 DBG_EXCEPTION_NOT_HANDLED
: DBG_CONTINUE
;
1174 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1177 /* Get context for currently selected thread */
1178 th
= thread_rec (current_event
.dwThreadId
, FALSE
);
1182 /* Single step by setting t bit */
1183 child_fetch_inferior_registers (PS_REGNUM
);
1184 th
->context
.EFlags
|= FLAG_TRACE_BIT
;
1188 if (th
->context
.ContextFlags
)
1190 CHECK (SetThreadContext (th
->h
, &th
->context
));
1191 th
->context
.ContextFlags
= 0;
1194 /* Allow continuing with the same signal that interrupted us.
1195 Otherwise complain. */
1197 child_continue (continue_status
, pid
);
1201 child_prepare_to_store ()
1203 /* Do nothing, since we can store individual regs */
1215 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid
));
1218 struct target_ops child_ops
;
1221 init_child_ops (void)
1223 child_ops
.to_shortname
= "child";
1224 child_ops
.to_longname
= "Win32 child process";
1225 child_ops
.to_doc
= "Win32 child process (started by the \"run\" command).";
1226 child_ops
.to_open
= child_open
;
1227 child_ops
.to_close
= child_close
;
1228 child_ops
.to_attach
= child_attach
;
1229 child_ops
.to_detach
= child_detach
;
1230 child_ops
.to_resume
= child_resume
;
1231 child_ops
.to_wait
= child_wait
;
1232 child_ops
.to_fetch_registers
= child_fetch_inferior_registers
;
1233 child_ops
.to_store_registers
= child_store_inferior_registers
;
1234 child_ops
.to_prepare_to_store
= child_prepare_to_store
;
1235 child_ops
.to_xfer_memory
= child_xfer_memory
;
1236 child_ops
.to_files_info
= child_files_info
;
1237 child_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1238 child_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1239 child_ops
.to_terminal_init
= terminal_init_inferior
;
1240 child_ops
.to_terminal_inferior
= terminal_inferior
;
1241 child_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1242 child_ops
.to_terminal_ours
= terminal_ours
;
1243 child_ops
.to_terminal_info
= child_terminal_info
;
1244 child_ops
.to_kill
= child_kill_inferior
;
1245 child_ops
.to_load
= 0;
1246 child_ops
.to_lookup_symbol
= 0;
1247 child_ops
.to_create_inferior
= child_create_inferior
;
1248 child_ops
.to_mourn_inferior
= child_mourn_inferior
;
1249 child_ops
.to_can_run
= child_can_run
;
1250 child_ops
.to_notice_signals
= 0;
1251 child_ops
.to_thread_alive
= win32_child_thread_alive
;
1252 child_ops
.to_pid_to_str
= cygwin_pid_to_str
;
1253 child_ops
.to_stop
= child_stop
;
1254 child_ops
.to_stratum
= process_stratum
;
1255 child_ops
.DONT_USE
= 0;
1256 child_ops
.to_has_all_memory
= 1;
1257 child_ops
.to_has_memory
= 1;
1258 child_ops
.to_has_stack
= 1;
1259 child_ops
.to_has_registers
= 1;
1260 child_ops
.to_has_execution
= 1;
1261 child_ops
.to_sections
= 0;
1262 child_ops
.to_sections_end
= 0;
1263 child_ops
.to_magic
= OPS_MAGIC
;
1267 _initialize_inftarg ()
1272 (add_set_cmd ("new-console", class_support
, var_boolean
,
1273 (char *) &new_console
,
1274 "Set creation of new console when creating child process.",
1279 (add_set_cmd ("new-group", class_support
, var_boolean
,
1280 (char *) &new_group
,
1281 "Set creation of new group when creating child process.",
1286 (add_set_cmd ("debugexec", class_support
, var_boolean
,
1287 (char *) &debug_exec
,
1288 "Set whether to display execution in child process.",
1293 (add_set_cmd ("debugevents", class_support
, var_boolean
,
1294 (char *) &debug_events
,
1295 "Set whether to display kernel events in child process.",
1300 (add_set_cmd ("debugmemory", class_support
, var_boolean
,
1301 (char *) &debug_memory
,
1302 "Set whether to display memory accesses in child process.",
1307 (add_set_cmd ("debugexceptions", class_support
, var_boolean
,
1308 (char *) &debug_exceptions
,
1309 "Set whether to display kernel exceptions in child process.",
1313 add_target (&child_ops
);
1316 /* Determine if the thread referenced by "pid" is alive
1317 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1318 it means that the pid has died. Otherwise it is assumed to be alive. */
1320 win32_child_thread_alive (int pid
)
1322 return WaitForSingleObject (thread_rec (pid
, FALSE
)->h
, 0) == WAIT_OBJECT_0
?
1326 /* Convert pid to printable format. */
1328 cygwin_pid_to_str (int pid
)
1330 static char buf
[80];
1331 if (pid
== current_event
.dwProcessId
)
1332 sprintf (buf
, "process %d", pid
);
1334 sprintf (buf
, "thread %d.0x%x", current_event
.dwProcessId
, pid
);