From: Pedro Alves Date: Thu, 21 Oct 2021 17:16:58 +0000 (+0100) Subject: Windows gdb+gdbserver: Make current_event per-thread state X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e1aacf15a9b6d6103cfde7b062ac8b76b42feea;p=thirdparty%2Fbinutils-gdb.git Windows gdb+gdbserver: Make current_event per-thread state With non-stop mode, each thread is controlled independently of the others, and each thread has its own independent reason for its last stop. Thus, any thread-specific state that is currently per-process must be converted to per-thread state. This patch converts windows_process_info::current_event, moving it to windows_thread_info instead, renamed to last_event. Since each thread will have its own copy of its last Windows debug event, we no longer need the same information stored in struct pending_stop. Since windows_process.current_event no longer exists, we need to pass the current event as parameter to a number of methods. This adjusts both native gdb and gdbserver. Approved-By: Tom Tromey Change-Id: Ice09a5d932c912210608d5af25e1898f823e3c99 commit-id:ca7e9182 --- diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c index 11151fdc28a..4adca4afa64 100644 --- a/gdb/nat/windows-nat.c +++ b/gdb/nat/windows-nat.c @@ -300,8 +300,10 @@ get_image_name (HANDLE h, void *address, int unicode) /* See nat/windows-nat.h. */ bool -windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD *rec) +windows_process_info::handle_ms_vc_exception (const DEBUG_EVENT ¤t_event) { + const EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord; + if (rec->NumberParameters >= 3 && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000) { @@ -342,7 +344,8 @@ windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD *rec) #define MS_VC_EXCEPTION 0x406d1388 handle_exception_result -windows_process_info::handle_exception (struct target_waitstatus *ourstatus, +windows_process_info::handle_exception (DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus, bool debug_exceptions) { #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \ @@ -470,7 +473,7 @@ windows_process_info::handle_exception (struct target_waitstatus *ourstatus, break; case MS_VC_EXCEPTION: DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION"); - if (handle_ms_vc_exception (rec)) + if (handle_ms_vc_exception (current_event)) { ourstatus->set_stopped (GDB_SIGNAL_TRAP); result = HANDLE_EXCEPTION_IGNORED; @@ -610,11 +613,11 @@ windows_process_info::add_dll (LPVOID load_addr) /* See nat/windows-nat.h. */ void -windows_process_info::dll_loaded_event () +windows_process_info::dll_loaded_event (const DEBUG_EVENT ¤t_event) { gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT); - LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; + const LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; const char *dll_name; /* Try getting the DLL name via the lpImageName field of the event. diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index 8d97ecc4cb6..4710ec39130 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -46,10 +46,6 @@ struct pending_stop /* The target waitstatus we computed. TARGET_WAITKIND_IGNORE if the thread does not have a pending stop. */ target_waitstatus status; - - /* The event. A few fields of this can be referenced after a stop, - and it seemed simplest to store the entire event. */ - DEBUG_EVENT event; }; @@ -104,6 +100,10 @@ struct windows_thread_info process them once the step has completed. See PR gdb/22992. */ struct pending_stop pending_stop {}; + /* The last Windows event returned by WaitForDebugEvent for this + thread. */ + DEBUG_EVENT last_event {}; + /* The context of the thread, including any manipulations. */ union { @@ -149,10 +149,6 @@ struct windows_process_info DWORD main_thread_id = 0; enum gdb_signal last_sig = GDB_SIGNAL_0; - /* The current debug event from WaitForDebugEvent or from a pending - stop. */ - DEBUG_EVENT current_event {}; - /* Contents of $_siginfo */ EXCEPTION_RECORD siginfo_er {}; @@ -176,7 +172,8 @@ struct windows_process_info a Cygwin signal. Otherwise just print the string as a warning. This function must be supplied by the embedding application. */ - virtual DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) = 0; + virtual DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus) = 0; /* Handle a DLL load event. @@ -197,7 +194,7 @@ struct windows_process_info This function must be supplied by the embedding application. */ - virtual void handle_unload_dll () = 0; + virtual void handle_unload_dll (const DEBUG_EVENT ¤t_event) = 0; /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding application a chance to change it to be considered "unhandled". @@ -207,11 +204,12 @@ struct windows_process_info virtual bool handle_access_violation (const EXCEPTION_RECORD *rec) = 0; handle_exception_result handle_exception - (struct target_waitstatus *ourstatus, bool debug_exceptions); + (DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus, bool debug_exceptions); /* Call to indicate that a DLL was loaded. */ - void dll_loaded_event (); + void dll_loaded_event (const DEBUG_EVENT ¤t_event); /* Iterate over all DLLs currently mapped by our inferior, and add them to our list of solibs. */ @@ -247,7 +245,7 @@ private: Return true if the exception was handled; return false otherwise. */ - bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec); + bool handle_ms_vc_exception (const DEBUG_EVENT ¤t_event); /* Iterate over all DLLs currently mapped by our inferior, looking for a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 614d85ac8f7..64c53b53934 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -557,7 +557,7 @@ windows_per_inferior::handle_load_dll (const char *dll_name, LPVOID base) /* See nat/windows-nat.h. */ void -windows_per_inferior::handle_unload_dll () +windows_per_inferior::handle_unload_dll (const DEBUG_EVENT ¤t_event) { LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll; @@ -620,7 +620,8 @@ signal_event_command (const char *args, int from_tty) DWORD windows_per_inferior::handle_output_debug_string - (struct target_waitstatus *ourstatus) + (const DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus) { DWORD thread_id = 0; @@ -753,11 +754,11 @@ windows_nat_target::windows_continue (DWORD continue_status, int id, /* Called in pathological case where Windows fails to send a CREATE_PROCESS_DEBUG_EVENT after an attach. */ DWORD -windows_nat_target::fake_create_process () +windows_nat_target::fake_create_process (const DEBUG_EVENT ¤t_event) { windows_process->handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, - windows_process->current_event.dwProcessId); + current_event.dwProcessId); if (windows_process->handle != NULL) windows_process->open_process_used = 1; else @@ -766,12 +767,11 @@ windows_nat_target::fake_create_process () throw_winerror_with_name (_("OpenProcess call failed"), err); /* We can not debug anything in that case. */ } - add_thread (ptid_t (windows_process->current_event.dwProcessId, - windows_process->current_event.dwThreadId, 0), - windows_process->current_event.u.CreateThread.hThread, - windows_process->current_event.u.CreateThread.lpThreadLocalBase, + add_thread (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0), + current_event.u.CreateThread.hThread, + current_event.u.CreateThread.lpThreadLocalBase, true /* main_thread_p */); - return windows_process->current_event.dwThreadId; + return current_event.dwThreadId; } void @@ -788,6 +788,13 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) if (resume_all) ptid = inferior_ptid; + DEBUG_EXEC ("pid=%d, tid=0x%x, step=%d, sig=%d", + ptid.pid (), (unsigned) ptid.lwp (), step, sig); + + /* Get currently selected thread. */ + th = windows_process->find_thread (inferior_ptid); + gdb_assert (th != nullptr); + if (sig != GDB_SIGNAL_0) { /* Note it is OK to call get_last_debug_event_ptid() from the @@ -800,8 +807,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) DEBUG_EXCEPT ("Cannot continue with signal %d here. " "Not last-event thread", sig); } - else if (windows_process->current_event.dwDebugEventCode - != EXCEPTION_DEBUG_EVENT) + else if (th->last_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) { DEBUG_EXCEPT ("Cannot continue with signal %d here. " "Not stopped for EXCEPTION_DEBUG_EVENT", sig); @@ -818,7 +824,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) for (const xlate_exception &x : xlate) if (x.us == sig) { - current_event.u.Exception.ExceptionRecord.ExceptionCode + th->last_event.u.Exception.ExceptionRecord.ExceptionCode = x.them; continue_status = DBG_EXCEPTION_NOT_HANDLED; break; @@ -835,12 +841,8 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) windows_process->last_sig = GDB_SIGNAL_0; - DEBUG_EXEC ("pid=%d, tid=0x%x, step=%d, sig=%d", - ptid.pid (), (unsigned) ptid.lwp (), step, sig); - /* Get context for currently selected thread. */ - th = windows_process->find_thread (inferior_ptid); - if (th != nullptr && step) + if (step) { /* Single step by setting t bit. */ regcache *regcache = get_thread_regcache (inferior_thread ()); @@ -915,7 +917,8 @@ windows_nat_target::stop (ptid_t ptid) ptid_t windows_nat_target::get_windows_debug_event - (int pid, struct target_waitstatus *ourstatus, target_wait_flags options) + (int pid, struct target_waitstatus *ourstatus, target_wait_flags options, + DEBUG_EVENT *current_event) { DWORD continue_status, event_code; DWORD thread_id = 0; @@ -933,7 +936,7 @@ windows_nat_target::get_windows_debug_event thread_id = th->tid; *ourstatus = th->pending_stop.status; th->pending_stop.status.set_ignore (); - windows_process->current_event = th->pending_stop.event; + *current_event = th->last_event; ptid_t ptid (windows_process->process_id, thread_id); windows_process->invalidate_thread_context (th.get ()); @@ -942,7 +945,6 @@ windows_nat_target::get_windows_debug_event } windows_process->last_sig = GDB_SIGNAL_0; - DEBUG_EVENT *current_event = &windows_process->current_event; if ((options & TARGET_WNOHANG) != 0 && !m_debug_event_pending) { @@ -950,11 +952,11 @@ windows_nat_target::get_windows_debug_event return minus_one_ptid; } - wait_for_debug_event_main_thread (&windows_process->current_event); + wait_for_debug_event_main_thread (current_event); continue_status = DBG_CONTINUE; - event_code = windows_process->current_event.dwDebugEventCode; + event_code = current_event->dwDebugEventCode; ourstatus->set_spurious (); switch (event_code) @@ -972,7 +974,7 @@ windows_nat_target::get_windows_debug_event /* Kludge around a Windows bug where first event is a create thread event. Caused when attached process does not have a main thread. */ - thread_id = fake_create_process (); + thread_id = fake_create_process (*current_event); if (thread_id) windows_process->saw_create++; } @@ -1069,7 +1071,7 @@ windows_nat_target::get_windows_debug_event break; try { - windows_process->dll_loaded_event (); + windows_process->dll_loaded_event (*current_event); } catch (const gdb_exception &ex) { @@ -1089,7 +1091,7 @@ windows_nat_target::get_windows_debug_event break; try { - windows_process->handle_unload_dll (); + windows_process->handle_unload_dll (*current_event); } catch (const gdb_exception &ex) { @@ -1106,7 +1108,8 @@ windows_nat_target::get_windows_debug_event "EXCEPTION_DEBUG_EVENT"); if (windows_process->saw_create != 1) break; - switch (windows_process->handle_exception (ourstatus, debug_exceptions)) + switch (windows_process->handle_exception (*current_event, + ourstatus, debug_exceptions)) { case HANDLE_EXCEPTION_UNHANDLED: default: @@ -1128,7 +1131,8 @@ windows_nat_target::get_windows_debug_event "OUTPUT_DEBUG_STRING_EVENT"); if (windows_process->saw_create != 1) break; - thread_id = windows_process->handle_output_debug_string (ourstatus); + thread_id = windows_process->handle_output_debug_string (*current_event, + ourstatus); break; default: @@ -1153,6 +1157,8 @@ windows_nat_target::get_windows_debug_event const ptid_t ptid = ptid_t (current_event->dwProcessId, thread_id, 0); windows_thread_info *th = windows_process->find_thread (ptid); + th->last_event = *current_event; + if (th->suspended) { /* Pending stop. See the comment by the definition of @@ -1168,8 +1174,8 @@ windows_nat_target::get_windows_debug_event th->stopped_at_software_breakpoint = true; th->pc_adjusted = false; } + th->pending_stop.status = *ourstatus; - th->pending_stop.event = *current_event; ourstatus->set_ignore (); continue_last_debug_event_main_thread @@ -1195,7 +1201,10 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, while (1) { - ptid_t result = get_windows_debug_event (pid, ourstatus, options); + DEBUG_EVENT current_event; + + ptid_t result = get_windows_debug_event (pid, ourstatus, options, + ¤t_event); if ((options & TARGET_WNOHANG) != 0 && ourstatus->kind () == TARGET_WAITKIND_IGNORE) @@ -1214,11 +1223,11 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, windows_thread_info *th = windows_process->find_thread (result); th->stopped_at_software_breakpoint = false; - if (windows_process->current_event.dwDebugEventCode + if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT - && ((windows_process->current_event.u.Exception.ExceptionRecord.ExceptionCode + && ((current_event.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) - || (windows_process->current_event.u.Exception.ExceptionRecord.ExceptionCode + || (current_event.u.Exception.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT)) && windows_process->windows_initialization_done) { @@ -1261,8 +1270,6 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching) windows_process->cygwin_load_end = 0; #endif windows_process->process_id = pid; - memset (&windows_process->current_event, 0, - sizeof (windows_process->current_event)); inf = current_inferior (); if (!inf->target_is_pushed (this)) inf->push_target (this); @@ -1292,7 +1299,10 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching) && status.kind () != TARGET_WAITKIND_SPURIOUS) break; - this->resume (minus_one_ptid, 0, GDB_SIGNAL_0); + /* Don't use windows_nat_target::resume here because that + assumes that inferior_ptid points at a valid thread, and we + haven't switched to any thread yet. */ + windows_continue (DBG_CONTINUE, -1); } switch_to_thread (this->find_thread (last_ptid)); @@ -1575,7 +1585,7 @@ windows_nat_target::detach (inferior *inf, int from_tty) if (process_alive) do_synchronously ([&] () { - if (!DebugActiveProcessStop (windows_process->current_event.dwProcessId)) + if (!DebugActiveProcessStop (windows_process->process_id)) err = (unsigned) GetLastError (); else DebugSetProcessKillOnExit (FALSE); @@ -1586,7 +1596,7 @@ windows_nat_target::detach (inferior *inf, int from_tty) { std::string msg = string_printf (_("Can't detach process %u"), - (unsigned) windows_process->current_event.dwProcessId); + windows_process->process_id); throw_winerror_with_name (msg.c_str (), *err); } @@ -2383,9 +2393,9 @@ windows_nat_target::kill () { if (!windows_continue (DBG_CONTINUE, -1, WCONT_KILLED)) break; - wait_for_debug_event_main_thread (&windows_process->current_event); - if (windows_process->current_event.dwDebugEventCode - == EXIT_PROCESS_DEBUG_EVENT) + DEBUG_EVENT current_event; + wait_for_debug_event_main_thread (¤t_event); + if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; } diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h index 0f586cd195e..15a177214f2 100644 --- a/gdb/windows-nat.h +++ b/gdb/windows-nat.h @@ -63,9 +63,10 @@ DEF_ENUM_FLAGS_TYPE (windows_continue_flag, windows_continue_flags); struct windows_per_inferior : public windows_nat::windows_process_info { windows_thread_info *find_thread (ptid_t ptid) override; - DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) override; + DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus) override; void handle_load_dll (const char *dll_name, LPVOID base) override; - void handle_unload_dll () override; + void handle_unload_dll (const DEBUG_EVENT ¤t_event) override; bool handle_access_violation (const EXCEPTION_RECORD *rec) override; /* Invalidate the thread context. */ @@ -172,7 +173,8 @@ struct windows_nat_target : public inf_child_target const char *thread_name (struct thread_info *) override; ptid_t get_windows_debug_event (int pid, struct target_waitstatus *ourstatus, - target_wait_flags options); + target_wait_flags options, + DEBUG_EVENT *current_event); void do_initial_windows_stuff (DWORD pid, bool attaching); @@ -244,7 +246,7 @@ private: windows_thread_info *add_thread (ptid_t ptid, HANDLE h, void *tlb, bool main_thread_p); void delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p); - DWORD fake_create_process (); + DWORD fake_create_process (const DEBUG_EVENT ¤t_event); void continue_one_thread (windows_thread_info *th, windows_continue_flags cont_flags); diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 5caec960082..aa484fcda4a 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -291,9 +291,6 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached) windows_process.open_process_used = true; - memset (&windows_process.current_event, 0, - sizeof (windows_process.current_event)); - #ifdef __x86_64__ BOOL wow64; if (!IsWow64Process (proch, &wow64)) @@ -590,7 +587,8 @@ win32_process_target::attach (unsigned long pid) DWORD gdbserver_windows_process::handle_output_debug_string - (struct target_waitstatus *ourstatus) + (const DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus) { #define READ_BUFFER_LEN 1024 CORE_ADDR addr; @@ -658,14 +656,13 @@ win32_process_target::kill (process_info *process) { if (!child_continue_for_kill (DBG_CONTINUE, -1)) break; - if (!wait_for_debug_event (&windows_process.current_event, INFINITE)) + DEBUG_EVENT current_event; + if (!wait_for_debug_event (¤t_event, INFINITE)) break; - if (windows_process.current_event.dwDebugEventCode - == EXIT_PROCESS_DEBUG_EVENT) + if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; - else if (windows_process.current_event.dwDebugEventCode - == OUTPUT_DEBUG_STRING_EVENT) - windows_process.handle_output_debug_string (nullptr); + else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) + windows_process.handle_output_debug_string (current_event, nullptr); } win32_clear_process (); @@ -744,8 +741,7 @@ resume_one_thread (thread_info *thread, bool step, gdb_signal sig, OUTMSG (("Cannot continue with signal %d here. " "Not last-event thread", sig)); } - else if (windows_process.current_event.dwDebugEventCode - != EXCEPTION_DEBUG_EVENT) + else if (th->last_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) { OUTMSG (("Cannot continue with signal %s here. " "Not stopped for EXCEPTION_DEBUG_EVENT.\n", @@ -884,7 +880,7 @@ gdbserver_windows_process::handle_load_dll (const char *name, LPVOID base) /* See nat/windows-nat.h. */ void -gdbserver_windows_process::handle_unload_dll () +gdbserver_windows_process::handle_unload_dll (const DEBUG_EVENT ¤t_event) { CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll; @@ -918,7 +914,7 @@ gdbserver_windows_process::handle_access_violation PC. */ static void -maybe_adjust_pc () +maybe_adjust_pc (const DEBUG_EVENT ¤t_event) { regcache *regcache = get_thread_regcache (current_thread); child_fetch_inferior_registers (regcache, -1); @@ -927,8 +923,8 @@ maybe_adjust_pc () = windows_process.find_thread (current_thread->id); th->stopped_at_software_breakpoint = false; - if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT - && (*the_low_target.is_sw_breakpoint) (&windows_process.current_event + if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT + && (*the_low_target.is_sw_breakpoint) (¤t_event .u.Exception.ExceptionRecord) && windows_process.child_initialization_done) { @@ -943,7 +939,8 @@ maybe_adjust_pc () static int get_child_debug_event (DWORD *continue_status, - struct target_waitstatus *ourstatus) + struct target_waitstatus *ourstatus, + DEBUG_EVENT *current_event) { ptid_t ptid; @@ -954,8 +951,6 @@ get_child_debug_event (DWORD *continue_status, /* Check if GDB sent us an interrupt request. */ check_remote_input_interrupt_request (); - DEBUG_EVENT *current_event = &windows_process.current_event; - windows_process.attaching = 0; { process_info *proc = find_process_pid (windows_process.process_id); @@ -968,8 +963,8 @@ get_child_debug_event (DWORD *continue_status, { *ourstatus = th->pending_stop.status; th->pending_stop.status.set_ignore (); - windows_process.current_event = th->pending_stop.event; - ptid = debug_event_ptid (&windows_process.current_event); + *current_event = th->last_event; + ptid = debug_event_ptid (current_event); switch_to_thread (find_thread_ptid (ptid)); return 1; } @@ -978,7 +973,7 @@ get_child_debug_event (DWORD *continue_status, /* Keep the wait time low enough for comfortable remote interruption, but high enough so gdbserver doesn't become a bottleneck. */ - if (!wait_for_debug_event (&windows_process.current_event, 250)) + if (!wait_for_debug_event (current_event, 250)) { DWORD e = GetLastError(); @@ -1073,7 +1068,7 @@ get_child_debug_event (DWORD *continue_status, CloseHandle (current_event->u.LoadDll.hFile); if (! windows_process.child_initialization_done) break; - windows_process.dll_loaded_event (); + windows_process.dll_loaded_event (*current_event); ourstatus->set_loaded (); break; @@ -1085,7 +1080,7 @@ get_child_debug_event (DWORD *continue_status, (unsigned) current_event->dwThreadId)); if (! windows_process.child_initialization_done) break; - windows_process.handle_unload_dll (); + windows_process.handle_unload_dll (*current_event); ourstatus->set_loaded (); break; @@ -1094,7 +1089,8 @@ get_child_debug_event (DWORD *continue_status, "for pid=%u tid=%x\n", (unsigned) current_event->dwProcessId, (unsigned) current_event->dwThreadId)); - if (windows_process.handle_exception (ourstatus, debug_threads) + if (windows_process.handle_exception (*current_event, + ourstatus, debug_threads) == HANDLE_EXCEPTION_UNHANDLED) *continue_status = DBG_EXCEPTION_NOT_HANDLED; break; @@ -1105,7 +1101,7 @@ get_child_debug_event (DWORD *continue_status, "for pid=%u tid=%x\n", (unsigned) current_event->dwProcessId, (unsigned) current_event->dwThreadId)); - windows_process.handle_output_debug_string (nullptr); + windows_process.handle_output_debug_string (*current_event, nullptr); break; default: @@ -1117,10 +1113,12 @@ get_child_debug_event (DWORD *continue_status, break; } - ptid = debug_event_ptid (&windows_process.current_event); + ptid = debug_event_ptid (current_event); windows_thread_info *th = windows_process.find_thread (ptid); + th->last_event = *current_event; + if (th != nullptr && th->suspended) { /* Pending stop. See the comment by the definition of @@ -1129,9 +1127,8 @@ get_child_debug_event (DWORD *continue_status, OUTMSG2 (("get_windows_debug_event - " "unexpected stop in suspended thread 0x%x\n", th->tid)); - maybe_adjust_pc (); + maybe_adjust_pc (*current_event); th->pending_stop.status = *ourstatus; - th->pending_stop.event = *current_event; ourstatus->set_spurious (); } else @@ -1155,13 +1152,16 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, fails). Report it now. */ *ourstatus = windows_process.cached_status; windows_process.cached_status.set_ignore (); - return debug_event_ptid (&windows_process.current_event); + return ptid_t (windows_process.process_id, + windows_process.main_thread_id, 0); } while (1) { DWORD continue_status; - if (!get_child_debug_event (&continue_status, ourstatus)) + DEBUG_EVENT current_event; + if (!get_child_debug_event (&continue_status, ourstatus, + ¤t_event)) continue; switch (ourstatus->kind ()) @@ -1170,20 +1170,20 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, OUTMSG2 (("Child exited with retcode = %x\n", ourstatus->exit_status ())); win32_clear_process (); - return ptid_t (windows_process.current_event.dwProcessId); + return ptid_t (windows_process.process_id); case TARGET_WAITKIND_STOPPED: case TARGET_WAITKIND_SIGNALLED: case TARGET_WAITKIND_LOADED: { OUTMSG2 (("Child Stopped with signal = %d \n", ourstatus->sig ())); - maybe_adjust_pc (); + maybe_adjust_pc (current_event); /* All-stop, suspend all threads until they are explicitly resumed. */ for_each_thread (suspend_one_thread); - return debug_event_ptid (&windows_process.current_event); + return debug_event_ptid (¤t_event); } default: OUTMSG (("Ignoring unknown internal event, %d\n", diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h index 9c672bfce1a..01a904043eb 100644 --- a/gdbserver/win32-low.h +++ b/gdbserver/win32-low.h @@ -179,9 +179,10 @@ public: struct gdbserver_windows_process : public windows_nat::windows_process_info { windows_nat::windows_thread_info *find_thread (ptid_t ptid) override; - DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) override; + DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event, + struct target_waitstatus *ourstatus) override; void handle_load_dll (const char *dll_name, LPVOID base) override; - void handle_unload_dll () override; + void handle_unload_dll (const DEBUG_EVENT ¤t_event) override; bool handle_access_violation (const EXCEPTION_RECORD *rec) override; int attaching = 0;