• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisiónf6327dcbf0bc91bb9d99e12232d2b1a2f959fce6 (tree)
Tiempo2017-09-22 03:49:47
AutorKevin Buettner <kevinb@redh...>
CommiterKevin Buettner

Log Message

Add thread_handle_to_thread_info support for remote targets

This patch adds support to remote targets for converting a thread
handle to a thread_info struct pointer.

A thread handle is fetched via a "handle" attribute which has been
added to the qXfer:threads:read query packet. An implementation is
provided in gdbserver for targets using the Linux kernel.

gdb/gdbserver/ChangeLog:

* linux-low.h (struct lwp_info): Add new field, thread_handle.
(thread_db_thread_handle): Declare.
* linux-low.c (linux_target_ops): Initialize thread_handle.
* server.c (handle_qxfer_threads_worker): Add support for
"handle" attribute.
* target.h (struct target_ops): Add new function pointer,
thread_handle.
(target_thread_handle): Define.
* thread-db.c (find_one_thread, attach_thread): Set thread_handle
field in lwp.
(thread_db_thread_handle): New function.

gdb/ChangeLog:

* remote.c (vector): Include.
(struct private_thread_info): Add field, thread_handle.
(free_private_thread_info): Deallocate storage associated with
thread handle.
(get_private_info_thread): Initialize thread_handle' field.
(struct thread_item): Add field, thread_handle.
(clear_threads_listing_context): Deallocate storage associated
with thread handle.
(start_thread): Add support for "handle" attribute.
(thread_attributes): Add "handle".
(remote_get_threads_with_qthreadinfo): Initialize thread_handle
field.
(remote_update_thread_list): Update thread_handle.
(remote_thread_handle_to_thread_info): New function.
(init_remote_ops): Initialize to_thread_handle_to_thread_info.

Cambiar Resumen

