X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fwindows-nat.c;h=36a47f7cdbc28be0e4791a9e40795580a572166f;hb=3318ac0e53a673f9989f5e9bbaa9d1c5d536f4e5;hp=63a780014abdfb922c7fa0a70d4feb32dd494488;hpb=2f4f025ff15b900706c8597060003a506107cf23;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 63a780014a..36a47f7cdb 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1,6 +1,6 @@ /* Target-vector operations for controlling windows child processes, for GDB. - Copyright (C) 1995-2018 Free Software Foundation, Inc. + Copyright (C) 1995-2020 Free Software Foundation, Inc. Contributed by Cygnus Solutions, A Red Hat Company. @@ -44,7 +44,6 @@ #endif #include -#include "buildsym.h" #include "filenames.h" #include "symfile.h" #include "objfiles.h" @@ -67,7 +66,9 @@ #include "x86-nat.h" #include "complaints.h" #include "inf-child.h" -#include "gdb_tilde_expand.h" +#include "gdbsupport/gdb_tilde_expand.h" +#include "gdbsupport/pathstuff.h" +#include "gdbsupport/gdb_wait.h" #define AdjustTokenPrivileges dyn_AdjustTokenPrivileges #define DebugActiveProcessStop dyn_DebugActiveProcessStop @@ -146,8 +147,10 @@ static GetConsoleFontSize_ftype *GetConsoleFontSize; static int have_saved_context; /* True if we've saved context from a cygwin signal. */ -static CONTEXT saved_context; /* Containes the saved context from a +#ifdef __CYGWIN__ +static CONTEXT saved_context; /* Contains the saved context from a cygwin signal. */ +#endif /* If we're not using the old Cygwin header file set, define the following which never should have been in the generic Win32 API @@ -222,7 +225,6 @@ typedef struct windows_thread_info_struct int suspended; int reload_context; CONTEXT context; - STACKFRAME sf; } windows_thread_info; @@ -234,7 +236,6 @@ static DEBUG_EVENT current_event; /* The current debug event from WaitForDebugEvent */ static HANDLE current_process_handle; /* Currently executing process */ static windows_thread_info *current_thread; /* Info on currently selected thread */ -static DWORD main_thread_id; /* Thread ID of the main thread */ /* Counts of things. */ static int exception_count = 0; @@ -243,16 +244,16 @@ static int saw_create; static int open_process_used = 0; /* User options. */ -static int new_console = 0; +static bool new_console = false; #ifdef __CYGWIN__ -static int cygwin_exceptions = 0; +static bool cygwin_exceptions = false; #endif -static int new_group = 1; -static int debug_exec = 0; /* show execution */ -static int debug_events = 0; /* show events from kernel */ -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 */ +static bool new_group = true; +static bool debug_exec = false; /* show execution */ +static bool debug_events = false; /* show events from kernel */ +static bool debug_memory = false; /* show target memory accesses */ +static bool debug_exceptions = false; /* show target exceptions */ +static bool useshell = false; /* use shell for subprocesses */ /* This vector maps GDB's idea of a register's number into an offset in the windows exception context vector. @@ -278,26 +279,29 @@ static const int *mappings; a segment register or not. */ static segment_register_p_ftype *segment_register_p; +/* See windows_nat_target::resume to understand why this is commented + out. */ +#if 0 /* This vector maps the target's idea of an exception (extracted from the DEBUG_EVENT structure) to GDB's idea. */ struct xlate_exception { - int them; + DWORD them; enum gdb_signal us; }; -static const struct xlate_exception - xlate[] = +static const struct xlate_exception xlate[] = { {EXCEPTION_ACCESS_VIOLATION, GDB_SIGNAL_SEGV}, {STATUS_STACK_OVERFLOW, GDB_SIGNAL_SEGV}, {EXCEPTION_BREAKPOINT, GDB_SIGNAL_TRAP}, {DBG_CONTROL_C, GDB_SIGNAL_INT}, {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP}, - {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE}, - {-1, GDB_SIGNAL_UNKNOWN}}; + {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE} +}; +#endif /* 0 */ struct windows_nat_target final : public x86_nat_target { @@ -335,7 +339,7 @@ struct windows_nat_target final : public x86_nat_target bool thread_alive (ptid_t ptid) override; - const char *pid_to_str (ptid_t) override; + std::string pid_to_str (ptid_t) override; void interrupt () override; @@ -420,16 +424,23 @@ thread_rec (DWORD id, int get_context) return NULL; } -/* Add a thread to the thread list. */ +/* Add a thread to the thread list. + + PTID is the ptid of the thread to be added. + H is its Windows handle. + TLB is its thread local base. + MAIN_THREAD_P should be true if the thread to be added is + the main thread, false otherwise. */ + static windows_thread_info * -windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) +windows_add_thread (ptid_t ptid, HANDLE h, void *tlb, bool main_thread_p) { windows_thread_info *th; DWORD id; - gdb_assert (ptid_get_tid (ptid) != 0); + gdb_assert (ptid.tid () != 0); - id = ptid_get_tid (ptid); + id = ptid.tid (); if ((th = thread_rec (id, FALSE))) return th; @@ -440,7 +451,17 @@ windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb; th->next = thread_head.next; thread_head.next = th; - add_thread (ptid); + + /* Add this new thread to the list of threads. + + To be consistent with what's done on other platforms, we add + the main thread silently (in reality, this thread is really + more of a process to the user than a thread). */ + if (main_thread_p) + add_thread_silent (ptid); + else + add_thread (ptid); + /* Set the debug registers for the new thread if they are used. */ if (debug_registers_used) { @@ -477,23 +498,38 @@ windows_init_thread_list (void) thread_head.next = NULL; } -/* Delete a thread from the list of threads. */ +/* Delete a thread from the list of threads. + + PTID is the ptid of the thread to be deleted. + EXIT_CODE is the thread's exit code. + MAIN_THREAD_P should be true if the thread to be deleted is + the main thread, false otherwise. */ + static void -windows_delete_thread (ptid_t ptid, DWORD exit_code) +windows_delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p) { windows_thread_info *th; DWORD id; - gdb_assert (ptid_get_tid (ptid) != 0); + gdb_assert (ptid.tid () != 0); + + id = ptid.tid (); + + /* Emit a notification about the thread being deleted. - id = ptid_get_tid (ptid); + Note that no notification was printed when the main thread + was created, and thus, unless in verbose mode, we should be + symmetrical, and avoid that notification for the main thread + here as well. */ if (info_verbose) - printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid)); - else if (print_thread_events && id != main_thread_id) + printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid).c_str ()); + else if (print_thread_events && !main_thread_p) printf_unfiltered (_("[%s exited with code %u]\n"), - target_pid_to_str (ptid), (unsigned) exit_code); - delete_thread (ptid); + target_pid_to_str (ptid).c_str (), + (unsigned) exit_code); + + delete_thread (find_thread_ptid (ptid)); for (th = &thread_head; th->next != NULL && th->next->id != id; @@ -509,14 +545,59 @@ windows_delete_thread (ptid_t ptid, DWORD exit_code) } } +/* Fetches register number R from the given windows_thread_info, + and supplies its value to the given regcache. + + This function assumes that R is non-negative. A failed assertion + is raised if that is not true. + + This function assumes that TH->RELOAD_CONTEXT is not set, meaning + that the windows_thread_info has an up-to-date context. A failed + assertion is raised if that assumption is violated. */ + static void -do_windows_fetch_inferior_registers (struct regcache *regcache, - windows_thread_info *th, int r) +windows_fetch_one_register (struct regcache *regcache, + windows_thread_info *th, int r) { + gdb_assert (r >= 0); + gdb_assert (!th->reload_context); + char *context_offset = ((char *) &th->context) + mappings[r]; struct gdbarch *gdbarch = regcache->arch (); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - long l; + + if (r == I387_FISEG_REGNUM (tdep)) + { + long l = *((long *) context_offset) & 0xffff; + regcache->raw_supply (r, (char *) &l); + } + else if (r == I387_FOP_REGNUM (tdep)) + { + long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + regcache->raw_supply (r, (char *) &l); + } + else if (segment_register_p (r)) + { + /* GDB treats segment registers as 32bit registers, but they are + in fact only 16 bits long. Make sure we do not read extra + bits from our source buffer. */ + long l = *((long *) context_offset) & 0xffff; + regcache->raw_supply (r, (char *) &l); + } + else + regcache->raw_supply (r, context_offset); +} + +void +windows_nat_target::fetch_registers (struct regcache *regcache, int r) +{ + DWORD tid = regcache->ptid ().tid (); + windows_thread_info *th = thread_rec (tid, TRUE); + + /* Check if TH exists. Windows sometimes uses a non-existent + thread id in its events. */ + if (th == NULL) + return; if (th->reload_context) { @@ -552,56 +633,26 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, th->reload_context = 0; } - if (r == I387_FISEG_REGNUM (tdep)) - { - l = *((long *) context_offset) & 0xffff; - regcache->raw_supply (r, (char *) &l); - } - else if (r == I387_FOP_REGNUM (tdep)) - { - l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); - regcache->raw_supply (r, (char *) &l); - } - else if (segment_register_p (r)) - { - /* GDB treats segment registers as 32bit registers, but they are - in fact only 16 bits long. Make sure we do not read extra - bits from our source buffer. */ - l = *((long *) context_offset) & 0xffff; - regcache->raw_supply (r, (char *) &l); - } - else if (r >= 0) - regcache->raw_supply (r, context_offset); + if (r < 0) + for (r = 0; r < gdbarch_num_regs (regcache->arch()); r++) + windows_fetch_one_register (regcache, th, r); else - { - for (r = 0; r < gdbarch_num_regs (gdbarch); r++) - do_windows_fetch_inferior_registers (regcache, th, r); - } + windows_fetch_one_register (regcache, th, r); } -void -windows_nat_target::fetch_registers (struct regcache *regcache, int r) -{ - DWORD pid = ptid_get_tid (regcache->ptid ()); - windows_thread_info *th = thread_rec (pid, TRUE); +/* Collect the register number R from the given regcache, and store + its value into the corresponding area of the given thread's context. - /* Check if TH exists. Windows sometimes uses a non-existent - thread id in its events. */ - if (th != NULL) - do_windows_fetch_inferior_registers (regcache, th, r); -} + This function assumes that R is non-negative. A failed assertion + assertion is raised if that is not true. */ static void -do_windows_store_inferior_registers (const struct regcache *regcache, - windows_thread_info *th, int r) +windows_store_one_register (const struct regcache *regcache, + windows_thread_info *th, int r) { - if (r >= 0) - regcache->raw_collect (r, ((char *) &th->context) + mappings[r]); - else - { - for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++) - do_windows_store_inferior_registers (regcache, th, r); - } + gdb_assert (r >= 0); + + regcache->raw_collect (r, ((char *) &th->context) + mappings[r]); } /* Store a new register value into the context of the thread tied to @@ -610,27 +661,20 @@ do_windows_store_inferior_registers (const struct regcache *regcache, void windows_nat_target::store_registers (struct regcache *regcache, int r) { - DWORD pid = ptid_get_tid (regcache->ptid ()); - windows_thread_info *th = thread_rec (pid, TRUE); + DWORD tid = regcache->ptid ().tid (); + windows_thread_info *th = thread_rec (tid, TRUE); /* Check if TH exists. Windows sometimes uses a non-existent thread id in its events. */ - if (th != NULL) - do_windows_store_inferior_registers (regcache, th, r); -} + if (th == NULL) + return; -/* Encapsulate the information required in a call to - symbol_file_add_args. */ -struct safe_symbol_file_add_args -{ - char *name; - int from_tty; - section_addr_info *addrs; - int mainline; - int flags; - struct ui_file *err, *out; - struct objfile *ret; -}; + if (r < 0) + for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++) + windows_store_one_register (regcache, th, r); + else + windows_store_one_register (regcache, th, r); +} /* Maintain a linked list of "so" information. */ struct lm_info_windows : public lm_info_base @@ -719,7 +763,6 @@ windows_make_so (const char *name, LPVOID load_addr) if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) { asection *text = NULL; - CORE_ADDR text_vma; gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->so_name, "pei-i386", -1)); @@ -737,8 +780,7 @@ windows_make_so (const char *name, LPVOID load_addr) file header and the section alignment. */ cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000); - cygwin_load_end = cygwin_load_start + bfd_section_size (abfd.get (), - text); + cygwin_load_end = cygwin_load_start + bfd_section_size (text); } #endif @@ -885,22 +927,28 @@ handle_unload_dll () static void catch_errors (void (*func) ()) { - TRY + try { func (); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { exception_print (gdb_stderr, ex); } - END_CATCH } /* Clear list of loaded DLLs. */ static void windows_clear_solib (void) { - solib_start.next = NULL; + struct so_list *so; + + for (so = solib_start.next; so; so = solib_start.next) + { + solib_start.next = so->next; + windows_free_so (so); + } + solib_end = &solib_start; } @@ -973,7 +1021,7 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) ourstatus->kind = TARGET_WAITKIND_STOPPED; retval = strtoul (p, &p, 0); if (!retval) - retval = main_thread_id; + retval = current_event.dwThreadId; else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0)) && ReadProcessMemory (current_process_handle, x, &saved_context, @@ -1038,14 +1086,16 @@ display_selector (HANDLE thread, DWORD sel) puts_filtered ("Code (Exec/Read, Conf"); break; default: - printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type); + printf_filtered ("Unknown type 0x%lx", + (unsigned long) info.HighWord.Bits.Type); } if ((info.HighWord.Bits.Type & 0x1) == 0) puts_filtered(", N.Acc"); puts_filtered (")\n"); if ((info.HighWord.Bits.Type & 0x10) == 0) puts_filtered("System selector "); - printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl); + printf_filtered ("Priviledge level = %ld. ", + (unsigned long) info.HighWord.Bits.Dpl); if (info.HighWord.Bits.Granularity) puts_filtered ("Page granular.\n"); else @@ -1277,7 +1327,6 @@ handle_exception (struct target_waitstatus *ourstatus) static BOOL windows_continue (DWORD continue_status, int id, int killed) { - int i; windows_thread_info *th; BOOL res; @@ -1348,13 +1397,13 @@ fake_create_process (void) (unsigned) GetLastError ()); /* We can not debug anything in that case. */ } - main_thread_id = current_event.dwThreadId; - current_thread = windows_add_thread ( - ptid_build (current_event.dwProcessId, 0, - current_event.dwThreadId), - current_event.u.CreateThread.hThread, - current_event.u.CreateThread.lpThreadLocalBase); - return main_thread_id; + current_thread + = windows_add_thread (ptid_t (current_event.dwProcessId, 0, + current_event.dwThreadId), + current_event.u.CreateThread.hThread, + current_event.u.CreateThread.lpThreadLocalBase, + true /* main_thread_p */); + return current_event.dwThreadId; } void @@ -1364,7 +1413,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) DWORD continue_status = DBG_CONTINUE; /* A specific PTID means `step only this thread id'. */ - int resume_all = ptid_equal (ptid, minus_one_ptid); + int resume_all = ptid == minus_one_ptid; /* If we're continuing all threads, it's the current inferior that should be handled specially. */ @@ -1386,12 +1435,11 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) structure when passing the exception to the inferior. Note that this seems possible in the exception handler itself. */ { - int i; - for (i = 0; xlate[i].them != -1; i++) - if (xlate[i].us == sig) + for (const xlate_exception &x : xlate) + if (x.us == sig) { current_event.u.Exception.ExceptionRecord.ExceptionCode - = xlate[i].them; + = x.them; continue_status = DBG_EXCEPTION_NOT_HANDLED; break; } @@ -1407,11 +1455,11 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) last_sig = GDB_SIGNAL_0; - DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n", - ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig)); + DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=0x%x, step=%d, sig=%d);\n", + ptid.pid (), (unsigned) ptid.tid (), step, sig)); /* Get context for currently selected thread. */ - th = thread_rec (ptid_get_tid (inferior_ptid), FALSE); + th = thread_rec (inferior_ptid.tid (), FALSE); if (th) { if (step) @@ -1445,7 +1493,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) if (resume_all) windows_continue (continue_status, -1, 0); else - windows_continue (continue_status, ptid_get_tid (ptid), 0); + windows_continue (continue_status, ptid.tid (), 0); } /* Ctrl-C handler used when the inferior is not run in the same console. The @@ -1523,10 +1571,11 @@ get_windows_debug_event (struct target_ops *ops, } /* Record the existence of this thread. */ thread_id = current_event.dwThreadId; - th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, - current_event.dwThreadId), - current_event.u.CreateThread.hThread, - current_event.u.CreateThread.lpThreadLocalBase); + th = windows_add_thread + (ptid_t (current_event.dwProcessId, 0, current_event.dwThreadId), + current_event.u.CreateThread.hThread, + current_event.u.CreateThread.lpThreadLocalBase, + false /* main_thread_p */); break; @@ -1535,14 +1584,11 @@ get_windows_debug_event (struct target_ops *ops, (unsigned) current_event.dwProcessId, (unsigned) current_event.dwThreadId, "EXIT_THREAD_DEBUG_EVENT")); - - if (current_event.dwThreadId != main_thread_id) - { - windows_delete_thread (ptid_build (current_event.dwProcessId, 0, - current_event.dwThreadId), - current_event.u.ExitThread.dwExitCode); - th = &dummy_thread_info; - } + windows_delete_thread (ptid_t (current_event.dwProcessId, 0, + current_event.dwThreadId), + current_event.u.ExitThread.dwExitCode, + false /* main_thread_p */); + th = &dummy_thread_info; break; case CREATE_PROCESS_DEBUG_EVENT: @@ -1555,16 +1601,13 @@ get_windows_debug_event (struct target_ops *ops, break; current_process_handle = current_event.u.CreateProcessInfo.hProcess; - if (main_thread_id) - windows_delete_thread (ptid_build (current_event.dwProcessId, 0, - main_thread_id), - 0); - main_thread_id = current_event.dwThreadId; /* Add the main thread. */ - th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, - current_event.dwThreadId), - current_event.u.CreateProcessInfo.hThread, - current_event.u.CreateProcessInfo.lpThreadLocalBase); + th = windows_add_thread + (ptid_t (current_event.dwProcessId, 0, + current_event.dwThreadId), + current_event.u.CreateProcessInfo.hThread, + current_event.u.CreateProcessInfo.lpThreadLocalBase, + true /* main_thread_p */); thread_id = current_event.dwThreadId; break; @@ -1582,9 +1625,27 @@ get_windows_debug_event (struct target_ops *ops, } else if (saw_create == 1) { - ourstatus->kind = TARGET_WAITKIND_EXITED; - ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; - thread_id = main_thread_id; + windows_delete_thread (ptid_t (current_event.dwProcessId, 0, + current_event.dwThreadId), + 0, true /* main_thread_p */); + DWORD exit_status = current_event.u.ExitProcess.dwExitCode; + /* If the exit status looks like a fatal exception, but we + don't recognize the exception's code, make the original + exit status value available, to avoid losing + information. */ + int exit_signal + = WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1; + if (exit_signal == -1) + { + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = exit_status; + } + else + { + ourstatus->kind = TARGET_WAITKIND_SIGNALLED; + ourstatus->value.sig = gdb_signal_from_host (exit_signal); + } + thread_id = current_event.dwThreadId; } break; @@ -1599,7 +1660,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_load_dll); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - thread_id = main_thread_id; + thread_id = current_event.dwThreadId; break; case UNLOAD_DLL_DEBUG_EVENT: @@ -1612,7 +1673,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_unload_dll); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - thread_id = main_thread_id; + thread_id = current_event.dwThreadId; break; case EXCEPTION_DEBUG_EVENT: @@ -1664,8 +1725,7 @@ get_windows_debug_event (struct target_ops *ops, } else { - inferior_ptid = ptid_build (current_event.dwProcessId, 0, - thread_id); + inferior_ptid = ptid_t (current_event.dwProcessId, 0, thread_id); current_thread = th; if (!current_thread) current_thread = thread_rec (thread_id, TRUE); @@ -1682,8 +1742,6 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, { int pid = -1; - target_terminal::ours (); - /* We loop when we get a non-standard exception rather than return with a SPURIOUS because resume can try and step or modify things, which needs a current_thread->h. But some of these exceptions mark @@ -1725,7 +1783,7 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, SetConsoleCtrlHandler (&ctrl_c_handler, FALSE); if (retval) - return ptid_build (current_event.dwProcessId, 0, retval); + return ptid_t (current_event.dwProcessId, 0, retval); else { int detach = 0; @@ -1745,7 +1803,6 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, static void windows_add_all_dlls (void) { - struct so_list *so; HMODULE dummy_hmodule; DWORD cb_needed; HMODULE *hmodules; @@ -1795,7 +1852,6 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) { int i; struct inferior *inf; - struct thread_info *tp; last_sig = GDB_SIGNAL_0; event_count = 0; @@ -1825,7 +1881,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) 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 windows_wait. */ - inferior_ptid = pid_to_ptid (pid); + inferior_ptid = ptid_t (pid); target_terminal::init (); target_terminal::inferior (); @@ -1950,22 +2006,21 @@ windows_nat_target::attach (const char *args, int from_tty) #endif if (!ok) - error (_("Can't attach to process.")); + error (_("Can't attach to process %u (error %u)"), + (unsigned) pid, (unsigned) GetLastError ()); DebugSetProcessKillOnExit (FALSE); if (from_tty) { - char *exec_file = (char *) get_exec_file (0); + const char *exec_file = get_exec_file (0); if (exec_file) printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, - target_pid_to_str (pid_to_ptid (pid))); + target_pid_to_str (ptid_t (pid)).c_str ()); else printf_unfiltered ("Attaching to %s\n", - target_pid_to_str (pid_to_ptid (pid))); - - gdb_flush (gdb_stdout); + target_pid_to_str (ptid_t (pid)).c_str ()); } do_initial_windows_stuff (this, pid, 1); @@ -1995,12 +2050,11 @@ windows_nat_target::detach (inferior *inf, int from_tty) exec_file = ""; printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file, (unsigned) current_event.dwProcessId); - gdb_flush (gdb_stdout); } x86_cleanup_dregs (); inferior_ptid = null_ptid; - detach_inferior (current_event.dwProcessId); + detach_inferior (inf); maybe_unpush_target (); } @@ -2094,7 +2148,7 @@ windows_nat_target::files_info () printf_unfiltered ("\tUsing the running image of %s %s.\n", inf->attach_flag ? "attached" : "child", - target_pid_to_str (inferior_ptid)); + target_pid_to_str (inferior_ptid).c_str ()); } /* Modify CreateProcess parameters for use of a new separate console. @@ -2496,16 +2550,12 @@ windows_nat_target::create_inferior (const char *exec_file, int tty; int ostdin, ostdout, ostderr; #else /* !__CYGWIN__ */ - char real_path[__PMAX]; char shell[__PMAX]; /* Path to shell */ const char *toexec; char *args, *allargs_copy; size_t args_len, allargs_len; int fd_inp = -1, fd_out = -1, fd_err = -1; HANDLE tty = INVALID_HANDLE_VALUE; - HANDLE inf_stdin = INVALID_HANDLE_VALUE; - HANDLE inf_stdout = INVALID_HANDLE_VALUE; - HANDLE inf_stderr = INVALID_HANDLE_VALUE; bool redirected = false; char *w32env; char *temp; @@ -2563,9 +2613,7 @@ windows_nat_target::create_inferior (const char *exec_file, } else { - sh = getenv ("SHELL"); - if (!sh) - sh = "/bin/sh"; + sh = get_shell (); if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0) error (_("Error starting executable via shell: %d"), errno); #ifdef __USEWIDE @@ -2666,13 +2714,13 @@ windows_nat_target::create_inferior (const char *exec_file, if (tty >= 0) { - close (tty); + ::close (tty); dup2 (ostdin, 0); dup2 (ostdout, 1); dup2 (ostderr, 2); - close (ostdin); - close (ostdout); - close (ostderr); + ::close (ostdin); + ::close (ostdout); + ::close (ostderr); } #else /* !__CYGWIN__ */ allargs_len = strlen (allargs); @@ -2685,7 +2733,7 @@ windows_nat_target::create_inferior (const char *exec_file, redirect_inferior_handles (allargs, allargs_copy, &fd_inp, &fd_out, &fd_err); if (errno) - warning (_("Error in redirection: %s."), strerror (errno)); + warning (_("Error in redirection: %s."), safe_strerror (errno)); else errno = e; allargs_len = strlen (allargs_copy); @@ -2888,21 +2936,15 @@ void windows_nat_target::close () { DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n", - ptid_get_pid (inferior_ptid))); + inferior_ptid.pid ())); } /* Convert pid to printable format. */ -const char * +std::string windows_nat_target::pid_to_str (ptid_t ptid) { - static char buf[80]; - - if (ptid_get_tid (ptid) != 0) - { - snprintf (buf, sizeof (buf), "Thread %d.0x%lx", - ptid_get_pid (ptid), ptid_get_tid (ptid)); - return buf; - } + if (ptid.tid () != 0) + return string_printf ("Thread %d.0x%lx", ptid.pid (), ptid.tid ()); return normal_pid_to_str (ptid); } @@ -2987,7 +3029,7 @@ windows_nat_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr) { windows_thread_info *th; - th = thread_rec (ptid_get_tid (ptid), 0); + th = thread_rec (ptid.tid (), 0); if (th == NULL) return false; @@ -3000,7 +3042,7 @@ windows_nat_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr) ptid_t windows_nat_target::get_ada_task_ptid (long lwp, long thread) { - return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp); + return ptid_t (inferior_ptid.pid (), 0, lwp); } /* Implementation of the to_thread_name method. */ @@ -3008,7 +3050,7 @@ windows_nat_target::get_ada_task_ptid (long lwp, long thread) const char * windows_nat_target::thread_name (struct thread_info *thr) { - return thread_rec (ptid_get_tid (thr->ptid), 0)->name; + return thread_rec (thr->ptid.tid (), 0)->name; } @@ -3168,8 +3210,8 @@ windows_nat_target::thread_alive (ptid_t ptid) { int tid; - gdb_assert (ptid_get_tid (ptid) != 0); - tid = ptid_get_tid (ptid); + gdb_assert (ptid.tid () != 0); + tid = ptid.tid (); return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) != WAIT_OBJECT_0; }