aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2017-11-24 10:40:31 -0500
committerSimon Marchi <simon.marchi@ericsson.com>2017-11-24 10:40:31 -0500
commit7aabaf9d4ad52a1df1f551908fbd8cafc5e7597a (patch)
tree236f4fa7e2efc5fce63f60afbe983e106e3a611d /gdb/remote.c
parent21fe1c752e254167d953fa8c846280f63a3a5290 (diff)
downloadgdb-7aabaf9d4ad52a1df1f551908fbd8cafc5e7597a.zip
gdb-7aabaf9d4ad52a1df1f551908fbd8cafc5e7597a.tar.gz
gdb-7aabaf9d4ad52a1df1f551908fbd8cafc5e7597a.tar.bz2
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.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c129
1 files changed, 54 insertions, 75 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 8c76b7e..0a62ae0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -439,23 +439,23 @@ struct remote_state
struct readahead_cache readahead_cache;
};
-/* Private data that we'll store in (struct thread_info)->private. */
-struct private_thread_info
+/* Private data that we'll store in (struct thread_info)->priv. */
+struct remote_thread_info : public private_thread_info
{
- char *extra;
- char *name;
- int core;
+ std::string extra;
+ std::string name;
+ int core = -1;
/* Thread handle, perhaps a pthread_t or thread_t value, stored as a
sequence of bytes. */
- gdb::byte_vector *thread_handle;
+ gdb::byte_vector thread_handle;
/* 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
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
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
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
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
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
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
@@ -1826,8 +1817,7 @@ remote_add_inferior (int fake_pid_p, int pid, int attached,
return inf;
}
-static struct private_thread_info *
- get_private_info_thread (struct thread_info *info);
+static remote_thread_info *get_remote_thread_info (thread_info *thread);
/* Add thread PTID to GDB's thread list. Tag it as executing/running
according to RUNNING. */
@@ -1849,7 +1839,7 @@ remote_add_thread (ptid_t ptid, int running, int executing)
else
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_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. */
-static struct private_thread_info *
-get_private_info_thread (struct thread_info *thread)
+static remote_thread_info *
+get_remote_thread_info (thread_info *thread)
{
gdb_assert (thread != NULL);
if (thread->priv == NULL)
- {
- struct private_thread_info *priv = XNEW (struct private_thread_info);
-
- thread->private_dtor = free_private_thread_info;
- 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;
- }
+ thread->priv.reset (new remote_thread_info);
- return thread->priv;
+ return static_cast<remote_thread_info *> (thread->priv.get ());
}
/* Return PTID's private thread data, creating it if necessary. */
-static struct private_thread_info *
-get_private_info_ptid (ptid_t ptid)
+static remote_thread_info *
+get_remote_thread_info (ptid_t 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
@@ -2294,7 +2270,7 @@ static const char *
remote_thread_name (struct target_ops *ops, struct thread_info *info)
{
if (info->priv != NULL)
- return info->priv->name;
+ return get_remote_thread_info (info)->name.c_str ();
return NULL;
}
@@ -2997,7 +2973,6 @@ struct thread_item
/* The thread handle associated with the thread. */
gdb::byte_vector thread_handle;
-
};
/* 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)
{
- struct private_thread_info *info;
/* In non-stop mode, we assume new found threads are
executing until proven otherwise with a stop reply.
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);
- info = get_private_info_ptid (item.ptid);
+ remote_thread_info *info = get_remote_thread_info (item.ptid);
info->core = item.core;
- info->extra = xstrdup (item.extra.c_str ());
- info->name = xstrdup (item.name.c_str ());
- info->thread_handle
- = new gdb::byte_vector (std::move (item.thread_handle));
+ info->extra = std::move (item.extra);
+ info->name = std::move (item.name);
+ info->thread_handle = 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);
- if (info && info->priv)
- return info->priv->extra;
+ if (info != NULL && info->priv != NULL)
+ return get_remote_thread_info (info)->extra.c_str ();
else
return NULL;
}
@@ -3925,7 +3898,7 @@ process_initial_stop_replies (int from_tty)
set_executing (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
@@ -5549,8 +5522,10 @@ resume_clear_thread_private_info (struct thread_info *thread)
{
if (thread->priv != NULL)
{
- thread->priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
- thread->priv->watch_data_address = 0;
+ remote_thread_info *priv = get_remote_thread_info (thread);
+
+ 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. */
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))
- remote_thr = get_private_info_ptid (inferior_ptid);
+ remote_thr = get_remote_thread_info (inferior_ptid);
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_sig = siggnal;
return;
@@ -6001,7 +5977,7 @@ remote_commit_resume (struct target_ops *ops)
/* Threads first. */
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)
continue;
@@ -7218,8 +7194,6 @@ process_stop_reply (struct stop_reply *stop_reply,
&& status->kind != TARGET_WAITKIND_SIGNALLED
&& status->kind != TARGET_WAITKIND_NO_RESUMED)
{
- struct private_thread_info *remote_thr;
-
/* Expedited registers. */
if (stop_reply->regcache)
{
@@ -7240,7 +7214,7 @@ process_stop_reply (struct stop_reply *stop_reply,
}
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->stop_reason = stop_reply->stop_reason;
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 ();
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
@@ -10057,7 +10032,8 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops)
struct thread_info *thread = inferior_thread ();
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
@@ -10075,7 +10051,8 @@ remote_stopped_by_watchpoint (struct target_ops *ops)
struct thread_info *thread = inferior_thread ();
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
@@ -10084,9 +10061,10 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
struct thread_info *thread = inferior_thread ();
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;
}
@@ -12923,8 +12901,9 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
{
struct thread_info *info = find_thread_ptid (ptid);
- if (info && info->priv)
- return info->priv->core;
+ if (info != NULL && info->priv != NULL)
+ return get_remote_thread_info (info)->core;
+
return -1;
}
@@ -13521,14 +13500,14 @@ remote_thread_handle_to_thread_info (struct target_ops *ops,
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 (handle_len != priv->thread_handle->size ())
+ if (handle_len != priv->thread_handle.size ())
error (_("Thread handle size mismatch: %d vs %zu (from remote)"),
- handle_len, priv->thread_handle->size ());
- if (memcmp (thread_handle, priv->thread_handle->data (),
+ handle_len, priv->thread_handle.size ());
+ if (memcmp (thread_handle, priv->thread_handle.data (),
handle_len) == 0)
return tp;
}