diff options
-rw-r--r-- | gdb/nat/windows-nat.c | 13 | ||||
-rw-r--r-- | gdb/nat/windows-nat.h | 24 | ||||
-rw-r--r-- | gdb/windows-nat.c | 136 | ||||
-rw-r--r-- | gdbserver/win32-low.cc | 70 | ||||
-rw-r--r-- | gdbserver/win32-low.h | 5 |
5 files changed, 129 insertions, 119 deletions
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c index 7f8834f..cabc61f 100644 --- a/gdb/nat/windows-nat.c +++ b/gdb/nat/windows-nat.c @@ -310,8 +310,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) { @@ -352,7 +354,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) \ @@ -480,7 +483,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; @@ -634,11 +637,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 70912fd..73c828e 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -40,10 +40,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; }; @@ -98,6 +94,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 { @@ -143,10 +143,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 {}; @@ -170,7 +166,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. @@ -191,7 +188,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". @@ -201,11 +198,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. */ @@ -222,7 +220,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 2913da6..bba8468 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -107,9 +107,10 @@ DEF_ENUM_FLAGS_TYPE (windows_continue_flag, windows_continue_flags); struct windows_per_inferior : public 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; void invalidate_context (windows_thread_info *th); @@ -321,7 +322,8 @@ struct windows_nat_target final : public x86_nat_target<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); @@ -352,7 +354,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); BOOL windows_continue (DWORD continue_status, int id, windows_continue_flags cont_flags = 0); @@ -980,7 +982,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; @@ -1043,7 +1045,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; @@ -1388,11 +1391,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 @@ -1401,12 +1404,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 @@ -1423,6 +1425,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 @@ -1435,8 +1444,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); @@ -1453,7 +1461,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; @@ -1470,36 +1478,28 @@ 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) - { #ifdef __x86_64__ - if (windows_process.wow64_process) + if (windows_process.wow64_process) + { + if (step) { - if (step) - { - /* Single step by setting t bit. */ - regcache *regcache = get_thread_regcache (inferior_thread ()); - struct gdbarch *gdbarch = regcache->arch (); - fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); - th->wow64_context.EFlags |= FLAG_TRACE_BIT; - } + /* Single step by setting t bit. */ + regcache *regcache = get_thread_regcache (inferior_thread ()); + struct gdbarch *gdbarch = regcache->arch (); + fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); + th->wow64_context.EFlags |= FLAG_TRACE_BIT; } - else + } + else #endif + { + if (step) { - if (step) - { - /* Single step by setting t bit. */ - regcache *regcache = get_thread_regcache (inferior_thread ()); - struct gdbarch *gdbarch = regcache->arch (); - fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); - th->context.EFlags |= FLAG_TRACE_BIT; - } + /* Single step by setting t bit. */ + regcache *regcache = get_thread_regcache (inferior_thread ()); + struct gdbarch *gdbarch = regcache->arch (); + fetch_registers (regcache, gdbarch_ps_regnum (gdbarch)); + th->context.EFlags |= FLAG_TRACE_BIT; } } @@ -1563,7 +1563,8 @@ windows_nat_target::pass_ctrlc () 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; @@ -1581,7 +1582,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_context (th.get ()); @@ -1590,7 +1591,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) { @@ -1598,11 +1598,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) @@ -1620,7 +1620,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++; } @@ -1717,7 +1717,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) { @@ -1737,7 +1737,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) { @@ -1754,7 +1754,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: @@ -1776,7 +1777,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: @@ -1801,6 +1803,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 @@ -1819,8 +1823,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 @@ -1846,7 +1850,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) @@ -1865,11 +1872,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) { @@ -1910,8 +1917,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); @@ -1958,7 +1963,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)); @@ -2234,7 +2242,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); @@ -2245,7 +2253,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); } @@ -3042,9 +3050,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/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 99a6150..5608fb9 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -309,9 +309,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)) @@ -622,7 +619,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; @@ -691,14 +689,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_inferiors (); @@ -772,8 +769,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", @@ -918,7 +914,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; @@ -952,7 +948,7 @@ gdbserver_windows_process::handle_access_violation PC. */ static void -maybe_adjust_pc () +maybe_adjust_pc (const DEBUG_EVENT ¤t_event) { struct regcache *regcache = get_thread_regcache (current_thread, 1); child_fetch_inferior_registers (regcache, -1); @@ -961,10 +957,10 @@ maybe_adjust_pc () = windows_process.find_thread (current_thread_ptid ()); th->stopped_at_software_breakpoint = false; - if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT - && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode + if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT + && ((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.child_initialization_done) { @@ -979,7 +975,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; @@ -990,8 +987,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; { for (thread_info *thread : all_threads) @@ -1003,8 +998,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; } @@ -1013,7 +1008,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(); @@ -1108,7 +1103,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; @@ -1120,7 +1115,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; @@ -1129,7 +1124,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; @@ -1140,7 +1136,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: @@ -1152,10 +1148,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 @@ -1164,9 +1162,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 @@ -1190,13 +1187,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 ()) @@ -1205,20 +1205,20 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, OUTMSG2 (("Child exited with retcode = %x\n", ourstatus->exit_status ())); win32_clear_inferiors (); - 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 4d26b87..e99e47e 100644 --- a/gdbserver/win32-low.h +++ b/gdbserver/win32-low.h @@ -175,9 +175,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; |