aboutsummaryrefslogtreecommitdiff
path: root/gdb/linux-nat.c
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2010-01-12 21:40:25 +0000
committerVladimir Prus <vladimir@codesourcery.com>2010-01-12 21:40:25 +0000
commitdc146f7c09d1369f5621e4aac23d410d40d3a6f0 (patch)
tree801e78e7bbd124f1c503f26bf1173741e224cb33 /gdb/linux-nat.c
parent837504c42dbf7cb67ee328fb0bdf594b70c90209 (diff)
downloadgdb-dc146f7c09d1369f5621e4aac23d410d40d3a6f0.zip
gdb-dc146f7c09d1369f5621e4aac23d410d40d3a6f0.tar.gz
gdb-dc146f7c09d1369f5621e4aac23d410d40d3a6f0.tar.bz2
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.
Diffstat (limited to 'gdb/linux-nat.c')
-rw-r--r--gdb/linux-nat.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 48ea1bc..bf0a5f1 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1184,6 +1184,7 @@ add_lwp (ptid_t ptid)
lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
lp->ptid = ptid;
+ lp->core = -1;
lp->next = lwp_list;
lwp_list = lp;
@@ -3642,6 +3643,7 @@ retry:
fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
restore_child_signals_mask (&prev_mask);
+ lp->core = linux_nat_core_of_thread_1 (lp->ptid);
return lp->ptid;
}
@@ -5423,6 +5425,75 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid)
return inf->aspace;
}
+int
+linux_nat_core_of_thread_1 (ptid_t ptid)
+{
+ struct cleanup *back_to;
+ char *filename;
+ FILE *f;
+ char *content = NULL;
+ char *p;
+ char *ts = 0;
+ int content_read = 0;
+ int i;
+ int core;
+
+ filename = xstrprintf ("/proc/%d/task/%ld/stat",
+ GET_PID (ptid), GET_LWP (ptid));
+ back_to = make_cleanup (xfree, filename);
+
+ f = fopen (filename, "r");
+ if (!f)
+ {
+ do_cleanups (back_to);
+ return -1;
+ }
+
+ make_cleanup_fclose (f);
+
+ for (;;)
+ {
+ int n;
+ content = xrealloc (content, content_read + 1024);
+ n = fread (content + content_read, 1, 1024, f);
+ content_read += n;
+ if (n < 1024)
+ {
+ content[content_read] = '\0';
+ break;
+ }
+ }
+
+ make_cleanup (xfree, content);
+
+ p = strchr (content, '(');
+ p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */
+
+ /* If the first field after program name has index 0, then core number is
+ the field with index 36. There's no constant for that anywhere. */
+ p = strtok_r (p, " ", &ts);
+ for (i = 0; i != 36; ++i)
+ p = strtok_r (NULL, " ", &ts);
+
+ if (sscanf (p, "%d", &core) == 0)
+ core = -1;
+
+ do_cleanups (back_to);
+
+ return core;
+}
+
+/* Return the cached value of the processor core for thread PTID. */
+
+int
+linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
+{
+ struct lwp_info *info = find_lwp_pid (ptid);
+ if (info)
+ return info->core;
+ return -1;
+}
+
void
linux_nat_add_target (struct target_ops *t)
{
@@ -5463,6 +5534,8 @@ linux_nat_add_target (struct target_ops *t)
t->to_supports_multi_process = linux_nat_supports_multi_process;
+ t->to_core_of_thread = linux_nat_core_of_thread;
+
/* We don't change the stratum; this target will sit at
process_stratum and thread_db will set at thread_stratum. This
is a little strange, since this is a multi-threaded-capable