mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
Implement core awareness.
* bcache.c (compare_ints): Remove (print_percentage): Use compare_positive_ints. * defs.h (compare_positive_ints): Declare. * linux-nat.h (struct lin_lwp): New field core. (linux_nat_core_of_thread_1): Declare. * linux-nat.c (add_lwp): Init the 'core' field. (linux_nat_wait_1): Record the core. (linux_nat_core_of_thread_1, linux_nat_core_of_thread): New. (linux_nat_add_target): Register the above. * linux-thread-db.c (update_thread_core): New. (thread_db_find_new_threads): Update core information for every thread. * remote.c (struct private_thread_info): New. (free_private_thread_info, demand_private_info): New. (PACKET_qXfer_threads, use_osdata_threads): New. (struct thread_item, threads_parsing_context (start_thread, end_thread, thread_attributes) (thread_children, threads_children, threads_elements): New. (remote_threads_info): Try qXfer:threads before anything else. (remote_protocol_packets): Register qXfer:threads. (remote_open_1): Init use_osdata_threads. (struct stop_reply): New field 'core'. (remote_parse_stop_reply): Parse core number. (process_stop_reply): Record core number. (remote_xfer_partial): Handle qXfer:threads. (remote_core_of_thread): New. (init_remote_ops): Register remote_core_of_thread. (_initialize_remote): Register qXfer:read. * target.c (target_core_of_thread): New * target.h (enum target_object): New value TARGET_OBJECT_THREADS. (struct target_ops): New field to_core_of_threads. (target_core_of_thread): Declare. * gdbthread.h (struct thread_info): New field private_dtor. * thread.c (print_thread_info): Report the core. * ui-out.c (MAX_UI_OUT_LEVELS): Increase. * utils.c (compare_positive_ints): New. * features/threads.dtd: New. * mi/mi-interp.c (mi_on_normal_stop): Report the core. * mi/mi-main.c (struct collect_cores_data, collect_cores) (do_nothing, free_vector_of_osdata_items) (splay_tree_int_comparator, free_splay_tree): New. (print_one_inferior_data): Implemented printing of selected inferiors. Collect and print cores. (output_cores): New. (mi_cmd_list_thread_groups): Support --recurse. Permit specifying thread groups together with --available.
This commit is contained in:
@@ -707,6 +707,87 @@ handle_monitor_command (char *mon)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_threads_qxfer_proper (struct buffer *buffer)
|
||||
{
|
||||
struct inferior_list_entry *thread;
|
||||
|
||||
buffer_grow_str (buffer, "<threads>\n");
|
||||
|
||||
for (thread = all_threads.head; thread; thread = thread->next)
|
||||
{
|
||||
ptid_t ptid = thread_to_gdb_id ((struct thread_info *)thread);
|
||||
char ptid_s[100];
|
||||
int core = -1;
|
||||
char core_s[21];
|
||||
|
||||
write_ptid (ptid_s, ptid);
|
||||
|
||||
if (the_target->core_of_thread)
|
||||
core = (*the_target->core_of_thread) (ptid);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
buffer_grow_str0 (buffer, "</threads>\n");
|
||||
}
|
||||
|
||||
static int
|
||||
handle_threads_qxfer (const char *annex,
|
||||
unsigned char *readbuf,
|
||||
CORE_ADDR offset, int length)
|
||||
{
|
||||
static char *result = 0;
|
||||
static unsigned int result_length = 0;
|
||||
|
||||
if (annex && strcmp (annex, "") != 0)
|
||||
return 0;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
struct buffer buffer;
|
||||
/* When asked for data at offset 0, generate everything and store into
|
||||
'result'. Successive reads will be served off 'result'. */
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
buffer_init (&buffer);
|
||||
|
||||
handle_threads_qxfer_proper (&buffer);
|
||||
|
||||
result = buffer_finish (&buffer);
|
||||
result_length = strlen (result);
|
||||
buffer_free (&buffer);
|
||||
}
|
||||
|
||||
if (offset >= result_length)
|
||||
{
|
||||
/* We're out of data. */
|
||||
free (result);
|
||||
result = NULL;
|
||||
result_length = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (length > result_length - offset)
|
||||
length = result_length - offset;
|
||||
|
||||
memcpy (readbuf, result + offset, length);
|
||||
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
/* Handle all of the extended 'q' packets. */
|
||||
void
|
||||
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||
@@ -1112,6 +1193,43 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:threads:read:", own_buf, 19) == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + 19, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (!data)
|
||||
return;
|
||||
n = handle_threads_qxfer (annex, data, ofs, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Protocol features query. */
|
||||
if (strncmp ("qSupported", own_buf, 10) == 0
|
||||
&& (own_buf[10] == ':' || own_buf[10] == '\0'))
|
||||
@@ -1168,6 +1286,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||
if (target_supports_non_stop ())
|
||||
strcat (own_buf, ";QNonStop+");
|
||||
|
||||
strcat (own_buf, ";qXfer:threads:read+");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user