GDBserver
|
00001 /* Low level interface to Windows debugging, for gdbserver. 00002 Copyright (C) 2006-2013 Free Software Foundation, Inc. 00003 00004 Contributed by Leo Zayas. Based on "win32-nat.c" from GDB. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "server.h" 00022 #include "regcache.h" 00023 #include "gdb/signals.h" 00024 #include "gdb/fileio.h" 00025 #include "mem-break.h" 00026 #include "win32-low.h" 00027 #include "gdbthread.h" 00028 #include "dll.h" 00029 #include "hostio.h" 00030 00031 #include <stdint.h> 00032 #include <windows.h> 00033 #include <winnt.h> 00034 #include <imagehlp.h> 00035 #include <tlhelp32.h> 00036 #include <psapi.h> 00037 #include <process.h> 00038 00039 #ifndef USE_WIN32API 00040 #include <sys/cygwin.h> 00041 #endif 00042 00043 #define OUTMSG(X) do { printf X; fflush (stderr); } while (0) 00044 00045 #define OUTMSG2(X) \ 00046 do \ 00047 { \ 00048 if (debug_threads) \ 00049 { \ 00050 printf X; \ 00051 fflush (stderr); \ 00052 } \ 00053 } while (0) 00054 00055 #ifndef _T 00056 #define _T(x) TEXT (x) 00057 #endif 00058 00059 #ifndef COUNTOF 00060 #define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0])) 00061 #endif 00062 00063 #ifdef _WIN32_WCE 00064 # define GETPROCADDRESS(DLL, PROC) \ 00065 ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC))) 00066 #else 00067 # define GETPROCADDRESS(DLL, PROC) \ 00068 ((winapi_ ## PROC) GetProcAddress (DLL, #PROC)) 00069 #endif 00070 00071 int using_threads = 1; 00072 00073 /* Globals. */ 00074 static int attaching = 0; 00075 static HANDLE current_process_handle = NULL; 00076 static DWORD current_process_id = 0; 00077 static DWORD main_thread_id = 0; 00078 static enum gdb_signal last_sig = GDB_SIGNAL_0; 00079 00080 /* The current debug event from WaitForDebugEvent. */ 00081 static DEBUG_EVENT current_event; 00082 00083 /* Non zero if an interrupt request is to be satisfied by suspending 00084 all threads. */ 00085 static int soft_interrupt_requested = 0; 00086 00087 /* Non zero if the inferior is stopped in a simulated breakpoint done 00088 by suspending all the threads. */ 00089 static int faked_breakpoint = 0; 00090 00091 const struct target_desc *win32_tdesc; 00092 00093 #define NUM_REGS (the_low_target.num_regs) 00094 00095 typedef BOOL (WINAPI *winapi_DebugActiveProcessStop) (DWORD dwProcessId); 00096 typedef BOOL (WINAPI *winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit); 00097 typedef BOOL (WINAPI *winapi_DebugBreakProcess) (HANDLE); 00098 typedef BOOL (WINAPI *winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD); 00099 00100 static void win32_resume (struct thread_resume *resume_info, size_t n); 00101 00102 /* Get the thread ID from the current selected inferior (the current 00103 thread). */ 00104 static ptid_t 00105 current_inferior_ptid (void) 00106 { 00107 return ((struct inferior_list_entry*) current_inferior)->id; 00108 } 00109 00110 /* The current debug event from WaitForDebugEvent. */ 00111 static ptid_t 00112 debug_event_ptid (DEBUG_EVENT *event) 00113 { 00114 return ptid_build (event->dwProcessId, event->dwThreadId, 0); 00115 } 00116 00117 /* Get the thread context of the thread associated with TH. */ 00118 00119 static void 00120 win32_get_thread_context (win32_thread_info *th) 00121 { 00122 memset (&th->context, 0, sizeof (CONTEXT)); 00123 (*the_low_target.get_thread_context) (th, ¤t_event); 00124 #ifdef _WIN32_WCE 00125 memcpy (&th->base_context, &th->context, sizeof (CONTEXT)); 00126 #endif 00127 } 00128 00129 /* Set the thread context of the thread associated with TH. */ 00130 00131 static void 00132 win32_set_thread_context (win32_thread_info *th) 00133 { 00134 #ifdef _WIN32_WCE 00135 /* Calling SuspendThread on a thread that is running kernel code 00136 will report that the suspending was successful, but in fact, that 00137 will often not be true. In those cases, the context returned by 00138 GetThreadContext will not be correct by the time the thread 00139 stops, hence we can't set that context back into the thread when 00140 resuming - it will most likelly crash the inferior. 00141 Unfortunately, there is no way to know when the thread will 00142 really stop. To work around it, we'll only write the context 00143 back to the thread when either the user or GDB explicitly change 00144 it between stopping and resuming. */ 00145 if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0) 00146 #endif 00147 (*the_low_target.set_thread_context) (th, ¤t_event); 00148 } 00149 00150 /* Find a thread record given a thread id. If GET_CONTEXT is set then 00151 also retrieve the context for this thread. */ 00152 static win32_thread_info * 00153 thread_rec (ptid_t ptid, int get_context) 00154 { 00155 struct thread_info *thread; 00156 win32_thread_info *th; 00157 00158 thread = (struct thread_info *) find_inferior_id (&all_threads, ptid); 00159 if (thread == NULL) 00160 return NULL; 00161 00162 th = inferior_target_data (thread); 00163 if (get_context && th->context.ContextFlags == 0) 00164 { 00165 if (!th->suspended) 00166 { 00167 if (SuspendThread (th->h) == (DWORD) -1) 00168 { 00169 DWORD err = GetLastError (); 00170 OUTMSG (("warning: SuspendThread failed in thread_rec, " 00171 "(error %d): %s\n", (int) err, strwinerror (err))); 00172 } 00173 else 00174 th->suspended = 1; 00175 } 00176 00177 win32_get_thread_context (th); 00178 } 00179 00180 return th; 00181 } 00182 00183 /* Add a thread to the thread list. */ 00184 static win32_thread_info * 00185 child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb) 00186 { 00187 win32_thread_info *th; 00188 ptid_t ptid = ptid_build (pid, tid, 0); 00189 00190 if ((th = thread_rec (ptid, FALSE))) 00191 return th; 00192 00193 th = xcalloc (1, sizeof (*th)); 00194 th->tid = tid; 00195 th->h = h; 00196 th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb; 00197 00198 add_thread (ptid, th); 00199 00200 if (the_low_target.thread_added != NULL) 00201 (*the_low_target.thread_added) (th); 00202 00203 return th; 00204 } 00205 00206 /* Delete a thread from the list of threads. */ 00207 static void 00208 delete_thread_info (struct inferior_list_entry *thread) 00209 { 00210 win32_thread_info *th = inferior_target_data ((struct thread_info *) thread); 00211 00212 remove_thread ((struct thread_info *) thread); 00213 CloseHandle (th->h); 00214 free (th); 00215 } 00216 00217 /* Delete a thread from the list of threads. */ 00218 static void 00219 child_delete_thread (DWORD pid, DWORD tid) 00220 { 00221 struct inferior_list_entry *thread; 00222 ptid_t ptid; 00223 00224 /* If the last thread is exiting, just return. */ 00225 if (all_threads.head == all_threads.tail) 00226 return; 00227 00228 ptid = ptid_build (pid, tid, 0); 00229 thread = find_inferior_id (&all_threads, ptid); 00230 if (thread == NULL) 00231 return; 00232 00233 delete_thread_info (thread); 00234 } 00235 00236 /* These watchpoint related wrapper functions simply pass on the function call 00237 if the low target has registered a corresponding function. */ 00238 00239 static int 00240 win32_insert_point (char type, CORE_ADDR addr, int len) 00241 { 00242 if (the_low_target.insert_point != NULL) 00243 return the_low_target.insert_point (type, addr, len); 00244 else 00245 /* Unsupported (see target.h). */ 00246 return 1; 00247 } 00248 00249 static int 00250 win32_remove_point (char type, CORE_ADDR addr, int len) 00251 { 00252 if (the_low_target.remove_point != NULL) 00253 return the_low_target.remove_point (type, addr, len); 00254 else 00255 /* Unsupported (see target.h). */ 00256 return 1; 00257 } 00258 00259 static int 00260 win32_stopped_by_watchpoint (void) 00261 { 00262 if (the_low_target.stopped_by_watchpoint != NULL) 00263 return the_low_target.stopped_by_watchpoint (); 00264 else 00265 return 0; 00266 } 00267 00268 static CORE_ADDR 00269 win32_stopped_data_address (void) 00270 { 00271 if (the_low_target.stopped_data_address != NULL) 00272 return the_low_target.stopped_data_address (); 00273 else 00274 return 0; 00275 } 00276 00277 00278 /* Transfer memory from/to the debugged process. */ 00279 static int 00280 child_xfer_memory (CORE_ADDR memaddr, char *our, int len, 00281 int write, struct target_ops *target) 00282 { 00283 BOOL success; 00284 SIZE_T done = 0; 00285 DWORD lasterror = 0; 00286 uintptr_t addr = (uintptr_t) memaddr; 00287 00288 if (write) 00289 { 00290 success = WriteProcessMemory (current_process_handle, (LPVOID) addr, 00291 (LPCVOID) our, len, &done); 00292 if (!success) 00293 lasterror = GetLastError (); 00294 FlushInstructionCache (current_process_handle, (LPCVOID) addr, len); 00295 } 00296 else 00297 { 00298 success = ReadProcessMemory (current_process_handle, (LPCVOID) addr, 00299 (LPVOID) our, len, &done); 00300 if (!success) 00301 lasterror = GetLastError (); 00302 } 00303 if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0) 00304 return done; 00305 else 00306 return success ? done : -1; 00307 } 00308 00309 /* Clear out any old thread list and reinitialize it to a pristine 00310 state. */ 00311 static void 00312 child_init_thread_list (void) 00313 { 00314 for_each_inferior (&all_threads, delete_thread_info); 00315 } 00316 00317 static void 00318 do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) 00319 { 00320 struct process_info *proc; 00321 00322 last_sig = GDB_SIGNAL_0; 00323 00324 current_process_handle = proch; 00325 current_process_id = pid; 00326 main_thread_id = 0; 00327 00328 soft_interrupt_requested = 0; 00329 faked_breakpoint = 0; 00330 00331 memset (¤t_event, 0, sizeof (current_event)); 00332 00333 proc = add_process (pid, attached); 00334 proc->tdesc = win32_tdesc; 00335 child_init_thread_list (); 00336 00337 if (the_low_target.initial_stuff != NULL) 00338 (*the_low_target.initial_stuff) (); 00339 } 00340 00341 /* Resume all artificially suspended threads if we are continuing 00342 execution. */ 00343 static int 00344 continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr) 00345 { 00346 struct thread_info *thread = (struct thread_info *) this_thread; 00347 int thread_id = * (int *) id_ptr; 00348 win32_thread_info *th = inferior_target_data (thread); 00349 00350 if ((thread_id == -1 || thread_id == th->tid) 00351 && th->suspended) 00352 { 00353 if (th->context.ContextFlags) 00354 { 00355 win32_set_thread_context (th); 00356 th->context.ContextFlags = 0; 00357 } 00358 00359 if (ResumeThread (th->h) == (DWORD) -1) 00360 { 00361 DWORD err = GetLastError (); 00362 OUTMSG (("warning: ResumeThread failed in continue_one_thread, " 00363 "(error %d): %s\n", (int) err, strwinerror (err))); 00364 } 00365 th->suspended = 0; 00366 } 00367 00368 return 0; 00369 } 00370 00371 static BOOL 00372 child_continue (DWORD continue_status, int thread_id) 00373 { 00374 /* The inferior will only continue after the ContinueDebugEvent 00375 call. */ 00376 find_inferior (&all_threads, continue_one_thread, &thread_id); 00377 faked_breakpoint = 0; 00378 00379 if (!ContinueDebugEvent (current_event.dwProcessId, 00380 current_event.dwThreadId, 00381 continue_status)) 00382 return FALSE; 00383 00384 return TRUE; 00385 } 00386 00387 /* Fetch register(s) from the current thread context. */ 00388 static void 00389 child_fetch_inferior_registers (struct regcache *regcache, int r) 00390 { 00391 int regno; 00392 win32_thread_info *th = thread_rec (current_inferior_ptid (), TRUE); 00393 if (r == -1 || r > NUM_REGS) 00394 child_fetch_inferior_registers (regcache, NUM_REGS); 00395 else 00396 for (regno = 0; regno < r; regno++) 00397 (*the_low_target.fetch_inferior_register) (regcache, th, regno); 00398 } 00399 00400 /* Store a new register value into the current thread context. We don't 00401 change the program's context until later, when we resume it. */ 00402 static void 00403 child_store_inferior_registers (struct regcache *regcache, int r) 00404 { 00405 int regno; 00406 win32_thread_info *th = thread_rec (current_inferior_ptid (), TRUE); 00407 if (r == -1 || r == 0 || r > NUM_REGS) 00408 child_store_inferior_registers (regcache, NUM_REGS); 00409 else 00410 for (regno = 0; regno < r; regno++) 00411 (*the_low_target.store_inferior_register) (regcache, th, regno); 00412 } 00413 00414 /* Map the Windows error number in ERROR to a locale-dependent error 00415 message string and return a pointer to it. Typically, the values 00416 for ERROR come from GetLastError. 00417 00418 The string pointed to shall not be modified by the application, 00419 but may be overwritten by a subsequent call to strwinerror 00420 00421 The strwinerror function does not change the current setting 00422 of GetLastError. */ 00423 00424 char * 00425 strwinerror (DWORD error) 00426 { 00427 static char buf[1024]; 00428 TCHAR *msgbuf; 00429 DWORD lasterr = GetLastError (); 00430 DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM 00431 | FORMAT_MESSAGE_ALLOCATE_BUFFER, 00432 NULL, 00433 error, 00434 0, /* Default language */ 00435 (LPVOID)&msgbuf, 00436 0, 00437 NULL); 00438 if (chars != 0) 00439 { 00440 /* If there is an \r\n appended, zap it. */ 00441 if (chars >= 2 00442 && msgbuf[chars - 2] == '\r' 00443 && msgbuf[chars - 1] == '\n') 00444 { 00445 chars -= 2; 00446 msgbuf[chars] = 0; 00447 } 00448 00449 if (chars > ((COUNTOF (buf)) - 1)) 00450 { 00451 chars = COUNTOF (buf) - 1; 00452 msgbuf [chars] = 0; 00453 } 00454 00455 #ifdef UNICODE 00456 wcstombs (buf, msgbuf, chars + 1); 00457 #else 00458 strncpy (buf, msgbuf, chars + 1); 00459 #endif 00460 LocalFree (msgbuf); 00461 } 00462 else 00463 sprintf (buf, "unknown win32 error (%u)", (unsigned) error); 00464 00465 SetLastError (lasterr); 00466 return buf; 00467 } 00468 00469 static BOOL 00470 create_process (const char *program, char *args, 00471 DWORD flags, PROCESS_INFORMATION *pi) 00472 { 00473 BOOL ret; 00474 00475 #ifdef _WIN32_WCE 00476 wchar_t *p, *wprogram, *wargs; 00477 size_t argslen; 00478 00479 wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t)); 00480 mbstowcs (wprogram, program, strlen (program) + 1); 00481 00482 for (p = wprogram; *p; ++p) 00483 if (L'/' == *p) 00484 *p = L'\\'; 00485 00486 argslen = strlen (args); 00487 wargs = alloca ((argslen + 1) * sizeof (wchar_t)); 00488 mbstowcs (wargs, args, argslen + 1); 00489 00490 ret = CreateProcessW (wprogram, /* image name */ 00491 wargs, /* command line */ 00492 NULL, /* security, not supported */ 00493 NULL, /* thread, not supported */ 00494 FALSE, /* inherit handles, not supported */ 00495 flags, /* start flags */ 00496 NULL, /* environment, not supported */ 00497 NULL, /* current directory, not supported */ 00498 NULL, /* start info, not supported */ 00499 pi); /* proc info */ 00500 #else 00501 STARTUPINFOA si = { sizeof (STARTUPINFOA) }; 00502 00503 ret = CreateProcessA (program, /* image name */ 00504 args, /* command line */ 00505 NULL, /* security */ 00506 NULL, /* thread */ 00507 TRUE, /* inherit handles */ 00508 flags, /* start flags */ 00509 NULL, /* environment */ 00510 NULL, /* current directory */ 00511 &si, /* start info */ 00512 pi); /* proc info */ 00513 #endif 00514 00515 return ret; 00516 } 00517 00518 /* Start a new process. 00519 PROGRAM is a path to the program to execute. 00520 ARGS is a standard NULL-terminated array of arguments, 00521 to be passed to the inferior as ``argv''. 00522 Returns the new PID on success, -1 on failure. Registers the new 00523 process with the process list. */ 00524 static int 00525 win32_create_inferior (char *program, char **program_args) 00526 { 00527 #ifndef USE_WIN32API 00528 char real_path[PATH_MAX]; 00529 char *orig_path, *new_path, *path_ptr; 00530 #endif 00531 BOOL ret; 00532 DWORD flags; 00533 char *args; 00534 int argslen; 00535 int argc; 00536 PROCESS_INFORMATION pi; 00537 DWORD err; 00538 00539 /* win32_wait needs to know we're not attaching. */ 00540 attaching = 0; 00541 00542 if (!program) 00543 error ("No executable specified, specify executable to debug.\n"); 00544 00545 flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; 00546 00547 #ifndef USE_WIN32API 00548 orig_path = NULL; 00549 path_ptr = getenv ("PATH"); 00550 if (path_ptr) 00551 { 00552 int size = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, NULL, 0); 00553 orig_path = alloca (strlen (path_ptr) + 1); 00554 new_path = alloca (size); 00555 strcpy (orig_path, path_ptr); 00556 cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, path_ptr, new_path, size); 00557 setenv ("PATH", new_path, 1); 00558 } 00559 cygwin_conv_path (CCP_POSIX_TO_WIN_A, program, real_path, PATH_MAX); 00560 program = real_path; 00561 #endif 00562 00563 argslen = 1; 00564 for (argc = 1; program_args[argc]; argc++) 00565 argslen += strlen (program_args[argc]) + 1; 00566 args = alloca (argslen); 00567 args[0] = '\0'; 00568 for (argc = 1; program_args[argc]; argc++) 00569 { 00570 /* FIXME: Can we do better about quoting? How does Cygwin 00571 handle this? */ 00572 strcat (args, " "); 00573 strcat (args, program_args[argc]); 00574 } 00575 OUTMSG2 (("Command line is \"%s\"\n", args)); 00576 00577 #ifdef CREATE_NEW_PROCESS_GROUP 00578 flags |= CREATE_NEW_PROCESS_GROUP; 00579 #endif 00580 00581 ret = create_process (program, args, flags, &pi); 00582 err = GetLastError (); 00583 if (!ret && err == ERROR_FILE_NOT_FOUND) 00584 { 00585 char *exename = alloca (strlen (program) + 5); 00586 strcat (strcpy (exename, program), ".exe"); 00587 ret = create_process (exename, args, flags, &pi); 00588 err = GetLastError (); 00589 } 00590 00591 #ifndef USE_WIN32API 00592 if (orig_path) 00593 setenv ("PATH", orig_path, 1); 00594 #endif 00595 00596 if (!ret) 00597 { 00598 error ("Error creating process \"%s%s\", (error %d): %s\n", 00599 program, args, (int) err, strwinerror (err)); 00600 } 00601 else 00602 { 00603 OUTMSG2 (("Process created: %s\n", (char *) args)); 00604 } 00605 00606 #ifndef _WIN32_WCE 00607 /* On Windows CE this handle can't be closed. The OS reuses 00608 it in the debug events, while the 9x/NT versions of Windows 00609 probably use a DuplicateHandle'd one. */ 00610 CloseHandle (pi.hThread); 00611 #endif 00612 00613 do_initial_child_stuff (pi.hProcess, pi.dwProcessId, 0); 00614 00615 return current_process_id; 00616 } 00617 00618 /* Attach to a running process. 00619 PID is the process ID to attach to, specified by the user 00620 or a higher layer. */ 00621 static int 00622 win32_attach (unsigned long pid) 00623 { 00624 HANDLE h; 00625 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; 00626 DWORD err; 00627 #ifdef _WIN32_WCE 00628 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); 00629 #else 00630 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); 00631 #endif 00632 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); 00633 00634 h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); 00635 if (h != NULL) 00636 { 00637 if (DebugActiveProcess (pid)) 00638 { 00639 if (DebugSetProcessKillOnExit != NULL) 00640 DebugSetProcessKillOnExit (FALSE); 00641 00642 /* win32_wait needs to know we're attaching. */ 00643 attaching = 1; 00644 do_initial_child_stuff (h, pid, 1); 00645 return 0; 00646 } 00647 00648 CloseHandle (h); 00649 } 00650 00651 err = GetLastError (); 00652 error ("Attach to process failed (error %d): %s\n", 00653 (int) err, strwinerror (err)); 00654 } 00655 00656 /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */ 00657 static void 00658 handle_output_debug_string (struct target_waitstatus *ourstatus) 00659 { 00660 #define READ_BUFFER_LEN 1024 00661 CORE_ADDR addr; 00662 char s[READ_BUFFER_LEN + 1] = { 0 }; 00663 DWORD nbytes = current_event.u.DebugString.nDebugStringLength; 00664 00665 if (nbytes == 0) 00666 return; 00667 00668 if (nbytes > READ_BUFFER_LEN) 00669 nbytes = READ_BUFFER_LEN; 00670 00671 addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData; 00672 00673 if (current_event.u.DebugString.fUnicode) 00674 { 00675 /* The event tells us how many bytes, not chars, even 00676 in Unicode. */ 00677 WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 }; 00678 if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0) 00679 return; 00680 wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR)); 00681 } 00682 else 00683 { 00684 if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) 00685 return; 00686 } 00687 00688 if (strncmp (s, "cYg", 3) != 0) 00689 { 00690 if (!server_waiting) 00691 { 00692 OUTMSG2(("%s", s)); 00693 return; 00694 } 00695 00696 monitor_output (s); 00697 } 00698 #undef READ_BUFFER_LEN 00699 } 00700 00701 static void 00702 win32_clear_inferiors (void) 00703 { 00704 if (current_process_handle != NULL) 00705 CloseHandle (current_process_handle); 00706 00707 for_each_inferior (&all_threads, delete_thread_info); 00708 clear_inferiors (); 00709 } 00710 00711 /* Kill all inferiors. */ 00712 static int 00713 win32_kill (int pid) 00714 { 00715 struct process_info *process; 00716 00717 if (current_process_handle == NULL) 00718 return -1; 00719 00720 TerminateProcess (current_process_handle, 0); 00721 for (;;) 00722 { 00723 if (!child_continue (DBG_CONTINUE, -1)) 00724 break; 00725 if (!WaitForDebugEvent (¤t_event, INFINITE)) 00726 break; 00727 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) 00728 break; 00729 else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) 00730 { 00731 struct target_waitstatus our_status = { 0 }; 00732 handle_output_debug_string (&our_status); 00733 } 00734 } 00735 00736 win32_clear_inferiors (); 00737 00738 process = find_process_pid (pid); 00739 remove_process (process); 00740 return 0; 00741 } 00742 00743 /* Detach from inferior PID. */ 00744 static int 00745 win32_detach (int pid) 00746 { 00747 struct process_info *process; 00748 winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL; 00749 winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; 00750 #ifdef _WIN32_WCE 00751 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); 00752 #else 00753 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); 00754 #endif 00755 DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop); 00756 DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); 00757 00758 if (DebugSetProcessKillOnExit == NULL 00759 || DebugActiveProcessStop == NULL) 00760 return -1; 00761 00762 { 00763 struct thread_resume resume; 00764 resume.thread = minus_one_ptid; 00765 resume.kind = resume_continue; 00766 resume.sig = 0; 00767 win32_resume (&resume, 1); 00768 } 00769 00770 if (!DebugActiveProcessStop (current_process_id)) 00771 return -1; 00772 00773 DebugSetProcessKillOnExit (FALSE); 00774 process = find_process_pid (pid); 00775 remove_process (process); 00776 00777 win32_clear_inferiors (); 00778 return 0; 00779 } 00780 00781 static void 00782 win32_mourn (struct process_info *process) 00783 { 00784 remove_process (process); 00785 } 00786 00787 /* Wait for inferiors to end. */ 00788 static void 00789 win32_join (int pid) 00790 { 00791 HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); 00792 if (h != NULL) 00793 { 00794 WaitForSingleObject (h, INFINITE); 00795 CloseHandle (h); 00796 } 00797 } 00798 00799 /* Return 1 iff the thread with thread ID TID is alive. */ 00800 static int 00801 win32_thread_alive (ptid_t ptid) 00802 { 00803 int res; 00804 00805 /* Our thread list is reliable; don't bother to poll target 00806 threads. */ 00807 if (find_inferior_id (&all_threads, ptid) != NULL) 00808 res = 1; 00809 else 00810 res = 0; 00811 return res; 00812 } 00813 00814 /* Resume the inferior process. RESUME_INFO describes how we want 00815 to resume. */ 00816 static void 00817 win32_resume (struct thread_resume *resume_info, size_t n) 00818 { 00819 DWORD tid; 00820 enum gdb_signal sig; 00821 int step; 00822 win32_thread_info *th; 00823 DWORD continue_status = DBG_CONTINUE; 00824 ptid_t ptid; 00825 00826 /* This handles the very limited set of resume packets that GDB can 00827 currently produce. */ 00828 00829 if (n == 1 && ptid_equal (resume_info[0].thread, minus_one_ptid)) 00830 tid = -1; 00831 else if (n > 1) 00832 tid = -1; 00833 else 00834 /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make 00835 the Windows resume code do the right thing for thread switching. */ 00836 tid = current_event.dwThreadId; 00837 00838 if (!ptid_equal (resume_info[0].thread, minus_one_ptid)) 00839 { 00840 sig = resume_info[0].sig; 00841 step = resume_info[0].kind == resume_step; 00842 } 00843 else 00844 { 00845 sig = 0; 00846 step = 0; 00847 } 00848 00849 if (sig != GDB_SIGNAL_0) 00850 { 00851 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) 00852 { 00853 OUTMSG (("Cannot continue with signal %d here.\n", sig)); 00854 } 00855 else if (sig == last_sig) 00856 continue_status = DBG_EXCEPTION_NOT_HANDLED; 00857 else 00858 OUTMSG (("Can only continue with recieved signal %d.\n", last_sig)); 00859 } 00860 00861 last_sig = GDB_SIGNAL_0; 00862 00863 /* Get context for the currently selected thread. */ 00864 ptid = debug_event_ptid (¤t_event); 00865 th = thread_rec (ptid, FALSE); 00866 if (th) 00867 { 00868 if (th->context.ContextFlags) 00869 { 00870 /* Move register values from the inferior into the thread 00871 context structure. */ 00872 regcache_invalidate (); 00873 00874 if (step) 00875 { 00876 if (the_low_target.single_step != NULL) 00877 (*the_low_target.single_step) (th); 00878 else 00879 error ("Single stepping is not supported " 00880 "in this configuration.\n"); 00881 } 00882 00883 win32_set_thread_context (th); 00884 th->context.ContextFlags = 0; 00885 } 00886 } 00887 00888 /* Allow continuing with the same signal that interrupted us. 00889 Otherwise complain. */ 00890 00891 child_continue (continue_status, tid); 00892 } 00893 00894 static void 00895 win32_add_one_solib (const char *name, CORE_ADDR load_addr) 00896 { 00897 char buf[MAX_PATH + 1]; 00898 char buf2[MAX_PATH + 1]; 00899 00900 #ifdef _WIN32_WCE 00901 WIN32_FIND_DATA w32_fd; 00902 WCHAR wname[MAX_PATH + 1]; 00903 mbstowcs (wname, name, MAX_PATH); 00904 HANDLE h = FindFirstFile (wname, &w32_fd); 00905 #else 00906 WIN32_FIND_DATAA w32_fd; 00907 HANDLE h = FindFirstFileA (name, &w32_fd); 00908 #endif 00909 00910 if (h == INVALID_HANDLE_VALUE) 00911 strcpy (buf, name); 00912 else 00913 { 00914 FindClose (h); 00915 strcpy (buf, name); 00916 #ifndef _WIN32_WCE 00917 { 00918 char cwd[MAX_PATH + 1]; 00919 char *p; 00920 if (GetCurrentDirectoryA (MAX_PATH + 1, cwd)) 00921 { 00922 p = strrchr (buf, '\\'); 00923 if (p) 00924 p[1] = '\0'; 00925 SetCurrentDirectoryA (buf); 00926 GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p); 00927 SetCurrentDirectoryA (cwd); 00928 } 00929 } 00930 #endif 00931 } 00932 00933 #ifndef _WIN32_WCE 00934 if (strcasecmp (buf, "ntdll.dll") == 0) 00935 { 00936 GetSystemDirectoryA (buf, sizeof (buf)); 00937 strcat (buf, "\\ntdll.dll"); 00938 } 00939 #endif 00940 00941 #ifdef __CYGWIN__ 00942 cygwin_conv_path (CCP_WIN_A_TO_POSIX, buf, buf2, sizeof (buf2)); 00943 #else 00944 strcpy (buf2, buf); 00945 #endif 00946 00947 loaded_dll (buf2, load_addr); 00948 } 00949 00950 static char * 00951 get_image_name (HANDLE h, void *address, int unicode) 00952 { 00953 static char buf[(2 * MAX_PATH) + 1]; 00954 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); 00955 char *address_ptr; 00956 int len = 0; 00957 char b[2]; 00958 SIZE_T done; 00959 00960 /* Attempt to read the name of the dll that was detected. 00961 This is documented to work only when actively debugging 00962 a program. It will not work for attached processes. */ 00963 if (address == NULL) 00964 return NULL; 00965 00966 #ifdef _WIN32_WCE 00967 /* Windows CE reports the address of the image name, 00968 instead of an address of a pointer into the image name. */ 00969 address_ptr = address; 00970 #else 00971 /* See if we could read the address of a string, and that the 00972 address isn't null. */ 00973 if (!ReadProcessMemory (h, address, &address_ptr, 00974 sizeof (address_ptr), &done) 00975 || done != sizeof (address_ptr) 00976 || !address_ptr) 00977 return NULL; 00978 #endif 00979 00980 /* Find the length of the string */ 00981 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) 00982 && (b[0] != 0 || b[size - 1] != 0) && done == size) 00983 continue; 00984 00985 if (!unicode) 00986 ReadProcessMemory (h, address_ptr, buf, len, &done); 00987 else 00988 { 00989 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR)); 00990 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), 00991 &done); 00992 00993 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0); 00994 } 00995 00996 return buf; 00997 } 00998 00999 typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *, 01000 DWORD, LPDWORD); 01001 typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE, 01002 LPMODULEINFO, DWORD); 01003 typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE, 01004 LPSTR, DWORD); 01005 01006 static winapi_EnumProcessModules win32_EnumProcessModules; 01007 static winapi_GetModuleInformation win32_GetModuleInformation; 01008 static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA; 01009 01010 static BOOL 01011 load_psapi (void) 01012 { 01013 static int psapi_loaded = 0; 01014 static HMODULE dll = NULL; 01015 01016 if (!psapi_loaded) 01017 { 01018 psapi_loaded = 1; 01019 dll = LoadLibrary (TEXT("psapi.dll")); 01020 if (!dll) 01021 return FALSE; 01022 win32_EnumProcessModules = 01023 GETPROCADDRESS (dll, EnumProcessModules); 01024 win32_GetModuleInformation = 01025 GETPROCADDRESS (dll, GetModuleInformation); 01026 win32_GetModuleFileNameExA = 01027 GETPROCADDRESS (dll, GetModuleFileNameExA); 01028 } 01029 01030 return (win32_EnumProcessModules != NULL 01031 && win32_GetModuleInformation != NULL 01032 && win32_GetModuleFileNameExA != NULL); 01033 } 01034 01035 static int 01036 psapi_get_dll_name (LPVOID BaseAddress, char *dll_name_ret) 01037 { 01038 DWORD len; 01039 MODULEINFO mi; 01040 size_t i; 01041 HMODULE dh_buf[1]; 01042 HMODULE *DllHandle = dh_buf; 01043 DWORD cbNeeded; 01044 BOOL ok; 01045 01046 if (!load_psapi ()) 01047 goto failed; 01048 01049 cbNeeded = 0; 01050 ok = (*win32_EnumProcessModules) (current_process_handle, 01051 DllHandle, 01052 sizeof (HMODULE), 01053 &cbNeeded); 01054 01055 if (!ok || !cbNeeded) 01056 goto failed; 01057 01058 DllHandle = (HMODULE *) alloca (cbNeeded); 01059 if (!DllHandle) 01060 goto failed; 01061 01062 ok = (*win32_EnumProcessModules) (current_process_handle, 01063 DllHandle, 01064 cbNeeded, 01065 &cbNeeded); 01066 if (!ok) 01067 goto failed; 01068 01069 for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++) 01070 { 01071 if (!(*win32_GetModuleInformation) (current_process_handle, 01072 DllHandle[i], 01073 &mi, 01074 sizeof (mi))) 01075 { 01076 DWORD err = GetLastError (); 01077 error ("Can't get module info: (error %d): %s\n", 01078 (int) err, strwinerror (err)); 01079 } 01080 01081 if (mi.lpBaseOfDll == BaseAddress) 01082 { 01083 len = (*win32_GetModuleFileNameExA) (current_process_handle, 01084 DllHandle[i], 01085 dll_name_ret, 01086 MAX_PATH); 01087 if (len == 0) 01088 { 01089 DWORD err = GetLastError (); 01090 error ("Error getting dll name: (error %d): %s\n", 01091 (int) err, strwinerror (err)); 01092 } 01093 return 1; 01094 } 01095 } 01096 01097 failed: 01098 dll_name_ret[0] = '\0'; 01099 return 0; 01100 } 01101 01102 typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD); 01103 typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32); 01104 typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32); 01105 01106 static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot; 01107 static winapi_Module32First win32_Module32First; 01108 static winapi_Module32Next win32_Module32Next; 01109 #ifdef _WIN32_WCE 01110 typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE); 01111 static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot; 01112 #endif 01113 01114 static BOOL 01115 load_toolhelp (void) 01116 { 01117 static int toolhelp_loaded = 0; 01118 static HMODULE dll = NULL; 01119 01120 if (!toolhelp_loaded) 01121 { 01122 toolhelp_loaded = 1; 01123 #ifndef _WIN32_WCE 01124 dll = GetModuleHandle (_T("KERNEL32.DLL")); 01125 #else 01126 dll = LoadLibrary (L"TOOLHELP.DLL"); 01127 #endif 01128 if (!dll) 01129 return FALSE; 01130 01131 win32_CreateToolhelp32Snapshot = 01132 GETPROCADDRESS (dll, CreateToolhelp32Snapshot); 01133 win32_Module32First = GETPROCADDRESS (dll, Module32First); 01134 win32_Module32Next = GETPROCADDRESS (dll, Module32Next); 01135 #ifdef _WIN32_WCE 01136 win32_CloseToolhelp32Snapshot = 01137 GETPROCADDRESS (dll, CloseToolhelp32Snapshot); 01138 #endif 01139 } 01140 01141 return (win32_CreateToolhelp32Snapshot != NULL 01142 && win32_Module32First != NULL 01143 && win32_Module32Next != NULL 01144 #ifdef _WIN32_WCE 01145 && win32_CloseToolhelp32Snapshot != NULL 01146 #endif 01147 ); 01148 } 01149 01150 static int 01151 toolhelp_get_dll_name (LPVOID BaseAddress, char *dll_name_ret) 01152 { 01153 HANDLE snapshot_module; 01154 MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) }; 01155 int found = 0; 01156 01157 if (!load_toolhelp ()) 01158 return 0; 01159 01160 snapshot_module = win32_CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 01161 current_event.dwProcessId); 01162 if (snapshot_module == INVALID_HANDLE_VALUE) 01163 return 0; 01164 01165 /* Ignore the first module, which is the exe. */ 01166 if (win32_Module32First (snapshot_module, &modEntry)) 01167 while (win32_Module32Next (snapshot_module, &modEntry)) 01168 if (modEntry.modBaseAddr == BaseAddress) 01169 { 01170 #ifdef UNICODE 01171 wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1); 01172 #else 01173 strcpy (dll_name_ret, modEntry.szExePath); 01174 #endif 01175 found = 1; 01176 break; 01177 } 01178 01179 #ifdef _WIN32_WCE 01180 win32_CloseToolhelp32Snapshot (snapshot_module); 01181 #else 01182 CloseHandle (snapshot_module); 01183 #endif 01184 return found; 01185 } 01186 01187 static void 01188 handle_load_dll (void) 01189 { 01190 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; 01191 char dll_buf[MAX_PATH + 1]; 01192 char *dll_name = NULL; 01193 CORE_ADDR load_addr; 01194 01195 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; 01196 01197 /* Windows does not report the image name of the dlls in the debug 01198 event on attaches. We resort to iterating over the list of 01199 loaded dlls looking for a match by image base. */ 01200 if (!psapi_get_dll_name (event->lpBaseOfDll, dll_buf)) 01201 { 01202 if (!server_waiting) 01203 /* On some versions of Windows and Windows CE, we can't create 01204 toolhelp snapshots while the inferior is stopped in a 01205 LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while 01206 Windows is reporting the already loaded dlls. */ 01207 toolhelp_get_dll_name (event->lpBaseOfDll, dll_buf); 01208 } 01209 01210 dll_name = dll_buf; 01211 01212 if (*dll_name == '\0') 01213 dll_name = get_image_name (current_process_handle, 01214 event->lpImageName, event->fUnicode); 01215 if (!dll_name) 01216 return; 01217 01218 /* The symbols in a dll are offset by 0x1000, which is the 01219 offset from 0 of the first byte in an image - because 01220 of the file header and the section alignment. */ 01221 01222 load_addr = (CORE_ADDR) (uintptr_t) event->lpBaseOfDll + 0x1000; 01223 win32_add_one_solib (dll_name, load_addr); 01224 } 01225 01226 static void 01227 handle_unload_dll (void) 01228 { 01229 CORE_ADDR load_addr = 01230 (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll; 01231 load_addr += 0x1000; 01232 unloaded_dll (NULL, load_addr); 01233 } 01234 01235 static void 01236 handle_exception (struct target_waitstatus *ourstatus) 01237 { 01238 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; 01239 01240 ourstatus->kind = TARGET_WAITKIND_STOPPED; 01241 01242 switch (code) 01243 { 01244 case EXCEPTION_ACCESS_VIOLATION: 01245 OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION")); 01246 ourstatus->value.sig = GDB_SIGNAL_SEGV; 01247 break; 01248 case STATUS_STACK_OVERFLOW: 01249 OUTMSG2 (("STATUS_STACK_OVERFLOW")); 01250 ourstatus->value.sig = GDB_SIGNAL_SEGV; 01251 break; 01252 case STATUS_FLOAT_DENORMAL_OPERAND: 01253 OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND")); 01254 ourstatus->value.sig = GDB_SIGNAL_FPE; 01255 break; 01256 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 01257 OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); 01258 ourstatus->value.sig = GDB_SIGNAL_FPE; 01259 break; 01260 case STATUS_FLOAT_INEXACT_RESULT: 01261 OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT")); 01262 ourstatus->value.sig = GDB_SIGNAL_FPE; 01263 break; 01264 case STATUS_FLOAT_INVALID_OPERATION: 01265 OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION")); 01266 ourstatus->value.sig = GDB_SIGNAL_FPE; 01267 break; 01268 case STATUS_FLOAT_OVERFLOW: 01269 OUTMSG2 (("STATUS_FLOAT_OVERFLOW")); 01270 ourstatus->value.sig = GDB_SIGNAL_FPE; 01271 break; 01272 case STATUS_FLOAT_STACK_CHECK: 01273 OUTMSG2 (("STATUS_FLOAT_STACK_CHECK")); 01274 ourstatus->value.sig = GDB_SIGNAL_FPE; 01275 break; 01276 case STATUS_FLOAT_UNDERFLOW: 01277 OUTMSG2 (("STATUS_FLOAT_UNDERFLOW")); 01278 ourstatus->value.sig = GDB_SIGNAL_FPE; 01279 break; 01280 case STATUS_FLOAT_DIVIDE_BY_ZERO: 01281 OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO")); 01282 ourstatus->value.sig = GDB_SIGNAL_FPE; 01283 break; 01284 case STATUS_INTEGER_DIVIDE_BY_ZERO: 01285 OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO")); 01286 ourstatus->value.sig = GDB_SIGNAL_FPE; 01287 break; 01288 case STATUS_INTEGER_OVERFLOW: 01289 OUTMSG2 (("STATUS_INTEGER_OVERFLOW")); 01290 ourstatus->value.sig = GDB_SIGNAL_FPE; 01291 break; 01292 case EXCEPTION_BREAKPOINT: 01293 OUTMSG2 (("EXCEPTION_BREAKPOINT")); 01294 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01295 #ifdef _WIN32_WCE 01296 /* Remove the initial breakpoint. */ 01297 check_breakpoints ((CORE_ADDR) (long) current_event 01298 .u.Exception.ExceptionRecord.ExceptionAddress); 01299 #endif 01300 break; 01301 case DBG_CONTROL_C: 01302 OUTMSG2 (("DBG_CONTROL_C")); 01303 ourstatus->value.sig = GDB_SIGNAL_INT; 01304 break; 01305 case DBG_CONTROL_BREAK: 01306 OUTMSG2 (("DBG_CONTROL_BREAK")); 01307 ourstatus->value.sig = GDB_SIGNAL_INT; 01308 break; 01309 case EXCEPTION_SINGLE_STEP: 01310 OUTMSG2 (("EXCEPTION_SINGLE_STEP")); 01311 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01312 break; 01313 case EXCEPTION_ILLEGAL_INSTRUCTION: 01314 OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION")); 01315 ourstatus->value.sig = GDB_SIGNAL_ILL; 01316 break; 01317 case EXCEPTION_PRIV_INSTRUCTION: 01318 OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION")); 01319 ourstatus->value.sig = GDB_SIGNAL_ILL; 01320 break; 01321 case EXCEPTION_NONCONTINUABLE_EXCEPTION: 01322 OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION")); 01323 ourstatus->value.sig = GDB_SIGNAL_ILL; 01324 break; 01325 default: 01326 if (current_event.u.Exception.dwFirstChance) 01327 { 01328 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 01329 return; 01330 } 01331 OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s", 01332 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, 01333 phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord. 01334 ExceptionAddress, sizeof (uintptr_t)))); 01335 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; 01336 break; 01337 } 01338 OUTMSG2 (("\n")); 01339 last_sig = ourstatus->value.sig; 01340 } 01341 01342 01343 static void 01344 suspend_one_thread (struct inferior_list_entry *entry) 01345 { 01346 struct thread_info *thread = (struct thread_info *) entry; 01347 win32_thread_info *th = inferior_target_data (thread); 01348 01349 if (!th->suspended) 01350 { 01351 if (SuspendThread (th->h) == (DWORD) -1) 01352 { 01353 DWORD err = GetLastError (); 01354 OUTMSG (("warning: SuspendThread failed in suspend_one_thread, " 01355 "(error %d): %s\n", (int) err, strwinerror (err))); 01356 } 01357 else 01358 th->suspended = 1; 01359 } 01360 } 01361 01362 static void 01363 fake_breakpoint_event (void) 01364 { 01365 OUTMSG2(("fake_breakpoint_event\n")); 01366 01367 faked_breakpoint = 1; 01368 01369 memset (¤t_event, 0, sizeof (current_event)); 01370 current_event.dwThreadId = main_thread_id; 01371 current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT; 01372 current_event.u.Exception.ExceptionRecord.ExceptionCode 01373 = EXCEPTION_BREAKPOINT; 01374 01375 for_each_inferior (&all_threads, suspend_one_thread); 01376 } 01377 01378 #ifdef _WIN32_WCE 01379 static int 01380 auto_delete_breakpoint (CORE_ADDR stop_pc) 01381 { 01382 return 1; 01383 } 01384 #endif 01385 01386 /* Get the next event from the child. */ 01387 01388 static int 01389 get_child_debug_event (struct target_waitstatus *ourstatus) 01390 { 01391 ptid_t ptid; 01392 01393 last_sig = GDB_SIGNAL_0; 01394 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 01395 01396 /* Check if GDB sent us an interrupt request. */ 01397 check_remote_input_interrupt_request (); 01398 01399 if (soft_interrupt_requested) 01400 { 01401 soft_interrupt_requested = 0; 01402 fake_breakpoint_event (); 01403 goto gotevent; 01404 } 01405 01406 #ifndef _WIN32_WCE 01407 attaching = 0; 01408 #else 01409 if (attaching) 01410 { 01411 /* WinCE doesn't set an initial breakpoint automatically. To 01412 stop the inferior, we flush all currently pending debug 01413 events -- the thread list and the dll list are always 01414 reported immediatelly without delay, then, we suspend all 01415 threads and pretend we saw a trap at the current PC of the 01416 main thread. 01417 01418 Contrary to desktop Windows, Windows CE *does* report the dll 01419 names on LOAD_DLL_DEBUG_EVENTs resulting from a 01420 DebugActiveProcess call. This limits the way we can detect 01421 if all the dlls have already been reported. If we get a real 01422 debug event before leaving attaching, the worst that will 01423 happen is the user will see a spurious breakpoint. */ 01424 01425 current_event.dwDebugEventCode = 0; 01426 if (!WaitForDebugEvent (¤t_event, 0)) 01427 { 01428 OUTMSG2(("no attach events left\n")); 01429 fake_breakpoint_event (); 01430 attaching = 0; 01431 } 01432 else 01433 OUTMSG2(("got attach event\n")); 01434 } 01435 else 01436 #endif 01437 { 01438 /* Keep the wait time low enough for confortable remote 01439 interruption, but high enough so gdbserver doesn't become a 01440 bottleneck. */ 01441 if (!WaitForDebugEvent (¤t_event, 250)) 01442 { 01443 DWORD e = GetLastError(); 01444 01445 if (e == ERROR_PIPE_NOT_CONNECTED) 01446 { 01447 /* This will happen if the loader fails to succesfully 01448 load the application, e.g., if the main executable 01449 tries to pull in a non-existing export from a 01450 DLL. */ 01451 ourstatus->kind = TARGET_WAITKIND_EXITED; 01452 ourstatus->value.integer = 1; 01453 return 1; 01454 } 01455 01456 return 0; 01457 } 01458 } 01459 01460 gotevent: 01461 01462 switch (current_event.dwDebugEventCode) 01463 { 01464 case CREATE_THREAD_DEBUG_EVENT: 01465 OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT " 01466 "for pid=%u tid=%x)\n", 01467 (unsigned) current_event.dwProcessId, 01468 (unsigned) current_event.dwThreadId)); 01469 01470 /* Record the existence of this thread. */ 01471 child_add_thread (current_event.dwProcessId, 01472 current_event.dwThreadId, 01473 current_event.u.CreateThread.hThread, 01474 current_event.u.CreateThread.lpThreadLocalBase); 01475 break; 01476 01477 case EXIT_THREAD_DEBUG_EVENT: 01478 OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT " 01479 "for pid=%u tid=%x\n", 01480 (unsigned) current_event.dwProcessId, 01481 (unsigned) current_event.dwThreadId)); 01482 child_delete_thread (current_event.dwProcessId, 01483 current_event.dwThreadId); 01484 01485 current_inferior = (struct thread_info *) all_threads.head; 01486 return 1; 01487 01488 case CREATE_PROCESS_DEBUG_EVENT: 01489 OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT " 01490 "for pid=%u tid=%x\n", 01491 (unsigned) current_event.dwProcessId, 01492 (unsigned) current_event.dwThreadId)); 01493 CloseHandle (current_event.u.CreateProcessInfo.hFile); 01494 01495 current_process_handle = current_event.u.CreateProcessInfo.hProcess; 01496 main_thread_id = current_event.dwThreadId; 01497 01498 ourstatus->kind = TARGET_WAITKIND_EXECD; 01499 ourstatus->value.execd_pathname = "Main executable"; 01500 01501 /* Add the main thread. */ 01502 child_add_thread (current_event.dwProcessId, 01503 main_thread_id, 01504 current_event.u.CreateProcessInfo.hThread, 01505 current_event.u.CreateProcessInfo.lpThreadLocalBase); 01506 01507 ourstatus->value.related_pid = debug_event_ptid (¤t_event); 01508 #ifdef _WIN32_WCE 01509 if (!attaching) 01510 { 01511 /* Windows CE doesn't set the initial breakpoint 01512 automatically like the desktop versions of Windows do. 01513 We add it explicitly here. It will be removed as soon as 01514 it is hit. */ 01515 set_breakpoint_at ((CORE_ADDR) (long) current_event.u 01516 .CreateProcessInfo.lpStartAddress, 01517 auto_delete_breakpoint); 01518 } 01519 #endif 01520 break; 01521 01522 case EXIT_PROCESS_DEBUG_EVENT: 01523 OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT " 01524 "for pid=%u tid=%x\n", 01525 (unsigned) current_event.dwProcessId, 01526 (unsigned) current_event.dwThreadId)); 01527 ourstatus->kind = TARGET_WAITKIND_EXITED; 01528 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; 01529 child_continue (DBG_CONTINUE, -1); 01530 CloseHandle (current_process_handle); 01531 current_process_handle = NULL; 01532 break; 01533 01534 case LOAD_DLL_DEBUG_EVENT: 01535 OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT " 01536 "for pid=%u tid=%x\n", 01537 (unsigned) current_event.dwProcessId, 01538 (unsigned) current_event.dwThreadId)); 01539 CloseHandle (current_event.u.LoadDll.hFile); 01540 handle_load_dll (); 01541 01542 ourstatus->kind = TARGET_WAITKIND_LOADED; 01543 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01544 break; 01545 01546 case UNLOAD_DLL_DEBUG_EVENT: 01547 OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT " 01548 "for pid=%u tid=%x\n", 01549 (unsigned) current_event.dwProcessId, 01550 (unsigned) current_event.dwThreadId)); 01551 handle_unload_dll (); 01552 ourstatus->kind = TARGET_WAITKIND_LOADED; 01553 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01554 break; 01555 01556 case EXCEPTION_DEBUG_EVENT: 01557 OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT " 01558 "for pid=%u tid=%x\n", 01559 (unsigned) current_event.dwProcessId, 01560 (unsigned) current_event.dwThreadId)); 01561 handle_exception (ourstatus); 01562 break; 01563 01564 case OUTPUT_DEBUG_STRING_EVENT: 01565 /* A message from the kernel (or Cygwin). */ 01566 OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT " 01567 "for pid=%u tid=%x\n", 01568 (unsigned) current_event.dwProcessId, 01569 (unsigned) current_event.dwThreadId)); 01570 handle_output_debug_string (ourstatus); 01571 break; 01572 01573 default: 01574 OUTMSG2 (("gdbserver: kernel event unknown " 01575 "for pid=%u tid=%x code=%x\n", 01576 (unsigned) current_event.dwProcessId, 01577 (unsigned) current_event.dwThreadId, 01578 (unsigned) current_event.dwDebugEventCode)); 01579 break; 01580 } 01581 01582 ptid = debug_event_ptid (¤t_event); 01583 current_inferior = 01584 (struct thread_info *) find_inferior_id (&all_threads, ptid); 01585 return 1; 01586 } 01587 01588 /* Wait for the inferior process to change state. 01589 STATUS will be filled in with a response code to send to GDB. 01590 Returns the signal which caused the process to stop. */ 01591 static ptid_t 01592 win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) 01593 { 01594 struct regcache *regcache; 01595 01596 while (1) 01597 { 01598 if (!get_child_debug_event (ourstatus)) 01599 continue; 01600 01601 switch (ourstatus->kind) 01602 { 01603 case TARGET_WAITKIND_EXITED: 01604 OUTMSG2 (("Child exited with retcode = %x\n", 01605 ourstatus->value.integer)); 01606 win32_clear_inferiors (); 01607 return pid_to_ptid (current_event.dwProcessId); 01608 case TARGET_WAITKIND_STOPPED: 01609 case TARGET_WAITKIND_LOADED: 01610 OUTMSG2 (("Child Stopped with signal = %d \n", 01611 ourstatus->value.sig)); 01612 01613 regcache = get_thread_regcache (current_inferior, 1); 01614 child_fetch_inferior_registers (regcache, -1); 01615 01616 if (ourstatus->kind == TARGET_WAITKIND_LOADED 01617 && !server_waiting) 01618 { 01619 /* When gdb connects, we want to be stopped at the 01620 initial breakpoint, not in some dll load event. */ 01621 child_continue (DBG_CONTINUE, -1); 01622 break; 01623 } 01624 01625 /* We don't expose _LOADED events to gdbserver core. See 01626 the `dlls_changed' global. */ 01627 if (ourstatus->kind == TARGET_WAITKIND_LOADED) 01628 ourstatus->kind = TARGET_WAITKIND_STOPPED; 01629 01630 return debug_event_ptid (¤t_event); 01631 default: 01632 OUTMSG (("Ignoring unknown internal event, %d\n", ourstatus->kind)); 01633 /* fall-through */ 01634 case TARGET_WAITKIND_SPURIOUS: 01635 case TARGET_WAITKIND_EXECD: 01636 /* do nothing, just continue */ 01637 child_continue (DBG_CONTINUE, -1); 01638 break; 01639 } 01640 } 01641 } 01642 01643 /* Fetch registers from the inferior process. 01644 If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ 01645 static void 01646 win32_fetch_inferior_registers (struct regcache *regcache, int regno) 01647 { 01648 child_fetch_inferior_registers (regcache, regno); 01649 } 01650 01651 /* Store registers to the inferior process. 01652 If REGNO is -1, store all registers; otherwise, store at least REGNO. */ 01653 static void 01654 win32_store_inferior_registers (struct regcache *regcache, int regno) 01655 { 01656 child_store_inferior_registers (regcache, regno); 01657 } 01658 01659 /* Read memory from the inferior process. This should generally be 01660 called through read_inferior_memory, which handles breakpoint shadowing. 01661 Read LEN bytes at MEMADDR into a buffer at MYADDR. */ 01662 static int 01663 win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) 01664 { 01665 return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len; 01666 } 01667 01668 /* Write memory to the inferior process. This should generally be 01669 called through write_inferior_memory, which handles breakpoint shadowing. 01670 Write LEN bytes from the buffer at MYADDR to MEMADDR. 01671 Returns 0 on success and errno on failure. */ 01672 static int 01673 win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, 01674 int len) 01675 { 01676 return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len; 01677 } 01678 01679 /* Send an interrupt request to the inferior process. */ 01680 static void 01681 win32_request_interrupt (void) 01682 { 01683 winapi_DebugBreakProcess DebugBreakProcess; 01684 winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent; 01685 01686 #ifdef _WIN32_WCE 01687 HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); 01688 #else 01689 HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); 01690 #endif 01691 01692 GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent); 01693 01694 if (GenerateConsoleCtrlEvent != NULL 01695 && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id)) 01696 return; 01697 01698 /* GenerateConsoleCtrlEvent can fail if process id being debugged is 01699 not a process group id. 01700 Fallback to XP/Vista 'DebugBreakProcess', which generates a 01701 breakpoint exception in the interior process. */ 01702 01703 DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess); 01704 01705 if (DebugBreakProcess != NULL 01706 && DebugBreakProcess (current_process_handle)) 01707 return; 01708 01709 /* Last resort, suspend all threads manually. */ 01710 soft_interrupt_requested = 1; 01711 } 01712 01713 #ifdef _WIN32_WCE 01714 int 01715 win32_error_to_fileio_error (DWORD err) 01716 { 01717 switch (err) 01718 { 01719 case ERROR_BAD_PATHNAME: 01720 case ERROR_FILE_NOT_FOUND: 01721 case ERROR_INVALID_NAME: 01722 case ERROR_PATH_NOT_FOUND: 01723 return FILEIO_ENOENT; 01724 case ERROR_CRC: 01725 case ERROR_IO_DEVICE: 01726 case ERROR_OPEN_FAILED: 01727 return FILEIO_EIO; 01728 case ERROR_INVALID_HANDLE: 01729 return FILEIO_EBADF; 01730 case ERROR_ACCESS_DENIED: 01731 case ERROR_SHARING_VIOLATION: 01732 return FILEIO_EACCES; 01733 case ERROR_NOACCESS: 01734 return FILEIO_EFAULT; 01735 case ERROR_BUSY: 01736 return FILEIO_EBUSY; 01737 case ERROR_ALREADY_EXISTS: 01738 case ERROR_FILE_EXISTS: 01739 return FILEIO_EEXIST; 01740 case ERROR_BAD_DEVICE: 01741 return FILEIO_ENODEV; 01742 case ERROR_DIRECTORY: 01743 return FILEIO_ENOTDIR; 01744 case ERROR_FILENAME_EXCED_RANGE: 01745 case ERROR_INVALID_DATA: 01746 case ERROR_INVALID_PARAMETER: 01747 case ERROR_NEGATIVE_SEEK: 01748 return FILEIO_EINVAL; 01749 case ERROR_TOO_MANY_OPEN_FILES: 01750 return FILEIO_EMFILE; 01751 case ERROR_HANDLE_DISK_FULL: 01752 case ERROR_DISK_FULL: 01753 return FILEIO_ENOSPC; 01754 case ERROR_WRITE_PROTECT: 01755 return FILEIO_EROFS; 01756 case ERROR_NOT_SUPPORTED: 01757 return FILEIO_ENOSYS; 01758 } 01759 01760 return FILEIO_EUNKNOWN; 01761 } 01762 01763 static void 01764 wince_hostio_last_error (char *buf) 01765 { 01766 DWORD winerr = GetLastError (); 01767 int fileio_err = win32_error_to_fileio_error (winerr); 01768 sprintf (buf, "F-1,%x", fileio_err); 01769 } 01770 #endif 01771 01772 /* Write Windows OS Thread Information Block address. */ 01773 01774 static int 01775 win32_get_tib_address (ptid_t ptid, CORE_ADDR *addr) 01776 { 01777 win32_thread_info *th; 01778 th = thread_rec (ptid, 0); 01779 if (th == NULL) 01780 return 0; 01781 if (addr != NULL) 01782 *addr = th->thread_local_base; 01783 return 1; 01784 } 01785 01786 static struct target_ops win32_target_ops = { 01787 win32_create_inferior, 01788 win32_attach, 01789 win32_kill, 01790 win32_detach, 01791 win32_mourn, 01792 win32_join, 01793 win32_thread_alive, 01794 win32_resume, 01795 win32_wait, 01796 win32_fetch_inferior_registers, 01797 win32_store_inferior_registers, 01798 NULL, /* prepare_to_access_memory */ 01799 NULL, /* done_accessing_memory */ 01800 win32_read_inferior_memory, 01801 win32_write_inferior_memory, 01802 NULL, /* lookup_symbols */ 01803 win32_request_interrupt, 01804 NULL, /* read_auxv */ 01805 win32_insert_point, 01806 win32_remove_point, 01807 win32_stopped_by_watchpoint, 01808 win32_stopped_data_address, 01809 NULL, /* read_offsets */ 01810 NULL, /* get_tls_address */ 01811 NULL, /* qxfer_spu */ 01812 #ifdef _WIN32_WCE 01813 wince_hostio_last_error, 01814 #else 01815 hostio_last_error_from_errno, 01816 #endif 01817 NULL, /* qxfer_osdata */ 01818 NULL, /* qxfer_siginfo */ 01819 NULL, /* supports_non_stop */ 01820 NULL, /* async */ 01821 NULL, /* start_non_stop */ 01822 NULL, /* supports_multi_process */ 01823 NULL, /* handle_monitor_command */ 01824 NULL, /* core_of_thread */ 01825 NULL, /* read_loadmap */ 01826 NULL, /* process_qsupported */ 01827 NULL, /* supports_tracepoints */ 01828 NULL, /* read_pc */ 01829 NULL, /* write_pc */ 01830 NULL, /* thread_stopped */ 01831 win32_get_tib_address 01832 }; 01833 01834 /* Initialize the Win32 backend. */ 01835 void 01836 initialize_low (void) 01837 { 01838 set_target_ops (&win32_target_ops); 01839 if (the_low_target.breakpoint != NULL) 01840 set_breakpoint_data (the_low_target.breakpoint, 01841 the_low_target.breakpoint_len); 01842 the_low_target.arch_setup (); 01843 }