* [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
@ 2014-01-29 18:11 Doug Evans
2014-02-06 12:27 ` Pedro Alves
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Doug Evans @ 2014-01-29 18:11 UTC (permalink / raw)
To: gdb-patches
Hi.
This patch provides missing API routines where necessary,
and removes all references to list implementation details
outside of inferiors.c.
2014-01-28 Doug Evans <dje@google.com>
* dll.c (clear_dlls): Replace accessing list implemention details
with API function.
* gdbthread.h (get_first_thread): Declare.
* inferiors.c (for_each_inferior_with_data): New function.
(get_first_thread): New function.
(find_thread_ptid): Simplify.
(get_first_inferior): New function.
(clear_list): Delete.
(one_inferior_p): New function.
(clear_inferior_list): New function.
(clear_inferiors): Update.
* inferiors.h (for_each_inferior_with_data): Declare.
(clear_inferior_list): Declare.
(one_inferior_p): Declare.
(get_first_inferior): Declare.
* server.c (target_running): Replace accessing list implemention
details with API function.
(accumulate_file_name_length): New function.
(emit_dll_description): New function.
(handle_qxfer_libraries): Replace accessing list implemention
details with API function.
(handle_qxfer_threads_worker): New function.
(handle_qxfer_threads_proper): Replace accessing list implemention
details with API function.
(handle_query): Ditto.
(visit_actioned_threads_callback_ftype): New typedef.
(visit_actioned_threads_data): New struct.
(visit_actioned_threads): Rewrite to be find_inferior callback.
(resume): Call find_inferior.
(handle_status): Replace accessing list implemention
details with API function.
(process_serial_event): Replace accessing list implemention details
with API function.
* target.c (set_desired_inferior): Replace accessing list implemention
details with API function.
* tracepoint.c (same_process_p): New function.
(gdb_agent_about_to_close): Replace accessing list implemention
details with API function.
* win32-low.c (child_delete_thread): Replace accessing list
implemention details with API function.
(match_dll_by_basename): New function.
(dll_is_loaded_by_basename): New function.
(win32_ensure_ntdll_loaded): Replace accessing list implemention
details call to dll_is_loaded_by_basename.
diff --git a/gdb/gdbserver/dll.c b/gdb/gdbserver/dll.c
index be0e01f..52f997c 100644
--- a/gdb/gdbserver/dll.c
+++ b/gdb/gdbserver/dll.c
@@ -110,5 +110,5 @@ void
clear_dlls (void)
{
for_each_inferior (&all_dlls, free_one_dll);
- all_dlls.head = all_dlls.tail = NULL;
+ clear_inferior_list (&all_dlls);
}
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index 4c454a2..0eac5a4 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -76,6 +76,8 @@ extern struct inferior_list all_threads;
void remove_thread (struct thread_info *thread);
void add_thread (ptid_t ptid, void *target_data);
+struct thread_info *get_first_thread (void);
+
struct thread_info *find_thread_ptid (ptid_t ptid);
/* Get current thread ID (Linux task ID). */
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index e3d28ea..a090386 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -59,6 +59,24 @@ for_each_inferior (struct inferior_list *list,
}
}
+/* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
+
+void
+for_each_inferior_with_data (struct inferior_list *list,
+ void (*action) (struct inferior_list_entry *,
+ void *),
+ void *data)
+{
+ struct inferior_list_entry *cur = list->head, *next;
+
+ while (cur != NULL)
+ {
+ next = cur->next;
+ (*action) (cur, data);
+ cur = next;
+ }
+}
+
void
remove_inferior (struct inferior_list *list,
struct inferior_list_entry *entry)
@@ -111,20 +129,18 @@ thread_to_gdb_id (struct thread_info *thread)
return thread->entry.id;
}
+/* Wrapper around get_first_inferior to return a struct thread_info *. */
+
struct thread_info *
-find_thread_ptid (ptid_t ptid)
+get_first_thread (void)
{
- struct inferior_list_entry *inf = all_threads.head;
-
- while (inf != NULL)
- {
- struct thread_info *thread = get_thread (inf);
- if (ptid_equal (thread->entry.id, ptid))
- return thread;
- inf = inf->next;
- }
+ return (struct thread_info *) get_first_inferior ();
+}
- return NULL;
+struct thread_info *
+find_thread_ptid (ptid_t ptid)
+{
+ return (struct thread_info *) find_inferior_id (&all_threads, ptid);
}
ptid_t
@@ -153,6 +169,19 @@ remove_thread (struct thread_info *thread)
free_one_thread (&thread->entry);
}
+/* Return a pointer to the first inferior in the list, or NULL if there
+ isn't one.
+ This is for cases where the caller needs a thread, but doesn't care
+ which one. */
+
+struct inferior_list_entry *
+get_first_inferior (void)
+{
+ if (all_threads.head != NULL)
+ return all_threads.head;
+ return NULL;
+}
+
/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
returns non-zero. If no entry is found then return NULL. */
@@ -214,14 +243,28 @@ set_inferior_regcache_data (struct thread_info *inferior, void *data)
inferior->regcache_data = data;
}
-#define clear_list(LIST) \
- do { (LIST)->head = (LIST)->tail = NULL; } while (0)
+/* Return true if LIST has exactly one entry. */
+
+int
+one_inferior_p (struct inferior_list *list)
+{
+ return list->head != NULL && list->head == list->tail;
+}
+
+/* Reset head,tail of LIST, assuming all entries have already been freed. */
+
+void
+clear_inferior_list (struct inferior_list *list)
+{
+ list->head = NULL;
+ list->tail = NULL;
+}
void
clear_inferiors (void)
{
for_each_inferior (&all_threads, free_one_thread);
- clear_list (&all_threads);
+ clear_inferior_list (&all_threads);
clear_dlls ();
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index f02afdd..a503be6 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -86,10 +86,21 @@ void add_inferior_to_list (struct inferior_list *list,
void for_each_inferior (struct inferior_list *list,
void (*action) (struct inferior_list_entry *));
+void for_each_inferior_with_data
+ (struct inferior_list *list,
+ void (*action) (struct inferior_list_entry *, void *),
+ void *data);
+
+void clear_inferior_list (struct inferior_list *list);
+
+int one_inferior_p (struct inferior_list *list);
+
extern struct thread_info *current_inferior;
void remove_inferior (struct inferior_list *list,
struct inferior_list_entry *entry);
+struct inferior_list_entry *get_first_inferior (void);
+
struct process_info *add_process (int pid, int attached);
void remove_process (struct process_info *process);
struct process_info *find_process_pid (int pid);
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 2dc14e8..2190031 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -191,7 +191,7 @@ struct notif_server notif_stop =
static int
target_running (void)
{
- return all_threads.head != NULL;
+ return get_first_thread () != NULL;
}
static int
@@ -1135,6 +1135,48 @@ handle_qxfer_features (const char *annex,
return len;
}
+/* Worker routine for handle_qxfer_libraries.
+ Add to the length pointed to by ARG a conservative estimate of the
+ length needed to transmit the file name of INF. */
+
+static void
+accumulate_file_name_length (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *dll = (struct dll_info *) inf;
+ unsigned int *total_len = arg;
+
+ /* Over-estimate the necessary memory. Assume that every character
+ in the library name must be escaped. */
+ *total_len += 128 + 6 * strlen (dll->name);
+}
+
+/* Worker routine for handle_qxfer_libraries.
+ Emit the XML to describe the library in INF. */
+
+static void
+emit_dll_description (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *dll = (struct dll_info *) inf;
+ char **p_ptr = arg;
+ char *p = *p_ptr;
+ char *name;
+
+ strcpy (p, " <library name=\"");
+ p = p + strlen (p);
+ name = xml_escape_text (dll->name);
+ strcpy (p, name);
+ free (name);
+ p = p + strlen (p);
+ strcpy (p, "\"><segment address=\"");
+ p = p + strlen (p);
+ sprintf (p, "0x%lx", (long) dll->base_addr);
+ p = p + strlen (p);
+ strcpy (p, "\"/></library>\n");
+ p = p + strlen (p);
+
+ *p_ptr = p;
+}
+
/* Handle qXfer:libraries:read. */
static int
@@ -1144,7 +1186,6 @@ handle_qxfer_libraries (const char *annex,
{
unsigned int total_len;
char *document, *p;
- struct inferior_list_entry *dll_ptr;
if (writebuf != NULL)
return -2;
@@ -1152,11 +1193,9 @@ handle_qxfer_libraries (const char *annex,
if (annex[0] != '\0' || !target_running ())
return -1;
- /* Over-estimate the necessary memory. Assume that every character
- in the library name must be escaped. */
total_len = 64;
- for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
- total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
+ for_each_inferior_with_data (&all_dlls, accumulate_file_name_length,
+ &total_len);
document = malloc (total_len);
if (document == NULL)
@@ -1165,24 +1204,7 @@ handle_qxfer_libraries (const char *annex,
strcpy (document, "<library-list>\n");
p = document + strlen (document);
- for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
- {
- struct dll_info *dll = (struct dll_info *) dll_ptr;
- char *name;
-
- strcpy (p, " <library name=\"");
- p = p + strlen (p);
- name = xml_escape_text (dll->name);
- strcpy (p, name);
- free (name);
- p = p + strlen (p);
- strcpy (p, "\"><segment address=\"");
- p = p + strlen (p);
- sprintf (p, "0x%lx", (long) dll->base_addr);
- p = p + strlen (p);
- strcpy (p, "\"/></library>\n");
- p = p + strlen (p);
- }
+ for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
strcpy (p, "</library-list>\n");
@@ -1284,36 +1306,43 @@ handle_qxfer_statictrace (const char *annex,
return nbytes;
}
-/* Helper for handle_qxfer_threads. */
+/* Helper for handle_qxfer_threads_proper.
+ Emit the XML to describe the thread of INF. */
static void
-handle_qxfer_threads_proper (struct buffer *buffer)
+handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
{
- struct inferior_list_entry *thread;
+ struct thread_info *thread = (struct thread_info *) inf;
+ struct buffer *buffer = arg;
+ ptid_t ptid = thread_to_gdb_id (thread);
+ char ptid_s[100];
+ int core = target_core_of_thread (ptid);
+ char core_s[21];
- buffer_grow_str (buffer, "<threads>\n");
+ write_ptid (ptid_s, ptid);
- for (thread = all_threads.head; thread; thread = thread->next)
+ if (core != -1)
{
- ptid_t ptid = thread_to_gdb_id ((struct thread_info *)thread);
- char ptid_s[100];
- int core = target_core_of_thread (ptid);
- char core_s[21];
+ sprintf (core_s, "%d", core);
+ buffer_xml_printf (buffer, "<thread id=\"%s\" core=\"%s\"/>\n",
+ ptid_s, core_s);
+ }
+ else
+ {
+ buffer_xml_printf (buffer, "<thread id=\"%s\"/>\n",
+ ptid_s);
+ }
+}
- write_ptid (ptid_s, ptid);
+/* Helper for handle_qxfer_threads. */
- if (core != -1)
- {
- sprintf (core_s, "%d", core);
- buffer_xml_printf (buffer, "<thread id=\"%s\" core=\"%s\"/>\n",
- ptid_s, core_s);
- }
- else
- {
- buffer_xml_printf (buffer, "<thread id=\"%s\"/>\n",
- ptid_s);
- }
- }
+static void
+handle_qxfer_threads_proper (struct buffer *buffer)
+{
+ buffer_grow_str (buffer, "<threads>\n");
+
+ for_each_inferior_with_data (&all_threads, handle_qxfer_threads_worker,
+ buffer);
buffer_grow_str0 (buffer, "</threads>\n");
}
@@ -1701,7 +1730,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
gdb_id = general_thread;
else
{
- thread_ptr = all_threads.head;
+ thread_ptr = get_first_inferior ();
gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
}
@@ -1742,7 +1771,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
ptid_t gdb_id;
require_running (own_buf);
- thread_ptr = all_threads.head;
+ thread_ptr = get_first_inferior ();
*own_buf++ = 'm';
gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
@@ -2119,37 +2148,47 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
static void gdb_wants_all_threads_stopped (void);
static void resume (struct thread_resume *actions, size_t n);
+/* The callback that is passed to visit_actioned_threads. */
+typedef int (visit_actioned_threads_callback_ftype)
+ (const struct thread_resume *, struct thread_info *);
+
+/* Struct to pass data to visit_actioned_threads. */
+
+struct visit_actioned_threads_data
+{
+ const struct thread_resume *actions;
+ size_t num_actions;
+ visit_actioned_threads_callback_ftype *callback;
+};
+
/* Call CALLBACK for any thread to which ACTIONS applies to. Returns
true if CALLBACK returns true. Returns false if no matching thread
- is found or CALLBACK results false. */
+ is found or CALLBACK results false.
+ Note: This function is itself a callback for find_inferior. */
static int
-visit_actioned_threads (const struct thread_resume *actions,
- size_t num_actions,
- int (*callback) (const struct thread_resume *,
- struct thread_info *))
+visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
{
- struct inferior_list_entry *entry;
+ struct visit_actioned_threads_data *data = datap;
+ const struct thread_resume *actions = data->actions;
+ size_t num_actions = data->num_actions;
+ visit_actioned_threads_callback_ftype *callback = data->callback;
+ size_t i;
- for (entry = all_threads.head; entry != NULL; entry = entry->next)
+ for (i = 0; i < num_actions; i++)
{
- size_t i;
+ const struct thread_resume *action = &actions[i];
- for (i = 0; i < num_actions; i++)
+ if (ptid_equal (action->thread, minus_one_ptid)
+ || ptid_equal (action->thread, entry->id)
+ || ((ptid_get_pid (action->thread)
+ == ptid_get_pid (entry->id))
+ && ptid_get_lwp (action->thread) == -1))
{
- const struct thread_resume *action = &actions[i];
-
- if (ptid_equal (action->thread, minus_one_ptid)
- || ptid_equal (action->thread, entry->id)
- || ((ptid_get_pid (action->thread)
- == ptid_get_pid (entry->id))
- && ptid_get_lwp (action->thread) == -1))
- {
- struct thread_info *thread = (struct thread_info *) entry;
+ struct thread_info *thread = (struct thread_info *) entry;
- if ((*callback) (action, thread))
- return 1;
- }
+ if ((*callback) (action, thread))
+ return 1;
}
}
@@ -2307,7 +2346,12 @@ resume (struct thread_resume *actions, size_t num_actions)
one with a pending status to report. If so, skip actually
resuming/stopping and report the pending event
immediately. */
- if (visit_actioned_threads (actions, num_actions, handle_pending_status))
+ struct visit_actioned_threads_data data;
+
+ data.actions = actions;
+ data.num_actions = num_actions;
+ data.callback = handle_pending_status;
+ if (find_inferior (&all_threads, visit_actioned_threads, &data) != NULL)
return;
enable_async_io ();
@@ -2780,7 +2824,7 @@ handle_status (char *own_buf)
/* If we're still out of luck, simply pick the first thread in
the thread list. */
if (thread == NULL)
- thread = all_threads.head;
+ thread = get_first_inferior ();
if (thread != NULL)
{
@@ -3539,7 +3583,10 @@ process_serial_event (void)
(struct thread_info *) find_inferior_id (&all_threads,
general_thread);
if (thread == NULL)
- thread_id = all_threads.head->id;
+ {
+ thread = get_first_thread ();
+ thread_id = thread->entry.id;
+ }
}
general_thread = thread_id;
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index e148f33..dcad5c9 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -34,7 +34,7 @@ set_desired_inferior (int use_general)
found = find_thread_ptid (cont_thread);
if (found == NULL)
- current_inferior = (struct thread_info *) all_threads.head;
+ current_inferior = get_first_thread ();
else
current_inferior = found;
}
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 3706577..ffbfcff 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -3942,6 +3942,17 @@ cmd_qtstmat (char *packet)
run_inferior_command (packet, strlen (packet) + 1);
}
+/* Helper for gdb_agent_about_to_close.
+ Return non-zero if thread ENTRY is in the same process in DATA. */
+
+static int
+same_process_p (struct inferior_list_entry *inf, void *data)
+{
+ int *pid = data;
+
+ return ptid_get_pid (inf->id) == *pid;
+}
+
/* Sent the agent a command to close it. */
void
@@ -3952,19 +3963,12 @@ gdb_agent_about_to_close (int pid)
if (!maybe_write_ipa_not_loaded (buf))
{
struct thread_info *save_inferior;
- struct inferior_list_entry *inf = all_threads.head;
save_inferior = current_inferior;
- /* Find a certain thread which belongs to process PID. */
- while (inf != NULL)
- {
- if (ptid_get_pid (inf->id) == pid)
- break;
- inf = inf->next;
- }
-
- current_inferior = (struct thread_info *) inf;
+ /* Find any thread which belongs to process PID. */
+ current_inferior = (struct thread_info *)
+ find_inferior (&all_threads, same_process_p, &pid);
strcpy (buf, "close");
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index f2620a5..e84306d 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -232,7 +232,7 @@ child_delete_thread (DWORD pid, DWORD tid)
ptid_t ptid;
/* If the last thread is exiting, just return. */
- if (all_threads.head == all_threads.tail)
+ if (one_inferior_p (&all_threads))
return;
ptid = ptid_build (pid, tid, 0);
@@ -1142,6 +1142,28 @@ failed:
}
#ifndef _WIN32_WCE
+
+/* Helper routine for dll_is_loaded_by_basename.
+ Return non-zero if the basename in ARG matches the DLL in INF. */
+
+static int
+match_dll_by_basename (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *iter = (void *) inf;
+ const char *basename = arg;
+
+ return strcasecmp (lbasename (iter->name), basename) == 0;
+}
+
+/* Return non-zero if the DLL specified by BASENAME is loaded. */
+
+static int
+dll_is_loaded_by_basename (const char *basename)
+{
+ return find_inferior (&all_dlls, match_dll_by_basename,
+ (void *) basename) != NULL;
+}
+
/* On certain versions of Windows, the information about ntdll.dll
is not available yet at the time we get the LOAD_DLL_DEBUG_EVENT,
thus preventing us from reporting this DLL as an SO. This has been
@@ -1158,20 +1180,14 @@ failed:
static void
win32_ensure_ntdll_loaded (void)
{
- struct inferior_list_entry *dll_e;
size_t i;
HMODULE dh_buf[1];
HMODULE *DllHandle = dh_buf;
DWORD cbNeeded;
BOOL ok;
- for (dll_e = all_dlls.head; dll_e != NULL; dll_e = dll_e->next)
- {
- struct dll_info *dll = (struct dll_info *) dll_e;
-
- if (strcasecmp (lbasename (dll->name), "ntdll.dll") == 0)
- return;
- }
+ if (dll_is_loaded_by_basename ("ntdll.dll"))
+ return;
if (!load_psapi ())
return;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-01-29 18:11 [PATCH v2 2/3] remove all_lwps from gdbserver: use list api Doug Evans
@ 2014-02-06 12:27 ` Pedro Alves
2014-02-19 23:31 ` Doug Evans
2014-02-20 21:18 ` Doug Evans
2014-02-20 21:19 ` Doug Evans
2 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2014-02-06 12:27 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
On 01/29/2014 06:11 PM, Doug Evans wrote:
> +/* Return a pointer to the first inferior in the list, or NULL if there
> + isn't one.
> + This is for cases where the caller needs a thread, but doesn't care
> + which one. */
> +
> +struct inferior_list_entry *
> +get_first_inferior (void)
> +{
> + if (all_threads.head != NULL)
> + return all_threads.head;
I think this one, being an "inferior" function, should take
a list as argument.
> + return NULL;
> +}
> +
> +/* Helper for gdb_agent_about_to_close.
> + Return non-zero if thread ENTRY is in the same process in DATA. */
> +
> +static int
> +same_process_p (struct inferior_list_entry *inf, void *data)
Mismatch between comment and parameter (ENTRY vs inf).
Otherwise looks good to me.
(Note: I noticed that patch 3 had a hunk that should be here:
if (!non_stop)
{
- current_inferior = (struct thread_info *) all_threads.head;
+ current_inferior = get_first_thread ();
)
--
Pedro Alves
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-02-06 12:27 ` Pedro Alves
@ 2014-02-19 23:31 ` Doug Evans
2014-02-20 13:40 ` Pedro Alves
0 siblings, 1 reply; 8+ messages in thread
From: Doug Evans @ 2014-02-19 23:31 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On Thu, Feb 6, 2014 at 4:27 AM, Pedro Alves <palves@redhat.com> wrote:
> On 01/29/2014 06:11 PM, Doug Evans wrote:
>
>> +/* Return a pointer to the first inferior in the list, or NULL if there
>> + isn't one.
>> + This is for cases where the caller needs a thread, but doesn't care
>> + which one. */
>> +
>> +struct inferior_list_entry *
>> +get_first_inferior (void)
>> +{
>> + if (all_threads.head != NULL)
>> + return all_threads.head;
>
> I think this one, being an "inferior" function, should take
> a list as argument.
>
>> + return NULL;
>> +}
>> +
>
>> +/* Helper for gdb_agent_about_to_close.
>> + Return non-zero if thread ENTRY is in the same process in DATA. */
>> +
>> +static int
>> +same_process_p (struct inferior_list_entry *inf, void *data)
>
> Mismatch between comment and parameter (ENTRY vs inf).
>
> Otherwise looks good to me.
>
> (Note: I noticed that patch 3 had a hunk that should be here:
>
> if (!non_stop)
> {
> - current_inferior = (struct thread_info *) all_threads.head;
> + current_inferior = get_first_thread ();
> )
Committed with the suggested changes.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-02-19 23:31 ` Doug Evans
@ 2014-02-20 13:40 ` Pedro Alves
2014-02-20 18:18 ` Doug Evans
0 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2014-02-20 13:40 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
On 02/19/2014 11:31 PM, Doug Evans wrote:
> On Thu, Feb 6, 2014 at 4:27 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 01/29/2014 06:11 PM, Doug Evans wrote:
> Committed with the suggested changes.
>
Thanks!
(Note that we request contributors to always post what goes into
the tree, if there were changes since the last post / approval,
so I think we should get into the habit of doing that ourselves too.)
>>> +struct inferior_list_entry *
>>> +get_first_inferior (void)
>>> +{
>>> + if (all_threads.head != NULL)
>>> + return all_threads.head;
>>
>> I think this one, being an "inferior" function, should take
>> a list as argument.
I noticed a little buglet slipped here:
+/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
+ This is for cases where the caller needs a thread, but doesn't care
+ which one. */
+
+struct inferior_list_entry *
+get_first_inferior (struct inferior_list *list)
+{
+ if (all_threads.head != NULL)
+ return all_threads.head;
Should be:
if (list->head != NULL)
return list->head;
Thanks again for doing this.
--
Pedro Alves
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-02-20 13:40 ` Pedro Alves
@ 2014-02-20 18:18 ` Doug Evans
2014-02-20 18:27 ` Pedro Alves
0 siblings, 1 reply; 8+ messages in thread
From: Doug Evans @ 2014-02-20 18:18 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
On Thu, Feb 20, 2014 at 5:40 AM, Pedro Alves <palves@redhat.com> wrote:
> On 02/19/2014 11:31 PM, Doug Evans wrote:
>> On Thu, Feb 6, 2014 at 4:27 AM, Pedro Alves <palves@redhat.com> wrote:
>>> On 01/29/2014 06:11 PM, Doug Evans wrote:
>
>> Committed with the suggested changes.
>>
>
> Thanks!
>
> (Note that we request contributors to always post what goes into
> the tree, if there were changes since the last post / approval,
> so I think we should get into the habit of doing that ourselves too.)
That's the plan ....
It was getting late and I had a few more things to do.
If there is a < 24(?) hour deadline for such things we'd better write
it down ....
>
>>>> +struct inferior_list_entry *
>>>> +get_first_inferior (void)
>>>> +{
>>>> + if (all_threads.head != NULL)
>>>> + return all_threads.head;
>>>
>>> I think this one, being an "inferior" function, should take
>>> a list as argument.
>
> I noticed a little buglet slipped here:
>
> +/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
> + This is for cases where the caller needs a thread, but doesn't care
> + which one. */
> +
> +struct inferior_list_entry *
> +get_first_inferior (struct inferior_list *list)
> +{
> + if (all_threads.head != NULL)
> + return all_threads.head;
>
> Should be:
>
> if (list->head != NULL)
> return list->head;
Bleah.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-02-20 18:18 ` Doug Evans
@ 2014-02-20 18:27 ` Pedro Alves
0 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2014-02-20 18:27 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
On 02/20/2014 06:18 PM, Doug Evans wrote:
> That's the plan ....
> It was getting late and I had a few more things to do.
Understandable. No harm done. ;-)
Thanks,
--
Pedro Alves
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-01-29 18:11 [PATCH v2 2/3] remove all_lwps from gdbserver: use list api Doug Evans
2014-02-06 12:27 ` Pedro Alves
@ 2014-02-20 21:18 ` Doug Evans
2014-02-20 21:19 ` Doug Evans
2 siblings, 0 replies; 8+ messages in thread
From: Doug Evans @ 2014-02-20 21:18 UTC (permalink / raw)
To: gdb-patches
Doug Evans writes:
> Hi.
> This patch provides missing API routines where necessary,
> and removes all references to list implementation details
> outside of inferiors.c.
Here is what I checked in.
2014-02-19 Doug Evans <dje@google.com>
* dll.c (clear_dlls): Replace accessing list implemention details
with API function.
* gdbthread.h (get_first_thread): Declare.
* inferiors.c (for_each_inferior_with_data): New function.
(get_first_thread): New function.
(find_thread_ptid): Simplify.
(get_first_inferior): New function.
(clear_list): Delete.
(one_inferior_p): New function.
(clear_inferior_list): New function.
(clear_inferiors): Update.
* inferiors.h (for_each_inferior_with_data): Declare.
(clear_inferior_list): Declare.
(one_inferior_p): Declare.
(get_first_inferior): Declare.
* linux-low.c (linux_wait_for_event): Replace accessing list
implemention details with API function.
* server.c (target_running): Ditto.
(accumulate_file_name_length): New function.
(emit_dll_description): New function.
(handle_qxfer_libraries): Replace accessing list implemention
details with API function.
(handle_qxfer_threads_worker): New function.
(handle_qxfer_threads_proper): Replace accessing list implemention
details with API function.
(handle_query): Ditto.
(visit_actioned_threads_callback_ftype): New typedef.
(visit_actioned_threads_data): New struct.
(visit_actioned_threads): Rewrite to be find_inferior callback.
(resume): Call find_inferior.
(handle_status): Replace accessing list implemention
details with API function.
(process_serial_event): Replace accessing list implemention details
with API function.
* target.c (set_desired_inferior): Replace accessing list implemention
details with API function.
* tracepoint.c (same_process_p): New function.
(gdb_agent_about_to_close): Replace accessing list implemention
details with API function.
* win32-low.c (child_delete_thread): Replace accessing list
implemention details with API function.
(match_dll_by_basename): New function.
(dll_is_loaded_by_basename): New function.
(win32_ensure_ntdll_loaded): Replace accessing list implemention
details call to dll_is_loaded_by_basename.
diff --git a/gdb/gdbserver/dll.c b/gdb/gdbserver/dll.c
index be0e01f..52f997c 100644
--- a/gdb/gdbserver/dll.c
+++ b/gdb/gdbserver/dll.c
@@ -110,5 +110,5 @@ void
clear_dlls (void)
{
for_each_inferior (&all_dlls, free_one_dll);
- all_dlls.head = all_dlls.tail = NULL;
+ clear_inferior_list (&all_dlls);
}
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index 4c454a2..0eac5a4 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -76,6 +76,8 @@ extern struct inferior_list all_threads;
void remove_thread (struct thread_info *thread);
void add_thread (ptid_t ptid, void *target_data);
+struct thread_info *get_first_thread (void);
+
struct thread_info *find_thread_ptid (ptid_t ptid);
/* Get current thread ID (Linux task ID). */
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index e3d28ea..c709b36 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -59,6 +59,24 @@ for_each_inferior (struct inferior_list *list,
}
}
+/* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
+
+void
+for_each_inferior_with_data (struct inferior_list *list,
+ void (*action) (struct inferior_list_entry *,
+ void *),
+ void *data)
+{
+ struct inferior_list_entry *cur = list->head, *next;
+
+ while (cur != NULL)
+ {
+ next = cur->next;
+ (*action) (cur, data);
+ cur = next;
+ }
+}
+
void
remove_inferior (struct inferior_list *list,
struct inferior_list_entry *entry)
@@ -111,20 +129,18 @@ thread_to_gdb_id (struct thread_info *thread)
return thread->entry.id;
}
+/* Wrapper around get_first_inferior to return a struct thread_info *. */
+
struct thread_info *
-find_thread_ptid (ptid_t ptid)
+get_first_thread (void)
{
- struct inferior_list_entry *inf = all_threads.head;
-
- while (inf != NULL)
- {
- struct thread_info *thread = get_thread (inf);
- if (ptid_equal (thread->entry.id, ptid))
- return thread;
- inf = inf->next;
- }
+ return (struct thread_info *) get_first_inferior (&all_threads);
+}
- return NULL;
+struct thread_info *
+find_thread_ptid (ptid_t ptid)
+{
+ return (struct thread_info *) find_inferior_id (&all_threads, ptid);
}
ptid_t
@@ -153,6 +169,18 @@ remove_thread (struct thread_info *thread)
free_one_thread (&thread->entry);
}
+/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
+ This is for cases where the caller needs a thread, but doesn't care
+ which one. */
+
+struct inferior_list_entry *
+get_first_inferior (struct inferior_list *list)
+{
+ if (all_threads.head != NULL)
+ return all_threads.head;
+ return NULL;
+}
+
/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
returns non-zero. If no entry is found then return NULL. */
@@ -214,14 +242,28 @@ set_inferior_regcache_data (struct thread_info *inferior, void *data)
inferior->regcache_data = data;
}
-#define clear_list(LIST) \
- do { (LIST)->head = (LIST)->tail = NULL; } while (0)
+/* Return true if LIST has exactly one entry. */
+
+int
+one_inferior_p (struct inferior_list *list)
+{
+ return list->head != NULL && list->head == list->tail;
+}
+
+/* Reset head,tail of LIST, assuming all entries have already been freed. */
+
+void
+clear_inferior_list (struct inferior_list *list)
+{
+ list->head = NULL;
+ list->tail = NULL;
+}
void
clear_inferiors (void)
{
for_each_inferior (&all_threads, free_one_thread);
- clear_list (&all_threads);
+ clear_inferior_list (&all_threads);
clear_dlls ();
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index f02afdd..8601b7e 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -86,10 +86,21 @@ void add_inferior_to_list (struct inferior_list *list,
void for_each_inferior (struct inferior_list *list,
void (*action) (struct inferior_list_entry *));
+void for_each_inferior_with_data
+ (struct inferior_list *list,
+ void (*action) (struct inferior_list_entry *, void *),
+ void *data);
+
+void clear_inferior_list (struct inferior_list *list);
+
+int one_inferior_p (struct inferior_list *list);
+
extern struct thread_info *current_inferior;
void remove_inferior (struct inferior_list *list,
struct inferior_list_entry *entry);
+struct inferior_list_entry *get_first_inferior (struct inferior_list *list);
+
struct process_info *add_process (int pid, int attached);
void remove_process (struct process_info *process);
struct process_info *find_process_pid (int pid);
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 011ee58..2a83022 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -1872,7 +1872,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
if (!non_stop)
{
- current_inferior = (struct thread_info *) all_threads.head;
+ current_inferior = get_first_thread ();
if (debug_threads)
debug_printf ("Current inferior is now %ld\n",
lwpid_of (get_thread_lwp (current_inferior)));
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 94a72f7..115aca4 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -192,7 +192,7 @@ struct notif_server notif_stop =
static int
target_running (void)
{
- return all_threads.head != NULL;
+ return get_first_thread () != NULL;
}
static int
@@ -1136,6 +1136,48 @@ handle_qxfer_features (const char *annex,
return len;
}
+/* Worker routine for handle_qxfer_libraries.
+ Add to the length pointed to by ARG a conservative estimate of the
+ length needed to transmit the file name of INF. */
+
+static void
+accumulate_file_name_length (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *dll = (struct dll_info *) inf;
+ unsigned int *total_len = arg;
+
+ /* Over-estimate the necessary memory. Assume that every character
+ in the library name must be escaped. */
+ *total_len += 128 + 6 * strlen (dll->name);
+}
+
+/* Worker routine for handle_qxfer_libraries.
+ Emit the XML to describe the library in INF. */
+
+static void
+emit_dll_description (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *dll = (struct dll_info *) inf;
+ char **p_ptr = arg;
+ char *p = *p_ptr;
+ char *name;
+
+ strcpy (p, " <library name=\"");
+ p = p + strlen (p);
+ name = xml_escape_text (dll->name);
+ strcpy (p, name);
+ free (name);
+ p = p + strlen (p);
+ strcpy (p, "\"><segment address=\"");
+ p = p + strlen (p);
+ sprintf (p, "0x%lx", (long) dll->base_addr);
+ p = p + strlen (p);
+ strcpy (p, "\"/></library>\n");
+ p = p + strlen (p);
+
+ *p_ptr = p;
+}
+
/* Handle qXfer:libraries:read. */
static int
@@ -1145,7 +1187,6 @@ handle_qxfer_libraries (const char *annex,
{
unsigned int total_len;
char *document, *p;
- struct inferior_list_entry *dll_ptr;
if (writebuf != NULL)
return -2;
@@ -1153,11 +1194,9 @@ handle_qxfer_libraries (const char *annex,
if (annex[0] != '\0' || !target_running ())
return -1;
- /* Over-estimate the necessary memory. Assume that every character
- in the library name must be escaped. */
total_len = 64;
- for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
- total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
+ for_each_inferior_with_data (&all_dlls, accumulate_file_name_length,
+ &total_len);
document = malloc (total_len);
if (document == NULL)
@@ -1166,24 +1205,7 @@ handle_qxfer_libraries (const char *annex,
strcpy (document, "<library-list>\n");
p = document + strlen (document);
- for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
- {
- struct dll_info *dll = (struct dll_info *) dll_ptr;
- char *name;
-
- strcpy (p, " <library name=\"");
- p = p + strlen (p);
- name = xml_escape_text (dll->name);
- strcpy (p, name);
- free (name);
- p = p + strlen (p);
- strcpy (p, "\"><segment address=\"");
- p = p + strlen (p);
- sprintf (p, "0x%lx", (long) dll->base_addr);
- p = p + strlen (p);
- strcpy (p, "\"/></library>\n");
- p = p + strlen (p);
- }
+ for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
strcpy (p, "</library-list>\n");
@@ -1285,36 +1307,43 @@ handle_qxfer_statictrace (const char *annex,
return nbytes;
}
-/* Helper for handle_qxfer_threads. */
+/* Helper for handle_qxfer_threads_proper.
+ Emit the XML to describe the thread of INF. */
static void
-handle_qxfer_threads_proper (struct buffer *buffer)
+handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
{
- struct inferior_list_entry *thread;
+ struct thread_info *thread = (struct thread_info *) inf;
+ struct buffer *buffer = arg;
+ ptid_t ptid = thread_to_gdb_id (thread);
+ char ptid_s[100];
+ int core = target_core_of_thread (ptid);
+ char core_s[21];
- buffer_grow_str (buffer, "<threads>\n");
+ write_ptid (ptid_s, ptid);
- for (thread = all_threads.head; thread; thread = thread->next)
+ if (core != -1)
{
- ptid_t ptid = thread_to_gdb_id ((struct thread_info *)thread);
- char ptid_s[100];
- int core = target_core_of_thread (ptid);
- char core_s[21];
+ sprintf (core_s, "%d", core);
+ buffer_xml_printf (buffer, "<thread id=\"%s\" core=\"%s\"/>\n",
+ ptid_s, core_s);
+ }
+ else
+ {
+ buffer_xml_printf (buffer, "<thread id=\"%s\"/>\n",
+ ptid_s);
+ }
+}
- write_ptid (ptid_s, ptid);
+/* Helper for handle_qxfer_threads. */
- if (core != -1)
- {
- sprintf (core_s, "%d", core);
- buffer_xml_printf (buffer, "<thread id=\"%s\" core=\"%s\"/>\n",
- ptid_s, core_s);
- }
- else
- {
- buffer_xml_printf (buffer, "<thread id=\"%s\"/>\n",
- ptid_s);
- }
- }
+static void
+handle_qxfer_threads_proper (struct buffer *buffer)
+{
+ buffer_grow_str (buffer, "<threads>\n");
+
+ for_each_inferior_with_data (&all_threads, handle_qxfer_threads_worker,
+ buffer);
buffer_grow_str0 (buffer, "</threads>\n");
}
@@ -1702,7 +1731,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
gdb_id = general_thread;
else
{
- thread_ptr = all_threads.head;
+ thread_ptr = get_first_inferior (&all_threads);
gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
}
@@ -1743,7 +1772,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
ptid_t gdb_id;
require_running (own_buf);
- thread_ptr = all_threads.head;
+ thread_ptr = get_first_inferior (&all_threads);
*own_buf++ = 'm';
gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
@@ -2121,37 +2150,47 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
static void gdb_wants_all_threads_stopped (void);
static void resume (struct thread_resume *actions, size_t n);
+/* The callback that is passed to visit_actioned_threads. */
+typedef int (visit_actioned_threads_callback_ftype)
+ (const struct thread_resume *, struct thread_info *);
+
+/* Struct to pass data to visit_actioned_threads. */
+
+struct visit_actioned_threads_data
+{
+ const struct thread_resume *actions;
+ size_t num_actions;
+ visit_actioned_threads_callback_ftype *callback;
+};
+
/* Call CALLBACK for any thread to which ACTIONS applies to. Returns
true if CALLBACK returns true. Returns false if no matching thread
- is found or CALLBACK results false. */
+ is found or CALLBACK results false.
+ Note: This function is itself a callback for find_inferior. */
static int
-visit_actioned_threads (const struct thread_resume *actions,
- size_t num_actions,
- int (*callback) (const struct thread_resume *,
- struct thread_info *))
+visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
{
- struct inferior_list_entry *entry;
+ struct visit_actioned_threads_data *data = datap;
+ const struct thread_resume *actions = data->actions;
+ size_t num_actions = data->num_actions;
+ visit_actioned_threads_callback_ftype *callback = data->callback;
+ size_t i;
- for (entry = all_threads.head; entry != NULL; entry = entry->next)
+ for (i = 0; i < num_actions; i++)
{
- size_t i;
+ const struct thread_resume *action = &actions[i];
- for (i = 0; i < num_actions; i++)
+ if (ptid_equal (action->thread, minus_one_ptid)
+ || ptid_equal (action->thread, entry->id)
+ || ((ptid_get_pid (action->thread)
+ == ptid_get_pid (entry->id))
+ && ptid_get_lwp (action->thread) == -1))
{
- const struct thread_resume *action = &actions[i];
-
- if (ptid_equal (action->thread, minus_one_ptid)
- || ptid_equal (action->thread, entry->id)
- || ((ptid_get_pid (action->thread)
- == ptid_get_pid (entry->id))
- && ptid_get_lwp (action->thread) == -1))
- {
- struct thread_info *thread = (struct thread_info *) entry;
+ struct thread_info *thread = (struct thread_info *) entry;
- if ((*callback) (action, thread))
- return 1;
- }
+ if ((*callback) (action, thread))
+ return 1;
}
}
@@ -2309,7 +2348,12 @@ resume (struct thread_resume *actions, size_t num_actions)
one with a pending status to report. If so, skip actually
resuming/stopping and report the pending event
immediately. */
- if (visit_actioned_threads (actions, num_actions, handle_pending_status))
+ struct visit_actioned_threads_data data;
+
+ data.actions = actions;
+ data.num_actions = num_actions;
+ data.callback = handle_pending_status;
+ if (find_inferior (&all_threads, visit_actioned_threads, &data) != NULL)
return;
enable_async_io ();
@@ -2782,7 +2826,7 @@ handle_status (char *own_buf)
/* If we're still out of luck, simply pick the first thread in
the thread list. */
if (thread == NULL)
- thread = all_threads.head;
+ thread = get_first_inferior (&all_threads);
if (thread != NULL)
{
@@ -3541,7 +3585,10 @@ process_serial_event (void)
(struct thread_info *) find_inferior_id (&all_threads,
general_thread);
if (thread == NULL)
- thread_id = all_threads.head->id;
+ {
+ thread = get_first_thread ();
+ thread_id = thread->entry.id;
+ }
}
general_thread = thread_id;
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index e148f33..dcad5c9 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -34,7 +34,7 @@ set_desired_inferior (int use_general)
found = find_thread_ptid (cont_thread);
if (found == NULL)
- current_inferior = (struct thread_info *) all_threads.head;
+ current_inferior = get_first_thread ();
else
current_inferior = found;
}
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 8e294f6..7c4b291 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -3943,6 +3943,17 @@ cmd_qtstmat (char *packet)
run_inferior_command (packet, strlen (packet) + 1);
}
+/* Helper for gdb_agent_about_to_close.
+ Return non-zero if thread ENTRY is in the same process in DATA. */
+
+static int
+same_process_p (struct inferior_list_entry *entry, void *data)
+{
+ int *pid = data;
+
+ return ptid_get_pid (entry->id) == *pid;
+}
+
/* Sent the agent a command to close it. */
void
@@ -3953,19 +3964,12 @@ gdb_agent_about_to_close (int pid)
if (!maybe_write_ipa_not_loaded (buf))
{
struct thread_info *save_inferior;
- struct inferior_list_entry *inf = all_threads.head;
save_inferior = current_inferior;
- /* Find a certain thread which belongs to process PID. */
- while (inf != NULL)
- {
- if (ptid_get_pid (inf->id) == pid)
- break;
- inf = inf->next;
- }
-
- current_inferior = (struct thread_info *) inf;
+ /* Find any thread which belongs to process PID. */
+ current_inferior = (struct thread_info *)
+ find_inferior (&all_threads, same_process_p, &pid);
strcpy (buf, "close");
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index f2620a5..e84306d 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -232,7 +232,7 @@ child_delete_thread (DWORD pid, DWORD tid)
ptid_t ptid;
/* If the last thread is exiting, just return. */
- if (all_threads.head == all_threads.tail)
+ if (one_inferior_p (&all_threads))
return;
ptid = ptid_build (pid, tid, 0);
@@ -1142,6 +1142,28 @@ failed:
}
#ifndef _WIN32_WCE
+
+/* Helper routine for dll_is_loaded_by_basename.
+ Return non-zero if the basename in ARG matches the DLL in INF. */
+
+static int
+match_dll_by_basename (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *iter = (void *) inf;
+ const char *basename = arg;
+
+ return strcasecmp (lbasename (iter->name), basename) == 0;
+}
+
+/* Return non-zero if the DLL specified by BASENAME is loaded. */
+
+static int
+dll_is_loaded_by_basename (const char *basename)
+{
+ return find_inferior (&all_dlls, match_dll_by_basename,
+ (void *) basename) != NULL;
+}
+
/* On certain versions of Windows, the information about ntdll.dll
is not available yet at the time we get the LOAD_DLL_DEBUG_EVENT,
thus preventing us from reporting this DLL as an SO. This has been
@@ -1158,20 +1180,14 @@ failed:
static void
win32_ensure_ntdll_loaded (void)
{
- struct inferior_list_entry *dll_e;
size_t i;
HMODULE dh_buf[1];
HMODULE *DllHandle = dh_buf;
DWORD cbNeeded;
BOOL ok;
- for (dll_e = all_dlls.head; dll_e != NULL; dll_e = dll_e->next)
- {
- struct dll_info *dll = (struct dll_info *) dll_e;
-
- if (strcasecmp (lbasename (dll->name), "ntdll.dll") == 0)
- return;
- }
+ if (dll_is_loaded_by_basename ("ntdll.dll"))
+ return;
if (!load_psapi ())
return;
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] remove all_lwps from gdbserver: use list api
2014-01-29 18:11 [PATCH v2 2/3] remove all_lwps from gdbserver: use list api Doug Evans
2014-02-06 12:27 ` Pedro Alves
2014-02-20 21:18 ` Doug Evans
@ 2014-02-20 21:19 ` Doug Evans
2 siblings, 0 replies; 8+ messages in thread
From: Doug Evans @ 2014-02-20 21:19 UTC (permalink / raw)
To: gdb-patches
Doug Evans writes:
> Hi.
> This patch provides missing API routines where necessary,
> and removes all references to list implementation details
> outside of inferiors.c.
This patch fixes a buglet that was introduced.
Committed.
2014-02-20 Doug Evans <dje@google.com>
* inferiors.c (get_first_inferior): Fix buglet.
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index f83ee22..8c1375f 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -178,8 +178,8 @@ remove_thread (struct thread_info *thread)
struct inferior_list_entry *
get_first_inferior (struct inferior_list *list)
{
- if (all_threads.head != NULL)
- return all_threads.head;
+ if (list->head != NULL)
+ return list->head;
return NULL;
}
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-02-20 21:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-29 18:11 [PATCH v2 2/3] remove all_lwps from gdbserver: use list api Doug Evans
2014-02-06 12:27 ` Pedro Alves
2014-02-19 23:31 ` Doug Evans
2014-02-20 13:40 ` Pedro Alves
2014-02-20 18:18 ` Doug Evans
2014-02-20 18:27 ` Pedro Alves
2014-02-20 21:18 ` Doug Evans
2014-02-20 21:19 ` Doug Evans
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).