#include <cygwin/version.h>
#endif
#include <algorithm>
+#include <vector>
#include "filenames.h"
#include "symfile.h"
#include "gdbsupport/gdb_tilde_expand.h"
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/gdb_wait.h"
+#include "nat/windows-nat.h"
#define STATUS_WX86_BREAKPOINT 0x4000001F
#define STATUS_WX86_SINGLE_STEP 0x4000001E
static enum gdb_signal last_sig = GDB_SIGNAL_0;
/* Set if a signal was received from the debugged process. */
-/* Thread information structure used to track information that is
- not available in gdb's thread structure. */
-typedef struct windows_thread_info_struct
- {
- struct windows_thread_info_struct *next;
- DWORD id;
- HANDLE h;
- CORE_ADDR thread_local_base;
- char *name;
- int suspended;
- int reload_context;
- union
- {
- CONTEXT context;
-#ifdef __x86_64__
- WOW64_CONTEXT wow64_context;
-#endif
- };
- }
-windows_thread_info;
-
-static windows_thread_info thread_head;
+static std::vector<windows_thread_info *> thread_list;
/* The process and thread handles for the above context. */
static windows_thread_info *
thread_rec (DWORD id, int get_context)
{
- windows_thread_info *th;
-
- for (th = &thread_head; (th = th->next) != NULL;)
- if (th->id == id)
+ for (windows_thread_info *th : thread_list)
+ if (th->tid == id)
{
if (!th->suspended && get_context)
{
if ((th = thread_rec (id, FALSE)))
return th;
- th = XCNEW (windows_thread_info);
- th->id = id;
- th->h = h;
- th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb;
+ CORE_ADDR base = (CORE_ADDR) (uintptr_t) tlb;
#ifdef __x86_64__
/* For WOW64 processes, this is actually the pointer to the 64bit TIB,
and the 32bit TIB is exactly 2 pages after it. */
if (wow64_process)
- th->thread_local_base += 0x2000;
+ base += 0x2000;
#endif
- th->next = thread_head.next;
- thread_head.next = th;
+ th = new windows_thread_info (id, h, base);
+ thread_list.push_back (th);
/* Add this new thread to the list of threads.
static void
windows_init_thread_list (void)
{
- windows_thread_info *th = &thread_head;
-
DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
init_thread_list ();
- while (th->next != NULL)
- {
- windows_thread_info *here = th->next;
- th->next = here->next;
- xfree (here);
- }
- thread_head.next = NULL;
+
+ for (windows_thread_info *here : thread_list)
+ delete here;
+
+ thread_list.clear ();
}
/* Delete a thread from the list of threads.
static void
windows_delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p)
{
- windows_thread_info *th;
DWORD id;
gdb_assert (ptid.tid () != 0);
delete_thread (find_thread_ptid (&the_windows_nat_target, ptid));
- for (th = &thread_head;
- th->next != NULL && th->next->id != id;
- th = th->next)
- continue;
+ auto iter = std::find_if (thread_list.begin (), thread_list.end (),
+ [=] (windows_thread_info *th)
+ {
+ return th->tid == id;
+ });
- if (th->next != NULL)
+ if (iter != thread_list.end ())
{
- windows_thread_info *here = th->next;
- th->next = here->next;
- xfree (here->name);
- xfree (here);
+ delete *iter;
+ thread_list.erase (iter);
}
}
static BOOL
windows_continue (DWORD continue_status, int id, int killed)
{
- windows_thread_info *th;
BOOL res;
DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
continue_status == DBG_CONTINUE ?
"DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
- for (th = &thread_head; (th = th->next) != NULL;)
- if ((id == -1 || id == (int) th->id)
+ for (windows_thread_info *th : thread_list)
+ if ((id == -1 || id == (int) th->tid)
&& th->suspended)
{
#ifdef __x86_64__
BOOL debug_event;
DWORD continue_status, event_code;
windows_thread_info *th;
- static windows_thread_info dummy_thread_info;
+ static windows_thread_info dummy_thread_info (0, 0, 0);
DWORD thread_id = 0;
last_sig = GDB_SIGNAL_0;