Diferencia incremental

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,23 @@
11 2017-09-21 Kevin Buettner <kevinb@redhat.com>
22
3+ * remote.c (vector): Include.
4+ (struct private_thread_info): Add field, thread_handle.
5+ (free_private_thread_info): Deallocate storage associated with
6+ thread handle.
7+ (get_private_info_thread): Initialize `thread_handle' field.
8+ (struct thread_item): Add field, thread_handle.
9+ (clear_threads_listing_context): Deallocate storage associated
10+ with thread handle.
11+ (start_thread): Add support for "handle" attribute.
12+ (thread_attributes): Add "handle".
13+ (remote_get_threads_with_qthreadinfo): Initialize thread_handle
14+ field.
15+ (remote_update_thread_list): Update thread_handle.
16+ (remote_thread_handle_to_thread_info): New function.
17+ (init_remote_ops): Initialize to_thread_handle_to_thread_info.
18+
19+2017-09-21 Kevin Buettner <kevinb@redhat.com>
20+
321 * python/py-inferior.c (gdbpy_thread_from_thread_handle): New
422 function.
523 (inferior_object_methods): Add gdbpy_thread_from_thread_handle.
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,19 @@
11 2017-09-21 Kevin Buettner <kevinb@redhat.com>
22
3+ * linux-low.h (struct lwp_info): Add new field, thread_handle.
4+ (thread_db_thread_handle): Declare.
5+ * linux-low.c (linux_target_ops): Initialize thread_handle.
6+ * server.c (handle_qxfer_threads_worker): Add support for
7+ "handle" attribute.
8+ * target.h (struct target_ops): Add new function pointer,
9+ thread_handle.
10+ (target_thread_handle): Define.
11+ * thread-db.c (find_one_thread, attach_thread): Set thread_handle
12+ field in lwp.
13+ (thread_db_thread_handle): New function.
14+
15+2017-09-21 Kevin Buettner <kevinb@redhat.com>
16+
317 * linux-low.c (handle_extended_wait): Call thread_db_notice_clone().
418 * linux-low.h (thread_db_notice_clone): Declare.
519 * thread-db.c (thread_db_notice_clone): New function.
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -7705,6 +7705,11 @@ static struct target_ops linux_target_ops = {
77057705 linux_supports_software_single_step,
77067706 linux_supports_catch_syscall,
77077707 linux_get_ipa_tdesc_idx,
7708+#if USE_THREAD_DB
7709+ thread_db_thread_handle,
7710+#else
7711+ NULL,
7712+#endif
77087713 };
77097714
77107715 #ifdef HAVE_LINUX_REGSETS
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -374,6 +374,9 @@ struct lwp_info
374374 /* The thread handle, used for e.g. TLS access. Only valid if
375375 THREAD_KNOWN is set. */
376376 td_thrhandle_t th;
377+
378+ /* The pthread_t handle. */
379+ thread_t thread_handle;
377380 #endif
378381
379382 /* Arch-specific additions. */
@@ -416,4 +419,6 @@ int thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp);
416419
417420 void thread_db_notice_clone (struct process_info *proc, ptid_t lwp);
418421
422+bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len);
423+
419424 extern int have_ptrace_getregset;
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -1648,6 +1648,9 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
16481648 int core = target_core_of_thread (ptid);
16491649 char core_s[21];
16501650 const char *name = target_thread_name (ptid);
1651+ int handle_len;
1652+ gdb_byte *handle;
1653+ bool handle_status = target_thread_handle (ptid, &handle, &handle_len);
16511654
16521655 write_ptid (ptid_s, ptid);
16531656
@@ -1662,6 +1665,13 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
16621665 if (name != NULL)
16631666 buffer_xml_printf (buffer, " name=\"%s\"", name);
16641667
1668+ if (handle_status)
1669+ {
1670+ char *handle_s = (char *) alloca (handle_len * 2 + 1);
1671+ bin2hex (handle, handle_s, handle_len);
1672+ buffer_xml_printf (buffer, " handle=\"%s\"", handle_s);
1673+ }
1674+
16651675 buffer_xml_printf (buffer, "/>\n");
16661676 }
16671677
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -475,6 +475,11 @@ struct target_ops
475475
476476 /* Return tdesc index for IPA. */
477477 int (*get_ipa_tdesc_idx) (void);
478+
479+ /* Thread ID to (numeric) thread handle: Return true on success and
480+ false for failure. Return pointer to thread handle via HANDLE
481+ and the handle's length via HANDLE_LEN. */
482+ bool (*thread_handle) (ptid_t ptid, gdb_byte **handle, int *handle_len);
478483 };
479484
480485 extern struct target_ops *the_target;
@@ -693,6 +698,11 @@ void done_accessing_memory (void);
693698 (the_target->thread_name ? (*the_target->thread_name) (ptid) \
694699 : NULL)
695700
701+#define target_thread_handle(ptid, handle, handle_len) \
702+ (the_target->thread_handle ? (*the_target->thread_handle) \
703+ (ptid, handle, handle_len) \
704+ : false)
705+
696706 int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
697707
698708 int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -200,6 +200,7 @@ find_one_thread (ptid_t ptid)
200200
201201 lwp->thread_known = 1;
202202 lwp->th = th;
203+ lwp->thread_handle = ti.ti_tid;
203204
204205 return 1;
205206 }
@@ -231,6 +232,7 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
231232 gdb_assert (lwp != NULL);
232233 lwp->thread_known = 1;
233234 lwp->th = *th_p;
235+ lwp->thread_handle = ti_p->ti_tid;
234236
235237 return 1;
236238 }
@@ -439,6 +441,36 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
439441 return err;
440442 }
441443
444+/* See linux-low.h. */
445+
446+bool
447+thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len)
448+{
449+ struct thread_db *thread_db;
450+ struct lwp_info *lwp;
451+ struct thread_info *thread
452+ = (struct thread_info *) find_inferior_id (&all_threads, ptid);
453+
454+ if (thread == NULL)
455+ return false;
456+
457+ thread_db = get_thread_process (thread)->priv->thread_db;
458+
459+ if (thread_db == NULL)
460+ return false;
461+
462+ lwp = get_thread_lwp (thread);
463+
464+ if (!lwp->thread_known && !find_one_thread (thread->entry.id))
465+ return false;
466+
467+ gdb_assert (lwp->thread_known);
468+
469+ *handle = (gdb_byte *) &lwp->thread_handle;
470+ *handle_len = sizeof (lwp->thread_handle);
471+ return true;
472+}
473+
442474 #ifdef USE_LIBTHREAD_DB_DIRECTLY
443475
444476 static int
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -74,6 +74,7 @@
7474 #include <algorithm>
7575 #include "common/scoped_restore.h"
7676 #include "environ.h"
77+#include "common/byte-vector.h"
7778
7879 /* Temp hacks for tracepoint encoding migration. */
7980 static char *target_buf;
@@ -451,6 +452,10 @@ struct private_thread_info
451452 char *name;
452453 int core;
453454
455+ /* Thread handle, perhaps a pthread_t or thread_t value, stored as a
456+ sequence of bytes. */
457+ gdb::byte_vector *thread_handle;
458+
454459 /* Whether the target stopped for a breakpoint/watchpoint. */
455460 enum target_stop_reason stop_reason;
456461
@@ -482,6 +487,7 @@ free_private_thread_info (struct private_thread_info *info)
482487 {
483488 xfree (info->extra);
484489 xfree (info->name);
490+ delete info->thread_handle;
485491 xfree (info);
486492 }
487493
@@ -1971,6 +1977,7 @@ get_private_info_thread (struct thread_info *thread)
19711977 priv->last_resume_step = 0;
19721978 priv->last_resume_sig = GDB_SIGNAL_0;
19731979 priv->vcont_resumed = 0;
1980+ priv->thread_handle = nullptr;
19741981 }
19751982
19761983 return thread->priv;
@@ -2997,6 +3004,10 @@ typedef struct thread_item
29973004
29983005 /* The core the thread was running on. -1 if not known. */
29993006 int core;
3007+
3008+ /* The thread handle associated with the thread. */
3009+ gdb::byte_vector *thread_handle;
3010+
30003011 } thread_item_t;
30013012 DEF_VEC_O(thread_item_t);
30023013
@@ -3024,6 +3035,7 @@ clear_threads_listing_context (void *p)
30243035 {
30253036 xfree (item->extra);
30263037 xfree (item->name);
3038+ delete item->thread_handle;
30273039 }
30283040
30293041 VEC_free (thread_item_t, context->items);
@@ -3062,6 +3074,7 @@ remote_newthread_step (threadref *ref, void *data)
30623074 item.core = -1;
30633075 item.name = NULL;
30643076 item.extra = NULL;
3077+ item.thread_handle = nullptr;
30653078
30663079 VEC_safe_push (thread_item_t, context->items, &item);
30673080
@@ -3132,6 +3145,17 @@ start_thread (struct gdb_xml_parser *parser,
31323145 attr = xml_find_attribute (attributes, "name");
31333146 item.name = attr != NULL ? xstrdup ((const char *) attr->value) : NULL;
31343147
3148+ attr = xml_find_attribute (attributes, "handle");
3149+ if (attr != NULL)
3150+ {
3151+ item.thread_handle = new gdb::byte_vector
3152+ (strlen ((const char *) attr->value) / 2);
3153+ hex2bin ((const char *) attr->value, item.thread_handle->data (),
3154+ item.thread_handle->size ());
3155+ }
3156+ else
3157+ item.thread_handle = nullptr;
3158+
31353159 item.extra = 0;
31363160
31373161 VEC_safe_push (thread_item_t, data->items, &item);
@@ -3153,6 +3177,7 @@ const struct gdb_xml_attribute thread_attributes[] = {
31533177 { "id", GDB_XML_AF_NONE, NULL, NULL },
31543178 { "core", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
31553179 { "name", GDB_XML_AF_OPTIONAL, NULL, NULL },
3180+ { "handle", GDB_XML_AF_OPTIONAL, NULL, NULL },
31563181 { NULL, GDB_XML_AF_NONE, NULL, NULL }
31573182 };
31583183
@@ -3228,6 +3253,7 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
32283253 item.core = -1;
32293254 item.name = NULL;
32303255 item.extra = NULL;
3256+ item.thread_handle = nullptr;
32313257
32323258 VEC_safe_push (thread_item_t, context->items, &item);
32333259 }
@@ -3333,6 +3359,8 @@ remote_update_thread_list (struct target_ops *ops)
33333359 item->extra = NULL;
33343360 info->name = item->name;
33353361 item->name = NULL;
3362+ info->thread_handle = item->thread_handle;
3363+ item->thread_handle = nullptr;
33363364 }
33373365 }
33383366 }
@@ -13526,6 +13554,35 @@ remote_execution_direction (struct target_ops *self)
1352613554 return rs->last_resume_exec_dir;
1352713555 }
1352813556
13557+/* Return pointer to the thread_info struct which corresponds to
13558+ THREAD_HANDLE (having length HANDLE_LEN). */
13559+
13560+static struct thread_info *
13561+remote_thread_handle_to_thread_info (struct target_ops *ops,
13562+ const gdb_byte *thread_handle,
13563+ int handle_len,
13564+ struct inferior *inf)
13565+{
13566+ struct thread_info *tp;
13567+
13568+ ALL_NON_EXITED_THREADS (tp)
13569+ {
13570+ struct private_thread_info *priv = get_private_info_thread (tp);
13571+
13572+ if (tp->inf == inf && priv != NULL)
13573+ {
13574+ if (handle_len != priv->thread_handle->size ())
13575+ error (_("Thread handle size mismatch: %d vs %zu (from remote)"),
13576+ handle_len, priv->thread_handle->size ());
13577+ if (memcmp (thread_handle, priv->thread_handle->data (),
13578+ handle_len) == 0)
13579+ return tp;
13580+ }
13581+ }
13582+
13583+ return NULL;
13584+}
13585+
1352913586 static void
1353013587 init_remote_ops (void)
1353113588 {
@@ -13674,6 +13731,8 @@ Specify the serial device it is connected to\n\
1367413731 remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
1367513732 remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
1367613733 remote_ops.to_execution_direction = remote_execution_direction;
13734+ remote_ops.to_thread_handle_to_thread_info =
13735+ remote_thread_handle_to_thread_info;
1367713736 }
1367813737
1367913738 /* Set up the extended remote vector by making a copy of the standard