Create private_thread_info hierarchy
There are multiple definitions of the private_thread_info structure compiled in the same GDB build. Because of the one definition rule, we need to change this if we want to be able to make them non-POD (e.g. use std::vector fields). This patch creates a class hierarchy, with private_thread_info being an abstract base class, and all the specific implementations inheriting from it. In order to poison XNEW/xfree for non-POD types, it is also needed to get rid of the xfree in thread_info::~thread_info, which operates on an opaque type. This is replaced by thread_info::priv now being a unique_ptr, which calls the destructor of the private_thread_info subclass when the thread is being destroyed. Including gdbthread.h from darwin-nat.h gave these errors: /Users/simark/src/binutils-gdb/gdb/gdbthread.h:609:3: error: must use 'class' tag to refer to type 'thread_info' in this scope thread_info *m_thread; ^ class /usr/include/mach/thread_act.h:240:15: note: class 'thread_info' is hidden by a non-type declaration of 'thread_info' here kern_return_t thread_info ^ It turns out that there is a thread_info function in the Darwin/XNU/mach API: http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_info.html Therefore, I had to add the class keyword at a couple of places in gdbthread.h, I don't really see a way around it. gdb/ChangeLog: * gdbthread.h (private_thread_info): Define structure type, add virtual pure destructor. (thread_info) <priv>: Change type to unique_ptr. <private_dtor>: Remove. * thread.c (add_thread_with_info): Adjust to use of unique_ptr. (private_thread_info::~private_thread_info): Provide default implementation. (thread_info::~thread_info): Don't call private_dtor nor manually free priv. * aix-thread.c (private_thread_info): Rename to ... (aix_thread_info): ... this. (get_aix_thread_info): New. (sync_threadlists): Adjust. (iter_tid): Adjust. (aix_thread_resume): Adjust. (aix_thread_fetch_registers): Adjust. (aix_thread_store_registers): Adjust. (aix_thread_extra_thread_info): Adjust. * darwin-nat.h (private_thread_info): Rename to ... (darwin_thread_info): ... this. (get_darwin_thread_info): New. * darwin-nat.c (darwin_init_thread_list): Adjust. (darwin_check_new_threads): Adjust. (thread_info_from_private_thread_info): Adjust. * linux-thread-db.c (private_thread_info): Rename to ... (thread_db_thread_info): ... this, initialize fields. (get_thread_db_thread_info): New. <dying>: Change type to bool. (update_thread_state): Adjust to type rename. (record_thread): Adjust to type rename an use of unique_ptr. (thread_db_pid_to_str): Likewise. (thread_db_extra_thread_info): Likewise. (thread_db_thread_handle_to_thread_info): Likewise. (thread_db_get_thread_local_address): Likewise. * nto-tdep.h (private_thread_info): Rename to ... (nto_thread_info): ... this, initialize fields. (get_nto_thread_info): New. <name>: Change type to std::string. * nto-tdep.c (nto_extra_thread_info): Adjust to type rename and use of unique_ptr. * nto-procfs.c (update_thread_private_data_name): Adjust to std::string change, allocate nto_private_thread_info with new. (update_thread_private_data): Adjust to unique_ptr. * remote.c (private_thread_info): Rename to ... (remote_thread_info): ... this, initialize data members with default values. <extra, name>: Change type to std::string. <thread_handle>: Change type to non-pointer. (free_private_thread_info): Remove. (get_private_info_thread): Rename to... (get_remote_thread_info): ... this, change return type, adjust to use of unique_ptr, use remote_thread_info constructor. (remote_add_thread): Adjust. (get_private_info_ptid): Rename to... (get_remote_thread_info): ...this, change return type. (remote_thread_name): Use get_remote_thread_info, adjust to change to std::string. (struct thread_item) <~thread_item>: Remove. <thread_handle>: Make non pointer. (start_thread): Adjust to thread_item::thread_handle type change. (remote_update_thread_list): Adjust to type name change, move strings from temporary to long-lived object instead of duplicating. (remote_threads_extra_info): Use get_remote_thread_info. (process_initial_stop_replies): Likewise. (resume_clear_thread_private_info): Likewise. (remote_resume): Adjust to type name change. (remote_commit_resume): Use get_remote_thread_info. (process_stop_reply): Adjust to type name change. (remote_stopped_by_sw_breakpoint): Use get_remote_thread_info. (remote_stopped_by_hw_breakpoint): Likewise. (remote_stopped_by_watchpoint): Likewise. (remote_stopped_data_address): Likewise. (remote_core_of_thread): Likewise. (remote_thread_handle_to_thread_info): Use get_private_info_thread, adjust to thread_handle field type change.
This commit is contained in:
parent
21fe1c752e
commit
7aabaf9d4a
11 changed files with 256 additions and 169 deletions
|
@ -1,3 +1,84 @@
|
||||||
|
2017-11-24 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
|
* gdbthread.h (private_thread_info): Define structure type, add
|
||||||
|
virtual pure destructor.
|
||||||
|
(thread_info) <priv>: Change type to unique_ptr.
|
||||||
|
<private_dtor>: Remove.
|
||||||
|
* thread.c (add_thread_with_info): Adjust to use of unique_ptr.
|
||||||
|
(private_thread_info::~private_thread_info): Provide default
|
||||||
|
implementation.
|
||||||
|
(thread_info::~thread_info): Don't call private_dtor nor
|
||||||
|
manually free priv.
|
||||||
|
* aix-thread.c (private_thread_info): Rename to ...
|
||||||
|
(aix_thread_info): ... this.
|
||||||
|
(get_aix_thread_info): New.
|
||||||
|
(sync_threadlists): Adjust.
|
||||||
|
(iter_tid): Adjust.
|
||||||
|
(aix_thread_resume): Adjust.
|
||||||
|
(aix_thread_fetch_registers): Adjust.
|
||||||
|
(aix_thread_store_registers): Adjust.
|
||||||
|
(aix_thread_extra_thread_info): Adjust.
|
||||||
|
* darwin-nat.h (private_thread_info): Rename to ...
|
||||||
|
(darwin_thread_info): ... this.
|
||||||
|
(get_darwin_thread_info): New.
|
||||||
|
* darwin-nat.c (darwin_init_thread_list): Adjust.
|
||||||
|
(darwin_check_new_threads): Adjust.
|
||||||
|
(thread_info_from_private_thread_info): Adjust.
|
||||||
|
* linux-thread-db.c (private_thread_info): Rename to ...
|
||||||
|
(thread_db_thread_info): ... this, initialize fields.
|
||||||
|
(get_thread_db_thread_info): New.
|
||||||
|
<dying>: Change type to bool.
|
||||||
|
(update_thread_state): Adjust to type rename.
|
||||||
|
(record_thread): Adjust to type rename an use of unique_ptr.
|
||||||
|
(thread_db_pid_to_str): Likewise.
|
||||||
|
(thread_db_extra_thread_info): Likewise.
|
||||||
|
(thread_db_thread_handle_to_thread_info): Likewise.
|
||||||
|
(thread_db_get_thread_local_address): Likewise.
|
||||||
|
* nto-tdep.h (private_thread_info): Rename to ...
|
||||||
|
(nto_thread_info): ... this, initialize fields.
|
||||||
|
(get_nto_thread_info): New.
|
||||||
|
<name>: Change type to std::string.
|
||||||
|
* nto-tdep.c (nto_extra_thread_info): Adjust to type rename and
|
||||||
|
use of unique_ptr.
|
||||||
|
* nto-procfs.c (update_thread_private_data_name): Adjust to
|
||||||
|
std::string change, allocate nto_private_thread_info with new.
|
||||||
|
(update_thread_private_data): Adjust to unique_ptr.
|
||||||
|
* remote.c (private_thread_info): Rename to ...
|
||||||
|
(remote_thread_info): ... this, initialize data members with
|
||||||
|
default values.
|
||||||
|
<extra, name>: Change type to std::string.
|
||||||
|
<thread_handle>: Change type to non-pointer.
|
||||||
|
(free_private_thread_info): Remove.
|
||||||
|
(get_private_info_thread): Rename to...
|
||||||
|
(get_remote_thread_info): ... this, change return type, adjust to
|
||||||
|
use of unique_ptr, use remote_thread_info constructor.
|
||||||
|
(remote_add_thread): Adjust.
|
||||||
|
(get_private_info_ptid): Rename to...
|
||||||
|
(get_remote_thread_info): ...this, change return type.
|
||||||
|
(remote_thread_name): Use get_remote_thread_info, adjust to
|
||||||
|
change to std::string.
|
||||||
|
(struct thread_item) <~thread_item>: Remove.
|
||||||
|
<thread_handle>: Make non pointer.
|
||||||
|
(start_thread): Adjust to thread_item::thread_handle type
|
||||||
|
change.
|
||||||
|
(remote_update_thread_list): Adjust to type name change, move
|
||||||
|
strings from temporary to long-lived object instead of
|
||||||
|
duplicating.
|
||||||
|
(remote_threads_extra_info): Use get_remote_thread_info.
|
||||||
|
(process_initial_stop_replies): Likewise.
|
||||||
|
(resume_clear_thread_private_info): Likewise.
|
||||||
|
(remote_resume): Adjust to type name change.
|
||||||
|
(remote_commit_resume): Use get_remote_thread_info.
|
||||||
|
(process_stop_reply): Adjust to type name change.
|
||||||
|
(remote_stopped_by_sw_breakpoint): Use get_remote_thread_info.
|
||||||
|
(remote_stopped_by_hw_breakpoint): Likewise.
|
||||||
|
(remote_stopped_by_watchpoint): Likewise.
|
||||||
|
(remote_stopped_data_address): Likewise.
|
||||||
|
(remote_core_of_thread): Likewise.
|
||||||
|
(remote_thread_handle_to_thread_info): Use
|
||||||
|
get_private_info_thread, adjust to thread_handle field type
|
||||||
|
change.
|
||||||
|
|
||||||
2017-11-24 Simon Marchi <simon.marchi@polymtl.ca>
|
2017-11-24 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
* remote.c (struct thread_item): Add constructor, disable copy
|
* remote.c (struct thread_item): Add constructor, disable copy
|
||||||
|
|
|
@ -84,11 +84,20 @@ static int debug_aix_thread;
|
||||||
|
|
||||||
/* Private data attached to each element in GDB's thread list. */
|
/* Private data attached to each element in GDB's thread list. */
|
||||||
|
|
||||||
struct private_thread_info {
|
struct aix_thread_info : public private_thread_info
|
||||||
|
{
|
||||||
pthdb_pthread_t pdtid; /* thread's libpthdebug id */
|
pthdb_pthread_t pdtid; /* thread's libpthdebug id */
|
||||||
pthdb_tid_t tid; /* kernel thread id */
|
pthdb_tid_t tid; /* kernel thread id */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Return the aix_thread_info attached to THREAD. */
|
||||||
|
|
||||||
|
static aix_thread_info *
|
||||||
|
get_aix_thread_info (thread_info *thread)
|
||||||
|
{
|
||||||
|
return static_cast<aix_thread_info *> (thread->priv.get ());
|
||||||
|
}
|
||||||
|
|
||||||
/* Information about a thread of which libpthdebug is aware. */
|
/* Information about a thread of which libpthdebug is aware. */
|
||||||
|
|
||||||
struct pd_thread {
|
struct pd_thread {
|
||||||
|
@ -756,10 +765,12 @@ sync_threadlists (void)
|
||||||
}
|
}
|
||||||
else if (gi == gcount)
|
else if (gi == gcount)
|
||||||
{
|
{
|
||||||
thread = add_thread (ptid_build (infpid, 0, pbuf[pi].pthid));
|
aix_thread_info *priv = new aix_thread_info;
|
||||||
thread->priv = XNEW (struct private_thread_info);
|
priv->pdtid = pbuf[pi].pdtid;
|
||||||
thread->priv->pdtid = pbuf[pi].pdtid;
|
priv->tid = pbuf[pi].tid;
|
||||||
thread->priv->tid = pbuf[pi].tid;
|
|
||||||
|
thread = add_thread_with_info (ptid_t (infpid, 0, pbuf[pi].pthid), priv);
|
||||||
|
|
||||||
pi++;
|
pi++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -776,8 +787,10 @@ sync_threadlists (void)
|
||||||
|
|
||||||
if (cmp_result == 0)
|
if (cmp_result == 0)
|
||||||
{
|
{
|
||||||
gbuf[gi]->priv->pdtid = pdtid;
|
aix_thread_info *priv = get_aix_thread_info (gbuf[gi]);
|
||||||
gbuf[gi]->priv->tid = tid;
|
|
||||||
|
priv->pdtid = pdtid;
|
||||||
|
priv->tid = tid;
|
||||||
pi++;
|
pi++;
|
||||||
gi++;
|
gi++;
|
||||||
}
|
}
|
||||||
|
@ -789,9 +802,11 @@ sync_threadlists (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thread = add_thread (pptid);
|
thread = add_thread (pptid);
|
||||||
thread->priv = XNEW (struct private_thread_info);
|
|
||||||
thread->priv->pdtid = pdtid;
|
aix_thread_info *priv = new aix_thread_info;
|
||||||
thread->priv->tid = tid;
|
thread->priv.reset (priv);
|
||||||
|
priv->pdtid = pdtid;
|
||||||
|
priv->tid = tid;
|
||||||
pi++;
|
pi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -808,8 +823,9 @@ static int
|
||||||
iter_tid (struct thread_info *thread, void *tidp)
|
iter_tid (struct thread_info *thread, void *tidp)
|
||||||
{
|
{
|
||||||
const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
|
const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
|
||||||
|
aix_thread_info *priv = get_aix_thread_info (thread);
|
||||||
|
|
||||||
return (thread->priv->tid == tid);
|
return priv->tid == tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Synchronize libpthdebug's state with the inferior and with GDB,
|
/* Synchronize libpthdebug's state with the inferior and with GDB,
|
||||||
|
@ -998,7 +1014,9 @@ aix_thread_resume (struct target_ops *ops,
|
||||||
error (_("aix-thread resume: unknown pthread %ld"),
|
error (_("aix-thread resume: unknown pthread %ld"),
|
||||||
ptid_get_lwp (ptid));
|
ptid_get_lwp (ptid));
|
||||||
|
|
||||||
tid[0] = thread->priv->tid;
|
aix_thread_info *priv = get_aix_thread_info (thread);
|
||||||
|
|
||||||
|
tid[0] = priv->tid;
|
||||||
if (tid[0] == PTHDB_INVALID_TID)
|
if (tid[0] == PTHDB_INVALID_TID)
|
||||||
error (_("aix-thread resume: no tid for pthread %ld"),
|
error (_("aix-thread resume: no tid for pthread %ld"),
|
||||||
ptid_get_lwp (ptid));
|
ptid_get_lwp (ptid));
|
||||||
|
@ -1314,10 +1332,11 @@ aix_thread_fetch_registers (struct target_ops *ops,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thread = find_thread_ptid (regcache_get_ptid (regcache));
|
thread = find_thread_ptid (regcache_get_ptid (regcache));
|
||||||
tid = thread->priv->tid;
|
aix_thread_info *priv = get_aix_thread_info (thread);
|
||||||
|
tid = priv->tid;
|
||||||
|
|
||||||
if (tid == PTHDB_INVALID_TID)
|
if (tid == PTHDB_INVALID_TID)
|
||||||
fetch_regs_user_thread (regcache, thread->priv->pdtid);
|
fetch_regs_user_thread (regcache, priv->pdtid);
|
||||||
else
|
else
|
||||||
fetch_regs_kernel_thread (regcache, regno, tid);
|
fetch_regs_kernel_thread (regcache, regno, tid);
|
||||||
}
|
}
|
||||||
|
@ -1668,10 +1687,11 @@ aix_thread_store_registers (struct target_ops *ops,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thread = find_thread_ptid (regcache_get_ptid (regcache));
|
thread = find_thread_ptid (regcache_get_ptid (regcache));
|
||||||
tid = thread->priv->tid;
|
aix_thread_info *priv = get_aix_thread_info (thread);
|
||||||
|
tid = priv->tid;
|
||||||
|
|
||||||
if (tid == PTHDB_INVALID_TID)
|
if (tid == PTHDB_INVALID_TID)
|
||||||
store_regs_user_thread (regcache, thread->priv->pdtid);
|
store_regs_user_thread (regcache, priv->pdtid);
|
||||||
else
|
else
|
||||||
store_regs_kernel_thread (regcache, regno, tid);
|
store_regs_kernel_thread (regcache, regno, tid);
|
||||||
}
|
}
|
||||||
|
@ -1759,9 +1779,10 @@ aix_thread_extra_thread_info (struct target_ops *self,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
string_file buf;
|
string_file buf;
|
||||||
|
aix_thread_info *priv = get_aix_thread_info (thread);
|
||||||
|
|
||||||
pdtid = thread->priv->pdtid;
|
pdtid = priv->pdtid;
|
||||||
tid = thread->priv->tid;
|
tid = priv->tid;
|
||||||
|
|
||||||
if (tid != PTHDB_INVALID_TID)
|
if (tid != PTHDB_INVALID_TID)
|
||||||
/* i18n: Like "thread-identifier %d, [state] running, suspended" */
|
/* i18n: Like "thread-identifier %d, [state] running, suspended" */
|
||||||
|
|
|
@ -363,9 +363,8 @@ darwin_check_new_threads (struct inferior *inf)
|
||||||
if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
|
if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
|
||||||
{
|
{
|
||||||
/* A thread was created. */
|
/* A thread was created. */
|
||||||
struct private_thread_info *pti;
|
darwin_thread_info *pti = new darwin_thread_info;
|
||||||
|
|
||||||
pti = XCNEW (darwin_thread_t);
|
|
||||||
pti->gdb_port = new_id;
|
pti->gdb_port = new_id;
|
||||||
pti->msg_state = DARWIN_RUNNING;
|
pti->msg_state = DARWIN_RUNNING;
|
||||||
|
|
||||||
|
@ -1692,16 +1691,18 @@ darwin_attach_pid (struct inferior *inf)
|
||||||
push_target (darwin_ops);
|
push_target (darwin_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the thread_info object corresponding to this private_thread_info. */
|
/* Get the thread_info object corresponding to this darwin_thread_info. */
|
||||||
|
|
||||||
static struct thread_info *
|
static struct thread_info *
|
||||||
thread_info_from_private_thread_info (private_thread_info *pti)
|
thread_info_from_private_thread_info (darwin_thread_info *pti)
|
||||||
{
|
{
|
||||||
struct thread_info *it;
|
struct thread_info *it;
|
||||||
|
|
||||||
ALL_THREADS (it)
|
ALL_THREADS (it)
|
||||||
{
|
{
|
||||||
if (it->priv->gdb_port == pti->gdb_port)
|
darwin_thread_info *iter_pti = get_darwin_thread_info (it);
|
||||||
|
|
||||||
|
if (iter_pti->gdb_port == pti->gdb_port)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1719,7 +1720,7 @@ darwin_init_thread_list (struct inferior *inf)
|
||||||
|
|
||||||
gdb_assert (!priv->threads.empty ());
|
gdb_assert (!priv->threads.empty ());
|
||||||
|
|
||||||
private_thread_info *first_pti = priv->threads.front ();
|
darwin_thread_info *first_pti = priv->threads.front ();
|
||||||
struct thread_info *first_thread
|
struct thread_info *first_thread
|
||||||
= thread_info_from_private_thread_info (first_pti);
|
= thread_info_from_private_thread_info (first_pti);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define __DARWIN_NAT_H__
|
#define __DARWIN_NAT_H__
|
||||||
|
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
|
#include "gdbthread.h"
|
||||||
|
|
||||||
/* Describe the mach exception handling state for a task. This state is saved
|
/* Describe the mach exception handling state for a task. This state is saved
|
||||||
before being changed and restored when a process is detached.
|
before being changed and restored when a process is detached.
|
||||||
|
@ -69,7 +70,7 @@ enum darwin_msg_state
|
||||||
DARWIN_MESSAGE
|
DARWIN_MESSAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct private_thread_info
|
struct darwin_thread_info : public private_thread_info
|
||||||
{
|
{
|
||||||
/* The thread port from a GDB point of view. */
|
/* The thread port from a GDB point of view. */
|
||||||
thread_t gdb_port;
|
thread_t gdb_port;
|
||||||
|
@ -92,7 +93,13 @@ struct private_thread_info
|
||||||
/* The last exception received. */
|
/* The last exception received. */
|
||||||
struct darwin_exception_msg event;
|
struct darwin_exception_msg event;
|
||||||
};
|
};
|
||||||
typedef struct private_thread_info darwin_thread_t;
|
typedef struct darwin_thread_info darwin_thread_t;
|
||||||
|
|
||||||
|
static inline darwin_thread_info *
|
||||||
|
get_darwin_thread_info (class thread_info *thread)
|
||||||
|
{
|
||||||
|
return static_cast<darwin_thread_info *> (thread->priv.get ());
|
||||||
|
}
|
||||||
|
|
||||||
/* Describe an inferior. */
|
/* Describe an inferior. */
|
||||||
struct darwin_inferior : public private_inferior
|
struct darwin_inferior : public private_inferior
|
||||||
|
|
|
@ -179,6 +179,12 @@ typedef struct value *value_ptr;
|
||||||
DEF_VEC_P (value_ptr);
|
DEF_VEC_P (value_ptr);
|
||||||
typedef VEC (value_ptr) value_vec;
|
typedef VEC (value_ptr) value_vec;
|
||||||
|
|
||||||
|
/* Base class for target-specific thread data. */
|
||||||
|
struct private_thread_info
|
||||||
|
{
|
||||||
|
virtual ~private_thread_info () = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/* Threads are intrusively refcounted objects. Being the
|
/* Threads are intrusively refcounted objects. Being the
|
||||||
user-selected thread is normally considered an implicit strong
|
user-selected thread is normally considered an implicit strong
|
||||||
reference and is thus not accounted in the refcount, unlike
|
reference and is thus not accounted in the refcount, unlike
|
||||||
|
@ -345,11 +351,7 @@ public:
|
||||||
struct frame_id initiating_frame = null_frame_id;
|
struct frame_id initiating_frame = null_frame_id;
|
||||||
|
|
||||||
/* Private data used by the target vector implementation. */
|
/* Private data used by the target vector implementation. */
|
||||||
struct private_thread_info *priv = NULL;
|
std::unique_ptr<private_thread_info> priv;
|
||||||
|
|
||||||
/* Function that is called to free PRIVATE. If this is NULL, then
|
|
||||||
xfree will be called on PRIVATE. */
|
|
||||||
void (*private_dtor) (struct private_thread_info *) = NULL;
|
|
||||||
|
|
||||||
/* Branch trace information for this thread. */
|
/* Branch trace information for this thread. */
|
||||||
struct btrace_thread_info btrace {};
|
struct btrace_thread_info btrace {};
|
||||||
|
@ -604,7 +606,9 @@ public:
|
||||||
DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);
|
DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
thread_info *m_thread;
|
/* Use the "class" keyword here, because of a clash with a "thread_info"
|
||||||
|
function in the Darwin API. */
|
||||||
|
class thread_info *m_thread;
|
||||||
inferior *m_inf;
|
inferior *m_inf;
|
||||||
frame_id m_selected_frame_id;
|
frame_id m_selected_frame_id;
|
||||||
int m_selected_frame_level;
|
int m_selected_frame_level;
|
||||||
|
@ -683,7 +687,7 @@ extern void print_selected_thread_frame (struct ui_out *uiout,
|
||||||
Selects thread THR. TIDSTR is the original string the thread ID
|
Selects thread THR. TIDSTR is the original string the thread ID
|
||||||
was parsed from. This is used in the error message if THR is not
|
was parsed from. This is used in the error message if THR is not
|
||||||
alive anymore. */
|
alive anymore. */
|
||||||
extern void thread_select (const char *tidstr, thread_info *thr);
|
extern void thread_select (const char *tidstr, class thread_info *thr);
|
||||||
|
|
||||||
extern struct thread_info *thread_list;
|
extern struct thread_info *thread_list;
|
||||||
|
|
||||||
|
|
|
@ -251,16 +251,21 @@ delete_thread_db_info (int pid)
|
||||||
/* Use "struct private_thread_info" to cache thread state. This is
|
/* Use "struct private_thread_info" to cache thread state. This is
|
||||||
a substantial optimization. */
|
a substantial optimization. */
|
||||||
|
|
||||||
struct private_thread_info
|
struct thread_db_thread_info : public private_thread_info
|
||||||
{
|
{
|
||||||
/* Flag set when we see a TD_DEATH event for this thread. */
|
/* Flag set when we see a TD_DEATH event for this thread. */
|
||||||
unsigned int dying:1;
|
bool dying = false;
|
||||||
|
|
||||||
/* Cached thread state. */
|
/* Cached thread state. */
|
||||||
td_thrhandle_t th;
|
td_thrhandle_t th {};
|
||||||
thread_t tid;
|
thread_t tid {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static thread_db_thread_info *
|
||||||
|
get_thread_db_thread_info (thread_info *thread)
|
||||||
|
{
|
||||||
|
return static_cast<thread_db_thread_info *> (thread->priv.get ());
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
thread_db_err_str (td_err_e err)
|
thread_db_err_str (td_err_e err)
|
||||||
|
@ -1040,7 +1045,7 @@ thread_db_inferior_created (struct target_ops *target, int from_tty)
|
||||||
from libthread_db thread state information. */
|
from libthread_db thread state information. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_thread_state (struct private_thread_info *priv,
|
update_thread_state (thread_db_thread_info *priv,
|
||||||
const td_thrinfo_t *ti_p)
|
const td_thrinfo_t *ti_p)
|
||||||
{
|
{
|
||||||
priv->dying = (ti_p->ti_state == TD_THR_UNKNOWN
|
priv->dying = (ti_p->ti_state == TD_THR_UNKNOWN
|
||||||
|
@ -1057,8 +1062,6 @@ record_thread (struct thread_db_info *info,
|
||||||
ptid_t ptid, const td_thrhandle_t *th_p,
|
ptid_t ptid, const td_thrhandle_t *th_p,
|
||||||
const td_thrinfo_t *ti_p)
|
const td_thrinfo_t *ti_p)
|
||||||
{
|
{
|
||||||
struct private_thread_info *priv;
|
|
||||||
|
|
||||||
/* A thread ID of zero may mean the thread library has not
|
/* A thread ID of zero may mean the thread library has not
|
||||||
initialized yet. Leave private == NULL until the thread library
|
initialized yet. Leave private == NULL until the thread library
|
||||||
has initialized. */
|
has initialized. */
|
||||||
|
@ -1066,7 +1069,7 @@ record_thread (struct thread_db_info *info,
|
||||||
return tp;
|
return tp;
|
||||||
|
|
||||||
/* Construct the thread's private data. */
|
/* Construct the thread's private data. */
|
||||||
priv = XCNEW (struct private_thread_info);
|
thread_db_thread_info *priv = new thread_db_thread_info;
|
||||||
|
|
||||||
priv->th = *th_p;
|
priv->th = *th_p;
|
||||||
priv->tid = ti_p->ti_tid;
|
priv->tid = ti_p->ti_tid;
|
||||||
|
@ -1078,7 +1081,7 @@ record_thread (struct thread_db_info *info,
|
||||||
if (tp == NULL || tp->state == THREAD_EXITED)
|
if (tp == NULL || tp->state == THREAD_EXITED)
|
||||||
tp = add_thread_with_info (ptid, priv);
|
tp = add_thread_with_info (ptid, priv);
|
||||||
else
|
else
|
||||||
tp->priv = priv;
|
tp->priv.reset (priv);
|
||||||
|
|
||||||
if (target_has_execution)
|
if (target_has_execution)
|
||||||
check_thread_signals ();
|
check_thread_signals ();
|
||||||
|
@ -1381,11 +1384,10 @@ thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
|
||||||
if (thread_info != NULL && thread_info->priv != NULL)
|
if (thread_info != NULL && thread_info->priv != NULL)
|
||||||
{
|
{
|
||||||
static char buf[64];
|
static char buf[64];
|
||||||
thread_t tid;
|
thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
|
||||||
|
|
||||||
tid = thread_info->priv->tid;
|
|
||||||
snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
|
snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
|
||||||
(unsigned long) tid, ptid_get_lwp (ptid));
|
(unsigned long) priv->tid, ptid_get_lwp (ptid));
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -1404,7 +1406,9 @@ thread_db_extra_thread_info (struct target_ops *self,
|
||||||
if (info->priv == NULL)
|
if (info->priv == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (info->priv->dying)
|
thread_db_thread_info *priv = get_thread_db_thread_info (info);
|
||||||
|
|
||||||
|
if (priv->dying)
|
||||||
return "Exiting";
|
return "Exiting";
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1434,7 +1438,9 @@ thread_db_thread_handle_to_thread_info (struct target_ops *ops,
|
||||||
|
|
||||||
ALL_NON_EXITED_THREADS (tp)
|
ALL_NON_EXITED_THREADS (tp)
|
||||||
{
|
{
|
||||||
if (tp->inf == inf && tp->priv != NULL && handle_tid == tp->priv->tid)
|
thread_db_thread_info *priv = get_thread_db_thread_info (tp);
|
||||||
|
|
||||||
|
if (tp->inf == inf && priv != NULL && handle_tid == priv->tid)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1464,9 +1470,8 @@ thread_db_get_thread_local_address (struct target_ops *ops,
|
||||||
{
|
{
|
||||||
td_err_e err;
|
td_err_e err;
|
||||||
psaddr_t address;
|
psaddr_t address;
|
||||||
struct thread_db_info *info;
|
thread_db_info *info = get_thread_db_info (ptid_get_pid (ptid));
|
||||||
|
thread_db_thread_info *priv = get_thread_db_thread_info (thread_info);
|
||||||
info = get_thread_db_info (ptid_get_pid (ptid));
|
|
||||||
|
|
||||||
/* Finally, get the address of the variable. */
|
/* Finally, get the address of the variable. */
|
||||||
if (lm != 0)
|
if (lm != 0)
|
||||||
|
@ -1479,7 +1484,7 @@ thread_db_get_thread_local_address (struct target_ops *ops,
|
||||||
/* Note the cast through uintptr_t: this interface only works if
|
/* Note the cast through uintptr_t: this interface only works if
|
||||||
a target address fits in a psaddr_t, which is a host pointer.
|
a target address fits in a psaddr_t, which is a host pointer.
|
||||||
So a 32-bit debugger can not access 64-bit TLS through this. */
|
So a 32-bit debugger can not access 64-bit TLS through this. */
|
||||||
err = info->td_thr_tls_get_addr_p (&thread_info->priv->th,
|
err = info->td_thr_tls_get_addr_p (&priv->th,
|
||||||
(psaddr_t)(uintptr_t) lm,
|
(psaddr_t)(uintptr_t) lm,
|
||||||
offset, &address);
|
offset, &address);
|
||||||
}
|
}
|
||||||
|
@ -1497,8 +1502,7 @@ thread_db_get_thread_local_address (struct target_ops *ops,
|
||||||
PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL.
|
PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL.
|
||||||
The constant number 1 depends on GNU __libc_setup_tls
|
The constant number 1 depends on GNU __libc_setup_tls
|
||||||
initialization of l_tls_modid to 1. */
|
initialization of l_tls_modid to 1. */
|
||||||
err = info->td_thr_tlsbase_p (&thread_info->priv->th,
|
err = info->td_thr_tlsbase_p (&priv->th, 1, &address);
|
||||||
1, &address);
|
|
||||||
address = (char *) address + offset;
|
address = (char *) address + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,38 +248,24 @@ static void
|
||||||
update_thread_private_data_name (struct thread_info *new_thread,
|
update_thread_private_data_name (struct thread_info *new_thread,
|
||||||
const char *newname)
|
const char *newname)
|
||||||
{
|
{
|
||||||
int newnamelen;
|
nto_thread_info *pti = get_nto_thread_info (new_thread);
|
||||||
struct private_thread_info *pti;
|
|
||||||
|
|
||||||
gdb_assert (newname != NULL);
|
gdb_assert (newname != NULL);
|
||||||
gdb_assert (new_thread != NULL);
|
gdb_assert (new_thread != NULL);
|
||||||
newnamelen = strlen (newname);
|
|
||||||
if (!new_thread->priv)
|
|
||||||
{
|
|
||||||
new_thread->priv = xmalloc (offsetof (struct private_thread_info,
|
|
||||||
name)
|
|
||||||
+ newnamelen + 1);
|
|
||||||
memcpy (new_thread->priv->name, newname, newnamelen + 1);
|
|
||||||
}
|
|
||||||
else if (strcmp (newname, new_thread->priv->name) != 0)
|
|
||||||
{
|
|
||||||
/* Reallocate if neccessary. */
|
|
||||||
int oldnamelen = strlen (new_thread->priv->name);
|
|
||||||
|
|
||||||
if (oldnamelen < newnamelen)
|
if (pti)
|
||||||
new_thread->priv = xrealloc (new_thread->priv,
|
{
|
||||||
offsetof (struct private_thread_info,
|
pti = new nto_thread_info;
|
||||||
name)
|
new_thread->priv.reset (pti);
|
||||||
+ newnamelen + 1);
|
|
||||||
memcpy (new_thread->priv->name, newname, newnamelen + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pti->name = newname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_thread_private_data (struct thread_info *new_thread,
|
update_thread_private_data (struct thread_info *new_thread,
|
||||||
pthread_t tid, int state, int flags)
|
pthread_t tid, int state, int flags)
|
||||||
{
|
{
|
||||||
struct private_thread_info *pti;
|
|
||||||
procfs_info pidinfo;
|
procfs_info pidinfo;
|
||||||
struct _thread_name *tn;
|
struct _thread_name *tn;
|
||||||
procfs_threadctl tctl;
|
procfs_threadctl tctl;
|
||||||
|
@ -306,7 +292,7 @@ update_thread_private_data (struct thread_info *new_thread,
|
||||||
|
|
||||||
update_thread_private_data_name (new_thread, tn->name_buf);
|
update_thread_private_data_name (new_thread, tn->name_buf);
|
||||||
|
|
||||||
pti = (struct private_thread_info *) new_thread->priv;
|
nto_thread_info *pti = get_nto_thread_info (new_thread);
|
||||||
pti->tid = tid;
|
pti->tid = tid;
|
||||||
pti->state = state;
|
pti->state = state;
|
||||||
pti->flags = flags;
|
pti->flags = flags;
|
||||||
|
|
|
@ -380,9 +380,13 @@ static const char *nto_thread_state_str[] =
|
||||||
const char *
|
const char *
|
||||||
nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
|
nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
|
||||||
{
|
{
|
||||||
if (ti && ti->priv
|
if (ti != NULL && ti->priv != NULL)
|
||||||
&& ti->priv->state < ARRAY_SIZE (nto_thread_state_str))
|
{
|
||||||
return (char *)nto_thread_state_str [ti->priv->state];
|
nto_thread_info *priv = get_nto_thread_info (ti);
|
||||||
|
|
||||||
|
if (priv->state < ARRAY_SIZE (nto_thread_state_str))
|
||||||
|
return nto_thread_state_str [priv->state];
|
||||||
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,14 +134,20 @@ typedef struct _debug_regs
|
||||||
qnx_reg64 padding[1024];
|
qnx_reg64 padding[1024];
|
||||||
} nto_regset_t;
|
} nto_regset_t;
|
||||||
|
|
||||||
struct private_thread_info
|
struct nto_thread_info : public private_thread_info
|
||||||
{
|
{
|
||||||
short tid;
|
short tid = 0;
|
||||||
unsigned char state;
|
unsigned char state = 0;
|
||||||
unsigned char flags;
|
unsigned char flags = 0;
|
||||||
char name[1];
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline nto_thread_info *
|
||||||
|
get_nto_thread_info (thread_info *thread)
|
||||||
|
{
|
||||||
|
return static_cast<nto_thread_info *> (thread->priv.get ());
|
||||||
|
}
|
||||||
|
|
||||||
/* Per-inferior data, common for both procfs and remote. */
|
/* Per-inferior data, common for both procfs and remote. */
|
||||||
struct nto_inferior_data
|
struct nto_inferior_data
|
||||||
{
|
{
|
||||||
|
|
129
gdb/remote.c
129
gdb/remote.c
|
@ -439,23 +439,23 @@ struct remote_state
|
||||||
struct readahead_cache readahead_cache;
|
struct readahead_cache readahead_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Private data that we'll store in (struct thread_info)->private. */
|
/* Private data that we'll store in (struct thread_info)->priv. */
|
||||||
struct private_thread_info
|
struct remote_thread_info : public private_thread_info
|
||||||
{
|
{
|
||||||
char *extra;
|
std::string extra;
|
||||||
char *name;
|
std::string name;
|
||||||
int core;
|
int core = -1;
|
||||||
|
|
||||||
/* Thread handle, perhaps a pthread_t or thread_t value, stored as a
|
/* Thread handle, perhaps a pthread_t or thread_t value, stored as a
|
||||||
sequence of bytes. */
|
sequence of bytes. */
|
||||||
gdb::byte_vector *thread_handle;
|
gdb::byte_vector thread_handle;
|
||||||
|
|
||||||
/* Whether the target stopped for a breakpoint/watchpoint. */
|
/* Whether the target stopped for a breakpoint/watchpoint. */
|
||||||
enum target_stop_reason stop_reason;
|
enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;
|
||||||
|
|
||||||
/* This is set to the data address of the access causing the target
|
/* This is set to the data address of the access causing the target
|
||||||
to stop for a watchpoint. */
|
to stop for a watchpoint. */
|
||||||
CORE_ADDR watch_data_address;
|
CORE_ADDR watch_data_address = 0;
|
||||||
|
|
||||||
/* Fields used by the vCont action coalescing implemented in
|
/* Fields used by the vCont action coalescing implemented in
|
||||||
remote_resume / remote_commit_resume. remote_resume stores each
|
remote_resume / remote_commit_resume. remote_resume stores each
|
||||||
|
@ -465,26 +465,17 @@ struct private_thread_info
|
||||||
|
|
||||||
/* True if the last target_resume call for this thread was a step
|
/* True if the last target_resume call for this thread was a step
|
||||||
request, false if a continue request. */
|
request, false if a continue request. */
|
||||||
int last_resume_step;
|
int last_resume_step = 0;
|
||||||
|
|
||||||
/* The signal specified in the last target_resume call for this
|
/* The signal specified in the last target_resume call for this
|
||||||
thread. */
|
thread. */
|
||||||
enum gdb_signal last_resume_sig;
|
gdb_signal last_resume_sig = GDB_SIGNAL_0;
|
||||||
|
|
||||||
/* Whether this thread was already vCont-resumed on the remote
|
/* Whether this thread was already vCont-resumed on the remote
|
||||||
side. */
|
side. */
|
||||||
int vcont_resumed;
|
int vcont_resumed = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
free_private_thread_info (struct private_thread_info *info)
|
|
||||||
{
|
|
||||||
xfree (info->extra);
|
|
||||||
xfree (info->name);
|
|
||||||
delete info->thread_handle;
|
|
||||||
xfree (info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This data could be associated with a target, but we do not always
|
/* This data could be associated with a target, but we do not always
|
||||||
have access to the current target when we need it, so for now it is
|
have access to the current target when we need it, so for now it is
|
||||||
static. This will be fine for as long as only one target is in use
|
static. This will be fine for as long as only one target is in use
|
||||||
|
@ -1826,8 +1817,7 @@ remote_add_inferior (int fake_pid_p, int pid, int attached,
|
||||||
return inf;
|
return inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct private_thread_info *
|
static remote_thread_info *get_remote_thread_info (thread_info *thread);
|
||||||
get_private_info_thread (struct thread_info *info);
|
|
||||||
|
|
||||||
/* Add thread PTID to GDB's thread list. Tag it as executing/running
|
/* Add thread PTID to GDB's thread list. Tag it as executing/running
|
||||||
according to RUNNING. */
|
according to RUNNING. */
|
||||||
|
@ -1849,7 +1839,7 @@ remote_add_thread (ptid_t ptid, int running, int executing)
|
||||||
else
|
else
|
||||||
thread = add_thread (ptid);
|
thread = add_thread (ptid);
|
||||||
|
|
||||||
get_private_info_thread (thread)->vcont_resumed = executing;
|
get_remote_thread_info (thread)->vcont_resumed = executing;
|
||||||
set_executing (ptid, executing);
|
set_executing (ptid, executing);
|
||||||
set_running (ptid, running);
|
set_running (ptid, running);
|
||||||
}
|
}
|
||||||
|
@ -1946,39 +1936,25 @@ remote_notice_new_inferior (ptid_t currthread, int executing)
|
||||||
|
|
||||||
/* Return THREAD's private thread data, creating it if necessary. */
|
/* Return THREAD's private thread data, creating it if necessary. */
|
||||||
|
|
||||||
static struct private_thread_info *
|
static remote_thread_info *
|
||||||
get_private_info_thread (struct thread_info *thread)
|
get_remote_thread_info (thread_info *thread)
|
||||||
{
|
{
|
||||||
gdb_assert (thread != NULL);
|
gdb_assert (thread != NULL);
|
||||||
|
|
||||||
if (thread->priv == NULL)
|
if (thread->priv == NULL)
|
||||||
{
|
thread->priv.reset (new remote_thread_info);
|
||||||
struct private_thread_info *priv = XNEW (struct private_thread_info);
|
|
||||||
|
|
||||||
thread->private_dtor = free_private_thread_info;
|
return static_cast<remote_thread_info *> (thread->priv.get ());
|
||||||
thread->priv = priv;
|
|
||||||
|
|
||||||
priv->core = -1;
|
|
||||||
priv->extra = NULL;
|
|
||||||
priv->name = NULL;
|
|
||||||
priv->name = NULL;
|
|
||||||
priv->last_resume_step = 0;
|
|
||||||
priv->last_resume_sig = GDB_SIGNAL_0;
|
|
||||||
priv->vcont_resumed = 0;
|
|
||||||
priv->thread_handle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return thread->priv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return PTID's private thread data, creating it if necessary. */
|
/* Return PTID's private thread data, creating it if necessary. */
|
||||||
|
|
||||||
static struct private_thread_info *
|
static remote_thread_info *
|
||||||
get_private_info_ptid (ptid_t ptid)
|
get_remote_thread_info (ptid_t ptid)
|
||||||
{
|
{
|
||||||
struct thread_info *info = find_thread_ptid (ptid);
|
struct thread_info *info = find_thread_ptid (ptid);
|
||||||
|
|
||||||
return get_private_info_thread (info);
|
return get_remote_thread_info (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call this function as a result of
|
/* Call this function as a result of
|
||||||
|
@ -2294,7 +2270,7 @@ static const char *
|
||||||
remote_thread_name (struct target_ops *ops, struct thread_info *info)
|
remote_thread_name (struct target_ops *ops, struct thread_info *info)
|
||||||
{
|
{
|
||||||
if (info->priv != NULL)
|
if (info->priv != NULL)
|
||||||
return info->priv->name;
|
return get_remote_thread_info (info)->name.c_str ();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2997,7 +2973,6 @@ struct thread_item
|
||||||
|
|
||||||
/* The thread handle associated with the thread. */
|
/* The thread handle associated with the thread. */
|
||||||
gdb::byte_vector thread_handle;
|
gdb::byte_vector thread_handle;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Context passed around to the various methods listing remote
|
/* Context passed around to the various methods listing remote
|
||||||
|
@ -3285,7 +3260,6 @@ remote_update_thread_list (struct target_ops *ops)
|
||||||
{
|
{
|
||||||
if (item.ptid != null_ptid)
|
if (item.ptid != null_ptid)
|
||||||
{
|
{
|
||||||
struct private_thread_info *info;
|
|
||||||
/* In non-stop mode, we assume new found threads are
|
/* In non-stop mode, we assume new found threads are
|
||||||
executing until proven otherwise with a stop reply.
|
executing until proven otherwise with a stop reply.
|
||||||
In all-stop, we can only get here if all threads are
|
In all-stop, we can only get here if all threads are
|
||||||
|
@ -3294,12 +3268,11 @@ remote_update_thread_list (struct target_ops *ops)
|
||||||
|
|
||||||
remote_notice_new_inferior (item.ptid, executing);
|
remote_notice_new_inferior (item.ptid, executing);
|
||||||
|
|
||||||
info = get_private_info_ptid (item.ptid);
|
remote_thread_info *info = get_remote_thread_info (item.ptid);
|
||||||
info->core = item.core;
|
info->core = item.core;
|
||||||
info->extra = xstrdup (item.extra.c_str ());
|
info->extra = std::move (item.extra);
|
||||||
info->name = xstrdup (item.name.c_str ());
|
info->name = std::move (item.name);
|
||||||
info->thread_handle
|
info->thread_handle = std::move (item.thread_handle);
|
||||||
= new gdb::byte_vector (std::move (item.thread_handle));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3348,8 +3321,8 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
|
||||||
{
|
{
|
||||||
struct thread_info *info = find_thread_ptid (tp->ptid);
|
struct thread_info *info = find_thread_ptid (tp->ptid);
|
||||||
|
|
||||||
if (info && info->priv)
|
if (info != NULL && info->priv != NULL)
|
||||||
return info->priv->extra;
|
return get_remote_thread_info (info)->extra.c_str ();
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3925,7 +3898,7 @@ process_initial_stop_replies (int from_tty)
|
||||||
|
|
||||||
set_executing (event_ptid, 0);
|
set_executing (event_ptid, 0);
|
||||||
set_running (event_ptid, 0);
|
set_running (event_ptid, 0);
|
||||||
thread->priv->vcont_resumed = 0;
|
get_remote_thread_info (thread)->vcont_resumed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "Notice" the new inferiors before anything related to
|
/* "Notice" the new inferiors before anything related to
|
||||||
|
@ -5549,8 +5522,10 @@ resume_clear_thread_private_info (struct thread_info *thread)
|
||||||
{
|
{
|
||||||
if (thread->priv != NULL)
|
if (thread->priv != NULL)
|
||||||
{
|
{
|
||||||
thread->priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
|
remote_thread_info *priv = get_remote_thread_info (thread);
|
||||||
thread->priv->watch_data_address = 0;
|
|
||||||
|
priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
|
||||||
|
priv->watch_data_address = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5730,12 +5705,13 @@ remote_resume (struct target_ops *ops,
|
||||||
to do vCont action coalescing. */
|
to do vCont action coalescing. */
|
||||||
if (target_is_non_stop_p () && execution_direction != EXEC_REVERSE)
|
if (target_is_non_stop_p () && execution_direction != EXEC_REVERSE)
|
||||||
{
|
{
|
||||||
struct private_thread_info *remote_thr;
|
remote_thread_info *remote_thr;
|
||||||
|
|
||||||
if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
|
if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
|
||||||
remote_thr = get_private_info_ptid (inferior_ptid);
|
remote_thr = get_remote_thread_info (inferior_ptid);
|
||||||
else
|
else
|
||||||
remote_thr = get_private_info_ptid (ptid);
|
remote_thr = get_remote_thread_info (ptid);
|
||||||
|
|
||||||
remote_thr->last_resume_step = step;
|
remote_thr->last_resume_step = step;
|
||||||
remote_thr->last_resume_sig = siggnal;
|
remote_thr->last_resume_sig = siggnal;
|
||||||
return;
|
return;
|
||||||
|
@ -6001,7 +5977,7 @@ remote_commit_resume (struct target_ops *ops)
|
||||||
/* Threads first. */
|
/* Threads first. */
|
||||||
ALL_NON_EXITED_THREADS (tp)
|
ALL_NON_EXITED_THREADS (tp)
|
||||||
{
|
{
|
||||||
struct private_thread_info *remote_thr = tp->priv;
|
remote_thread_info *remote_thr = get_remote_thread_info (tp);
|
||||||
|
|
||||||
if (!tp->executing || remote_thr->vcont_resumed)
|
if (!tp->executing || remote_thr->vcont_resumed)
|
||||||
continue;
|
continue;
|
||||||
|
@ -7218,8 +7194,6 @@ process_stop_reply (struct stop_reply *stop_reply,
|
||||||
&& status->kind != TARGET_WAITKIND_SIGNALLED
|
&& status->kind != TARGET_WAITKIND_SIGNALLED
|
||||||
&& status->kind != TARGET_WAITKIND_NO_RESUMED)
|
&& status->kind != TARGET_WAITKIND_NO_RESUMED)
|
||||||
{
|
{
|
||||||
struct private_thread_info *remote_thr;
|
|
||||||
|
|
||||||
/* Expedited registers. */
|
/* Expedited registers. */
|
||||||
if (stop_reply->regcache)
|
if (stop_reply->regcache)
|
||||||
{
|
{
|
||||||
|
@ -7240,7 +7214,7 @@ process_stop_reply (struct stop_reply *stop_reply,
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_notice_new_inferior (ptid, 0);
|
remote_notice_new_inferior (ptid, 0);
|
||||||
remote_thr = get_private_info_ptid (ptid);
|
remote_thread_info *remote_thr = get_remote_thread_info (ptid);
|
||||||
remote_thr->core = stop_reply->core;
|
remote_thr->core = stop_reply->core;
|
||||||
remote_thr->stop_reason = stop_reply->stop_reason;
|
remote_thr->stop_reason = stop_reply->stop_reason;
|
||||||
remote_thr->watch_data_address = stop_reply->watch_data_address;
|
remote_thr->watch_data_address = stop_reply->watch_data_address;
|
||||||
|
@ -10037,7 +10011,8 @@ remote_stopped_by_sw_breakpoint (struct target_ops *ops)
|
||||||
struct thread_info *thread = inferior_thread ();
|
struct thread_info *thread = inferior_thread ();
|
||||||
|
|
||||||
return (thread->priv != NULL
|
return (thread->priv != NULL
|
||||||
&& thread->priv->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT);
|
&& (get_remote_thread_info (thread)->stop_reason
|
||||||
|
== TARGET_STOPPED_BY_SW_BREAKPOINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The to_supports_stopped_by_sw_breakpoint method of target
|
/* The to_supports_stopped_by_sw_breakpoint method of target
|
||||||
|
@ -10057,7 +10032,8 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops)
|
||||||
struct thread_info *thread = inferior_thread ();
|
struct thread_info *thread = inferior_thread ();
|
||||||
|
|
||||||
return (thread->priv != NULL
|
return (thread->priv != NULL
|
||||||
&& thread->priv->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT);
|
&& (get_remote_thread_info (thread)->stop_reason
|
||||||
|
== TARGET_STOPPED_BY_HW_BREAKPOINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The to_supports_stopped_by_hw_breakpoint method of target
|
/* The to_supports_stopped_by_hw_breakpoint method of target
|
||||||
|
@ -10075,7 +10051,8 @@ remote_stopped_by_watchpoint (struct target_ops *ops)
|
||||||
struct thread_info *thread = inferior_thread ();
|
struct thread_info *thread = inferior_thread ();
|
||||||
|
|
||||||
return (thread->priv != NULL
|
return (thread->priv != NULL
|
||||||
&& thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT);
|
&& (get_remote_thread_info (thread)->stop_reason
|
||||||
|
== TARGET_STOPPED_BY_WATCHPOINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -10084,9 +10061,10 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
|
||||||
struct thread_info *thread = inferior_thread ();
|
struct thread_info *thread = inferior_thread ();
|
||||||
|
|
||||||
if (thread->priv != NULL
|
if (thread->priv != NULL
|
||||||
&& thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
|
&& (get_remote_thread_info (thread)->stop_reason
|
||||||
|
== TARGET_STOPPED_BY_WATCHPOINT))
|
||||||
{
|
{
|
||||||
*addr_p = thread->priv->watch_data_address;
|
*addr_p = get_remote_thread_info (thread)->watch_data_address;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12923,8 +12901,9 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
|
||||||
{
|
{
|
||||||
struct thread_info *info = find_thread_ptid (ptid);
|
struct thread_info *info = find_thread_ptid (ptid);
|
||||||
|
|
||||||
if (info && info->priv)
|
if (info != NULL && info->priv != NULL)
|
||||||
return info->priv->core;
|
return get_remote_thread_info (info)->core;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13521,14 +13500,14 @@ remote_thread_handle_to_thread_info (struct target_ops *ops,
|
||||||
|
|
||||||
ALL_NON_EXITED_THREADS (tp)
|
ALL_NON_EXITED_THREADS (tp)
|
||||||
{
|
{
|
||||||
struct private_thread_info *priv = get_private_info_thread (tp);
|
remote_thread_info *priv = get_remote_thread_info (tp);
|
||||||
|
|
||||||
if (tp->inf == inf && priv != NULL)
|
if (tp->inf == inf && priv != NULL)
|
||||||
{
|
{
|
||||||
if (handle_len != priv->thread_handle->size ())
|
if (handle_len != priv->thread_handle.size ())
|
||||||
error (_("Thread handle size mismatch: %d vs %zu (from remote)"),
|
error (_("Thread handle size mismatch: %d vs %zu (from remote)"),
|
||||||
handle_len, priv->thread_handle->size ());
|
handle_len, priv->thread_handle.size ());
|
||||||
if (memcmp (thread_handle, priv->thread_handle->data (),
|
if (memcmp (thread_handle, priv->thread_handle.data (),
|
||||||
handle_len) == 0)
|
handle_len) == 0)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
14
gdb/thread.c
14
gdb/thread.c
|
@ -316,11 +316,11 @@ add_thread_silent (ptid_t ptid)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread_info *
|
struct thread_info *
|
||||||
add_thread_with_info (ptid_t ptid, struct private_thread_info *priv)
|
add_thread_with_info (ptid_t ptid, private_thread_info *priv)
|
||||||
{
|
{
|
||||||
struct thread_info *result = add_thread_silent (ptid);
|
struct thread_info *result = add_thread_silent (ptid);
|
||||||
|
|
||||||
result->priv = priv;
|
result->priv.reset (priv);
|
||||||
|
|
||||||
if (print_thread_events)
|
if (print_thread_events)
|
||||||
printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
|
printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
|
||||||
|
@ -335,6 +335,8 @@ add_thread (ptid_t ptid)
|
||||||
return add_thread_with_info (ptid, NULL);
|
return add_thread_with_info (ptid, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private_thread_info::~private_thread_info () = default;
|
||||||
|
|
||||||
thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)
|
thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)
|
||||||
: ptid (ptid_), inf (inf_)
|
: ptid (ptid_), inf (inf_)
|
||||||
{
|
{
|
||||||
|
@ -351,14 +353,6 @@ thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)
|
||||||
|
|
||||||
thread_info::~thread_info ()
|
thread_info::~thread_info ()
|
||||||
{
|
{
|
||||||
if (this->priv)
|
|
||||||
{
|
|
||||||
if (this->private_dtor)
|
|
||||||
this->private_dtor (this->priv);
|
|
||||||
else
|
|
||||||
xfree (this->priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
xfree (this->name);
|
xfree (this->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue