X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fwin32-nat.c;h=9a1a28cfd56ecaf309ccfe1a0df8dd65de4db6cf;hb=cd4a7468c909dc8135cdf6198d596869defcdabe;hp=2c6d9550bf71b4c094e480f4d69cedbc4ddbf4c1;hpb=7488902c738b0d8352fa414ee89e1b5537e13c87;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c index 2c6d9550bf..9a1a28cfd5 100644 --- a/gdb/win32-nat.c +++ b/gdb/win32-nat.c @@ -1,7 +1,7 @@ /* Target-vector operations for controlling win32 child processes, for GDB. Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Cygnus Solutions, A Red Hat Company. @@ -48,7 +48,6 @@ #include "objfiles.h" #include "gdb_obstack.h" #include "gdb_string.h" -#include "gdb_stdint.h" #include "gdbthread.h" #include "gdbcmd.h" #include @@ -61,7 +60,8 @@ #include "i386-tdep.h" #include "i387-tdep.h" -#include "i386-cygwin-tdep.h" +#include "win32-tdep.h" +#include "win32-nat.h" static struct target_ops win32_ops; @@ -86,6 +86,12 @@ enum #endif #include +#ifndef CONTEXT_EXTENDED_REGISTERS +/* This macro is only defined on ia32. It only makes sense on this target, + so define it as zero if not already defined. */ +#define CONTEXT_EXTENDED_REGISTERS 0 +#endif + #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \ | CONTEXT_EXTENDED_REGISTERS @@ -106,7 +112,7 @@ static int debug_registers_used; #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x -static void win32_stop (void); +static void win32_stop (ptid_t); static int win32_win32_thread_alive (ptid_t); static void win32_kill_inferior (void); @@ -156,11 +162,16 @@ static int debug_memory = 0; /* show target memory accesses */ static int debug_exceptions = 0; /* show target exceptions */ static int useshell = 0; /* use shell for subprocesses */ -/* This vector maps GDB's idea of a register's number into an address +/* This vector maps GDB's idea of a register's number into an offset in the win32 exception context vector. It also contains the bit mask needed to load the register in question. + The contents of this table can only be computed by the units + that provide CPU-specific support for Windows native debugging. + These units should set the table by calling + win32_set_context_register_offsets. + One day we could read a reg, we could inspect the context we already have loaded, if it doesn't have the bit set that we need, we read that set of registers in using GetThreadContext. If the @@ -169,55 +180,7 @@ static int useshell = 0; /* use shell for subprocesses */ the other regs of the group, and then we copy the info in and set out bit. */ -#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) -static const int mappings[] = -{ - context_offset (Eax), - context_offset (Ecx), - context_offset (Edx), - context_offset (Ebx), - context_offset (Esp), - context_offset (Ebp), - context_offset (Esi), - context_offset (Edi), - context_offset (Eip), - context_offset (EFlags), - context_offset (SegCs), - context_offset (SegSs), - context_offset (SegDs), - context_offset (SegEs), - context_offset (SegFs), - context_offset (SegGs), - context_offset (FloatSave.RegisterArea[0 * 10]), - context_offset (FloatSave.RegisterArea[1 * 10]), - context_offset (FloatSave.RegisterArea[2 * 10]), - context_offset (FloatSave.RegisterArea[3 * 10]), - context_offset (FloatSave.RegisterArea[4 * 10]), - context_offset (FloatSave.RegisterArea[5 * 10]), - context_offset (FloatSave.RegisterArea[6 * 10]), - context_offset (FloatSave.RegisterArea[7 * 10]), - context_offset (FloatSave.ControlWord), - context_offset (FloatSave.StatusWord), - context_offset (FloatSave.TagWord), - context_offset (FloatSave.ErrorSelector), - context_offset (FloatSave.ErrorOffset), - context_offset (FloatSave.DataSelector), - context_offset (FloatSave.DataOffset), - context_offset (FloatSave.ErrorSelector) - /* XMM0-7 */ , - context_offset (ExtendedRegisters[10*16]), - context_offset (ExtendedRegisters[11*16]), - context_offset (ExtendedRegisters[12*16]), - context_offset (ExtendedRegisters[13*16]), - context_offset (ExtendedRegisters[14*16]), - context_offset (ExtendedRegisters[15*16]), - context_offset (ExtendedRegisters[16*16]), - context_offset (ExtendedRegisters[17*16]), - /* MXCSR */ - context_offset (ExtendedRegisters[24]) -}; - -#undef context_offset +static const int *mappings; /* This vector maps the target's idea of an exception (extracted from the DEBUG_EVENT structure) to GDB's idea. */ @@ -239,6 +202,15 @@ static const struct xlate_exception {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE}, {-1, -1}}; +/* Set the MAPPINGS static global to OFFSETS. + See the description of MAPPINGS for more details. */ + +void +win32_set_context_register_offsets (const int *offsets) +{ + mappings = offsets; +} + static void check (BOOL ok, const char *file, int line) { @@ -281,11 +253,16 @@ thread_rec (DWORD id, int get_context) return NULL; } -/* Add a thread to the thread list */ +/* Add a thread to the thread list. */ static thread_info * -win32_add_thread (DWORD id, HANDLE h) +win32_add_thread (ptid_t ptid, HANDLE h) { thread_info *th; + DWORD id; + + gdb_assert (ptid_get_tid (ptid) != 0); + + id = ptid_get_tid (ptid); if ((th = thread_rec (id, FALSE))) return th; @@ -295,8 +272,8 @@ win32_add_thread (DWORD id, HANDLE h) th->h = h; th->next = thread_head.next; thread_head.next = th; - add_thread (pid_to_ptid (id)); - /* Set the debug registers for the new thread in they are used. */ + add_thread (ptid); + /* Set the debug registers for the new thread if they are used. */ if (debug_registers_used) { /* Only change the value of the debug registers. */ @@ -334,13 +311,18 @@ win32_init_thread_list (void) /* Delete a thread from the list of threads */ static void -win32_delete_thread (DWORD id) +win32_delete_thread (ptid_t ptid) { thread_info *th; + DWORD id; + + gdb_assert (ptid_get_tid (ptid) != 0); + + id = ptid_get_tid (ptid); if (info_verbose) - printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id))); - delete_thread (pid_to_ptid (id)); + printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid)); + delete_thread (ptid); for (th = &thread_head; th->next != NULL && th->next->id != id; @@ -421,7 +403,7 @@ do_win32_fetch_inferior_registers (struct regcache *regcache, int r) static void win32_fetch_inferior_registers (struct regcache *regcache, int r) { - current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE); /* Check if current_thread exists. Windows sometimes uses a non-existent thread id in its events */ if (current_thread) @@ -447,7 +429,7 @@ do_win32_store_inferior_registers (const struct regcache *regcache, int r) static void win32_store_inferior_registers (struct regcache *regcache, int r) { - current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); + current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE); /* Check if current_thread exists. Windows sometimes uses a non-existent thread id in its events */ if (current_thread) @@ -466,7 +448,7 @@ static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, is zero return the first loaded module (which is always the name of the executable). */ static int -get_module_name (DWORD base_address, char *dll_name_ret) +get_module_name (LPVOID base_address, char *dll_name_ret) { DWORD len; MODULEINFO mi; @@ -509,7 +491,7 @@ get_module_name (DWORD base_address, char *dll_name_ret) &mi, sizeof (mi))) error (_("Can't get module info")); - if (!base_address || (DWORD) (mi.lpBaseOfDll) == base_address) + if (!base_address || mi.lpBaseOfDll == base_address) { /* Try to find the name of the given module */ len = psapi_GetModuleFileNameExA (current_process_handle, @@ -545,7 +527,7 @@ struct safe_symbol_file_add_args /* Maintain a linked list of "so" information. */ struct lm_info { - DWORD load_addr; + LPVOID load_addr; }; static struct so_list solib_start, *solib_end; @@ -556,8 +538,6 @@ static int safe_symbol_file_add_stub (void *argv) { #define p ((struct safe_symbol_file_add_args *) argv) - struct so_list *so = &solib_start; - p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags); return !!p->ret; #undef p @@ -606,7 +586,7 @@ safe_symbol_file_add (char *name, int from_tty, } static struct so_list * -win32_make_so (const char *name, DWORD load_addr) +win32_make_so (const char *name, LPVOID load_addr) { struct so_list *so; char buf[MAX_PATH + 1]; @@ -689,7 +669,7 @@ get_image_name (HANDLE h, void *address, int unicode) char *address_ptr; int len = 0; char b[2]; - DWORD done; + SIZE_T done; /* Attempt to read the name of the dll that was detected. This is documented to work only when actively debugging @@ -733,7 +713,7 @@ handle_load_dll (void *dummy) dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; - if (!get_module_name ((DWORD) event->lpBaseOfDll, dll_buf)) + if (!get_module_name (event->lpBaseOfDll, dll_buf)) dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; dll_name = dll_buf; @@ -744,11 +724,11 @@ handle_load_dll (void *dummy) if (!dll_name) return 1; - solib_end->next = win32_make_so (dll_name, (DWORD) event->lpBaseOfDll); + solib_end->next = win32_make_so (dll_name, event->lpBaseOfDll); solib_end = solib_end->next; DEBUG_EVENTS (("gdb: Loading dll \"%s\" at 0x%lx.\n", solib_end->so_name, - (DWORD) solib_end->lm_info->load_addr)); + solib_end->lm_info->load_addr)); return 1; } @@ -764,7 +744,7 @@ win32_free_so (struct so_list *so) static int handle_unload_dll (void *dummy) { - DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll; + LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll; struct so_list *so; for (so = &solib_start; so->next != NULL; so = so->next) @@ -994,7 +974,7 @@ info_w32_command (char *args, int from_tty) #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \ printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \ - (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress) + current_event.u.Exception.ExceptionRecord.ExceptionAddress) static int handle_exception (struct target_waitstatus *ourstatus) @@ -1108,7 +1088,7 @@ handle_exception (struct target_waitstatus *ourstatus) return -1; printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n", current_event.u.Exception.ExceptionRecord.ExceptionCode, - (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress); + current_event.u.Exception.ExceptionRecord.ExceptionAddress); ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; break; } @@ -1179,7 +1159,8 @@ fake_create_process (void) /* We can not debug anything in that case. */ } main_thread_id = current_event.dwThreadId; - current_thread = win32_add_thread (main_thread_id, + current_thread = win32_add_thread (ptid_build (current_event.dwProcessId, 0, + current_event.dwThreadId), current_event.u.CreateThread.hThread); return main_thread_id; } @@ -1190,7 +1171,13 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig) thread_info *th; DWORD continue_status = DBG_CONTINUE; - int pid = PIDGET (ptid); + /* A specific PTID means `step only this thread id'. */ + int resume_all = ptid_equal (ptid, minus_one_ptid); + + /* If we're continuing all threads, it's the current inferior that + should be handled specially. */ + if (resume_all) + ptid = inferior_ptid; if (sig != TARGET_SIGNAL_0) { @@ -1228,11 +1215,11 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig) last_sig = TARGET_SIGNAL_0; - DEBUG_EXEC (("gdb: win32_resume (pid=%d, step=%d, sig=%d);\n", - pid, step, sig)); + DEBUG_EXEC (("gdb: win32_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n", + ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig)); /* Get context for currently selected thread */ - th = thread_rec (PIDGET (inferior_ptid), FALSE); + th = thread_rec (ptid_get_tid (inferior_ptid), FALSE); if (th) { if (step) @@ -1262,7 +1249,10 @@ win32_resume (ptid_t ptid, int step, enum target_signal sig) /* Allow continuing with the same signal that interrupted us. Otherwise complain. */ - win32_continue (continue_status, pid); + if (resume_all) + win32_continue (continue_status, -1); + else + win32_continue (continue_status, ptid_get_tid (ptid)); } /* Get the next event from the child. Return 1 if the event requires @@ -1276,7 +1266,6 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) thread_info *th; static thread_info dummy_thread_info; int retval = 0; - ptid_t ptid = {-1}; last_sig = TARGET_SIGNAL_0; @@ -1300,21 +1289,24 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) "CREATE_THREAD_DEBUG_EVENT")); if (saw_create != 1) { - if (!saw_create && attach_flag) + struct inferior *inf; + inf = find_inferior_pid (current_event.dwProcessId); + if (!saw_create && inf->attach_flag) { /* Kludge around a Windows bug where first event is a create thread event. Caused when attached process does not have a main thread. */ - retval = ourstatus->value.related_pid = fake_create_process (); - if (retval) - saw_create++; + retval = fake_create_process (); + if (retval) + saw_create++; } break; } /* Record the existence of this thread */ - th = win32_add_thread (current_event.dwThreadId, - current_event.u.CreateThread.hThread); retval = current_event.dwThreadId; + th = win32_add_thread (ptid_build (current_event.dwProcessId, 0, + current_event.dwThreadId), + current_event.u.CreateThread.hThread); break; case EXIT_THREAD_DEBUG_EVENT: @@ -1324,7 +1316,8 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) "EXIT_THREAD_DEBUG_EVENT")); if (current_event.dwThreadId != main_thread_id) { - win32_delete_thread (current_event.dwThreadId); + win32_delete_thread (ptid_build (current_event.dwProcessId, 0, + current_event.dwThreadId)); th = &dummy_thread_info; } break; @@ -1340,12 +1333,14 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) current_process_handle = current_event.u.CreateProcessInfo.hProcess; if (main_thread_id) - win32_delete_thread (main_thread_id); + win32_delete_thread (ptid_build (current_event.dwProcessId, 0, + main_thread_id)); main_thread_id = current_event.dwThreadId; /* Add the main thread */ - th = win32_add_thread (main_thread_id, + th = win32_add_thread (ptid_build (current_event.dwProcessId, 0, + current_event.dwThreadId), current_event.u.CreateProcessInfo.hThread); - retval = ourstatus->value.related_pid = current_event.dwThreadId; + retval = current_event.dwThreadId; break; case EXIT_PROCESS_DEBUG_EVENT: @@ -1433,13 +1428,14 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) if (!retval || saw_create != 1) { if (continue_status == -1) - win32_resume (ptid, 0, 1); + win32_resume (minus_one_ptid, 0, 1); else CHECK (win32_continue (continue_status, -1)); } else { - inferior_ptid = pid_to_ptid (retval); + inferior_ptid = ptid_build (current_event.dwProcessId, 0, + retval); current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); } @@ -1447,11 +1443,11 @@ out: return retval; } -/* Wait for interesting events to occur in the target process. */ +/* Wait for interesting events to occur in the target process. */ static ptid_t win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { - int pid = PIDGET (ptid); + int pid = -1; target_terminal_ours (); @@ -1483,7 +1479,7 @@ win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus) SetConsoleCtrlHandler (NULL, FALSE); if (retval) - return pid_to_ptid (retval); + return ptid_build (current_event.dwProcessId, 0, retval); else { int detach = 0; @@ -1498,10 +1494,12 @@ win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus) } static void -do_initial_win32_stuff (DWORD pid) +do_initial_win32_stuff (struct target_ops *ops, DWORD pid, int attaching) { extern int stop_after_trap; int i; + struct inferior *inf; + struct thread_info *tp; last_sig = TARGET_SIGNAL_0; event_count = 0; @@ -1516,24 +1514,37 @@ do_initial_win32_stuff (DWORD pid) #endif current_event.dwProcessId = pid; memset (¤t_event, 0, sizeof (current_event)); - push_target (&win32_ops); + push_target (ops); disable_breakpoints_in_shlibs (); win32_clear_solib (); clear_proceed_status (); init_wait_for_inferior (); + inf = add_inferior (pid); + inf->attach_flag = attaching; + + /* Make the new process the current inferior, so terminal handling + can rely on it. When attaching, we don't know about any thread + id here, but that's OK --- nothing should be referencing the + current thread until we report an event out of win32_wait. */ + inferior_ptid = pid_to_ptid (pid); + terminal_init_inferior_with_pgrp (pid); target_terminal_inferior (); + inf->stop_soon = STOP_QUIETLY; while (1) { stop_after_trap = 1; wait_for_inferior (0); - if (stop_signal != TARGET_SIGNAL_TRAP) - resume (0, stop_signal); + tp = inferior_thread (); + if (tp->stop_signal != TARGET_SIGNAL_TRAP) + resume (0, tp->stop_signal); else break; } + + inf->stop_soon = NO_STOP_QUIETLY; stop_after_trap = 0; return; } @@ -1543,8 +1554,8 @@ do_initial_win32_stuff (DWORD pid) If loading these functions succeeds use them to actually detach from the inferior process, otherwise behave as usual, pretending that detach has worked. */ -static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL); -static BOOL WINAPI (*DebugActiveProcessStop)(DWORD); +static BOOL WINAPI (*kernel32_DebugSetProcessKillOnExit)(BOOL); +static BOOL WINAPI (*kernel32_DebugActiveProcessStop)(DWORD); static int has_detach_ability (void) @@ -1555,13 +1566,14 @@ has_detach_ability (void) kernel32 = LoadLibrary ("kernel32.dll"); if (kernel32) { - if (!DebugSetProcessKillOnExit) - DebugSetProcessKillOnExit = GetProcAddress (kernel32, - "DebugSetProcessKillOnExit"); - if (!DebugActiveProcessStop) - DebugActiveProcessStop = GetProcAddress (kernel32, - "DebugActiveProcessStop"); - if (DebugSetProcessKillOnExit && DebugActiveProcessStop) + if (!kernel32_DebugSetProcessKillOnExit) + kernel32_DebugSetProcessKillOnExit = + (void *) GetProcAddress (kernel32, "DebugSetProcessKillOnExit"); + if (!kernel32_DebugActiveProcessStop) + kernel32_DebugActiveProcessStop = + (void *) GetProcAddress (kernel32, "DebugActiveProcessStop"); + if (kernel32_DebugSetProcessKillOnExit + && kernel32_DebugActiveProcessStop) return 1; } return 0; @@ -1596,13 +1608,14 @@ set_process_privilege (const char *privilege, BOOL enable) if (!(advapi32 = LoadLibrary ("advapi32.dll"))) goto out; if (!OpenProcessToken) - OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken"); + OpenProcessToken = + (void *) GetProcAddress (advapi32, "OpenProcessToken"); if (!LookupPrivilegeValue) - LookupPrivilegeValue = GetProcAddress (advapi32, - "LookupPrivilegeValueA"); + LookupPrivilegeValue = + (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA"); if (!AdjustTokenPrivileges) - AdjustTokenPrivileges = GetProcAddress (advapi32, - "AdjustTokenPrivileges"); + AdjustTokenPrivileges = + (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges"); if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges) { advapi32 = NULL; @@ -1646,7 +1659,7 @@ out: /* Attach to process PID, then initialize for debugging it. */ static void -win32_attach (char *args, int from_tty) +win32_attach (struct target_ops *ops, char *args, int from_tty) { BOOL ok; DWORD pid; @@ -1681,9 +1694,7 @@ win32_attach (char *args, int from_tty) error (_("Can't attach to process.")); if (has_detach_ability ()) - DebugSetProcessKillOnExit (FALSE); - - attach_flag = 1; + kernel32_DebugSetProcessKillOnExit (FALSE); if (from_tty) { @@ -1699,12 +1710,12 @@ win32_attach (char *args, int from_tty) gdb_flush (gdb_stdout); } - do_initial_win32_stuff (pid); + do_initial_win32_stuff (ops, pid, 1); target_terminal_ours (); } static void -win32_detach (char *args, int from_tty) +win32_detach (struct target_ops *ops, char *args, int from_tty) { int detached = 1; @@ -1713,13 +1724,13 @@ win32_detach (char *args, int from_tty) ptid_t ptid = {-1}; win32_resume (ptid, 0, TARGET_SIGNAL_0); - if (!DebugActiveProcessStop (current_event.dwProcessId)) + if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId)) { error (_("Can't detach process %lu (error %lu)"), current_event.dwProcessId, GetLastError ()); detached = 0; } - DebugSetProcessKillOnExit (FALSE); + kernel32_DebugSetProcessKillOnExit (FALSE); } if (detached && from_tty) { @@ -1730,8 +1741,11 @@ win32_detach (char *args, int from_tty) current_event.dwProcessId); gdb_flush (gdb_stdout); } + inferior_ptid = null_ptid; - unpush_target (&win32_ops); + detach_inferior (current_event.dwProcessId); + + unpush_target (ops); } static char * @@ -1743,7 +1757,7 @@ win32_pid_to_exec_file (int pid) /* Try to find exe name as symlink target of /proc//exe */ int nchars; char procexe[sizeof ("/proc/4294967295/exe")]; - sprintf (procexe, "/proc/%lu/exe", current_event.dwProcessId); + sprintf (procexe, "/proc/%u/exe", pid); nchars = readlink (procexe, path, sizeof(path)); if (nchars > 0 && nchars < sizeof (path)) { @@ -1765,8 +1779,11 @@ win32_pid_to_exec_file (int pid) static void win32_files_info (struct target_ops *ignore) { + struct inferior *inf = current_inferior (); + printf_unfiltered ("\tUsing the running image of %s %s.\n", - attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); + inf->attach_flag ? "attached" : "child", + target_pid_to_str (inferior_ptid)); } static void @@ -1781,8 +1798,8 @@ win32_open (char *arg, int from_tty) ENV is the environment vector to pass. Errors reported with error(). */ static void -win32_create_inferior (char *exec_file, char *allargs, char **in_env, - int from_tty) +win32_create_inferior (struct target_ops *ops, char *exec_file, + char *allargs, char **in_env, int from_tty) { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -1835,8 +1852,6 @@ win32_create_inferior (char *exec_file, char *allargs, char **in_env, if (new_console) flags |= CREATE_NEW_CONSOLE; - attach_flag = 0; - args = alloca (strlen (toexec) + strlen (allargs) + 2); strcpy (args, toexec); strcat (args, " "); @@ -1905,13 +1920,13 @@ win32_create_inferior (char *exec_file, char *allargs, char **in_env, else saw_create = 0; - do_initial_win32_stuff (pi.dwProcessId); + do_initial_win32_stuff (ops, pi.dwProcessId, 0); /* win32_continue (DBG_CONTINUE, -1); */ } static void -win32_mourn_inferior (void) +win32_mourn_inferior (struct target_ops *ops) { (void) win32_continue (DBG_CONTINUE, -1); i386_cleanup_dregs(); @@ -1920,7 +1935,7 @@ win32_mourn_inferior (void) CHECK (CloseHandle (current_process_handle)); open_process_used = 0; } - unpush_target (&win32_ops); + unpush_target (ops); generic_mourn_inferior (); } @@ -1928,7 +1943,7 @@ win32_mourn_inferior (void) ^C on the controlling terminal. */ static void -win32_stop (void) +win32_stop (ptid_t ptid) { DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); @@ -1940,7 +1955,7 @@ win32_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len, int write, struct mem_attrib *mem, struct target_ops *target) { - DWORD done = 0; + SIZE_T done = 0; if (write) { DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n", @@ -2006,13 +2021,15 @@ static char * win32_pid_to_str (ptid_t ptid) { static char buf[80]; - int pid = PIDGET (ptid); - if ((DWORD) pid == current_event.dwProcessId) - sprintf (buf, "process %d", pid); - else - sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid); - return buf; + if (ptid_get_tid (ptid) != 0) + { + snprintf (buf, sizeof (buf), "Thread %d.0x%lx", + ptid_get_pid (ptid), ptid_get_tid (ptid)); + return buf; + } + + return normal_pid_to_str (ptid); } static LONGEST @@ -2032,7 +2049,8 @@ win32_xfer_shared_libraries (struct target_ops *ops, obstack_init (&obstack); obstack_grow_str (&obstack, "\n"); for (so = solib_start.next; so; so = so->next) - win32_xfer_shared_library (so->so_name, so->lm_info->load_addr, &obstack); + win32_xfer_shared_library (so->so_name, (CORE_ADDR) so->lm_info->load_addr, + &obstack); obstack_grow_str0 (&obstack, "\n"); buf = obstack_finish (&obstack); @@ -2085,6 +2103,7 @@ init_win32_ops (void) win32_ops.to_open = win32_open; win32_ops.to_close = win32_close; win32_ops.to_attach = win32_attach; + win32_ops.to_attach_no_wait = 1; win32_ops.to_detach = win32_detach; win32_ops.to_resume = win32_resume; win32_ops.to_wait = win32_wait; @@ -2115,8 +2134,8 @@ init_win32_ops (void) win32_ops.to_has_stack = 1; win32_ops.to_has_registers = 1; win32_ops.to_has_execution = 1; - win32_ops.to_magic = OPS_MAGIC; win32_ops.to_pid_to_exec_file = win32_pid_to_exec_file; + win32_ops.to_magic = OPS_MAGIC; } static void @@ -2244,15 +2263,18 @@ cygwin_get_dr6 (void) return dr[6]; } -/* Determine if the thread referenced by "pid" is alive +/* Determine if the thread referenced by "ptid" is alive by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 - it means that the pid has died. Otherwise it is assumed to be alive. */ + it means that the thread has died. Otherwise it is assumed to be alive. */ static int win32_win32_thread_alive (ptid_t ptid) { - int pid = PIDGET (ptid); + int tid; + + gdb_assert (ptid_get_tid (ptid) != 0); + tid = ptid_get_tid (ptid); - return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ? + return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0 ? FALSE : TRUE; }