Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Aaron Gamble <agamble@google.com>
To: Tom Tromey <tromey@redhat.com>
Cc: Sergio Durigan Junior <sergiodj@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [patch] info threads sort by name and name regex matching
Date: Fri, 24 Aug 2012 01:09:00 -0000	[thread overview]
Message-ID: <CAHX8C+L=iiicRcprm7ixcxn2ykd+3aePR7r0=XsrvB1-kbLv2g@mail.gmail.com> (raw)
In-Reply-To: <87pq6hppiz.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1165 bytes --]

Here is an updated patch. I have changed the options to be as follows.

'info threads [-a] [ id ... | -r regex ]'

-a enables sorting by thread name
-r regex matches regex with thread names.

I have not changed the threads array to a VEC as of yet. At this point
it seems like more trouble than it's worth. But I suppose it could be
done if people think it's necessary.

On Thu, Aug 23, 2012 at 9:00 AM, Tom Tromey <tromey@redhat.com> wrote:
>
> Sergio> Why not `-r regex'?  I think it would be more clear.
>
> Me too.
>
> Sergio> Other commands (`sharedlibrary', `info variables', etc) take a regex as
> Sergio> their first argument, without requiring a modifier like `-r'.  If the
> Sergio> "pipe" patch were already in, this alphabetical sorting would not be
> Sergio> needed...  Anyway, just thinking here.
>
> Piping is nice but I think it is also good to have options for common
> cases.
>
> Sergio> I guess Tom did not suggest this because of performance per se, but
> Sergio> rather because if you have to make a list in GDB then it is already a
> Sergio> convention to use VEC for these things.
>
> Yeah.  I thought it would make the code simpler.
>
> Tom

[-- Attachment #2: thread_sorting_regex_with-a-r-options.patch --]
[-- Type: application/octet-stream, Size: 22268 bytes --]

From efef7b796f528835d18bb778304805e6228695fd Mon Sep 17 00:00:00 2001
From: Aaron Gamble <agamble@google.com>
Date: Thu, 23 Aug 2012 18:04:03 -0700
Subject: [PATCH] sorting with -a -r regex options

---
 gdb/doc/gdb.texinfo                                |   11 +-
 gdb/gdbthread.h                                    |    6 +-
 gdb/testsuite/gdb.threads/Makefile.in              |    2 +-
 gdb/testsuite/gdb.threads/info-thread-sort-regex.c |  122 +++++++
 .../gdb.threads/info-thread-sort-regex.exp         |   58 +++
 gdb/thread.c                                       |  374 +++++++++++++-------
 6 files changed, 441 insertions(+), 132 deletions(-)
 create mode 100644 gdb/testsuite/gdb.threads/info-thread-sort-regex.c
 create mode 100644 gdb/testsuite/gdb.threads/info-thread-sort-regex.exp

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 08ba92d..3e6c108 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2751,10 +2751,13 @@ number---always a single integer---with each thread in your program.
 
 @table @code
 @kindex info threads
-@item info threads @r{[}@var{id}@dots{}@r{]}
-Display a summary of all threads currently in your program.  Optional 
-argument @var{id}@dots{} is one or more thread ids separated by spaces, and
-means to print information only about the specified thread or threads.
+@item info threads @r{[}-a@r{]} @r{[}@var{id}@dots{}@b{|}-r @var{regex}@r{]}
+Display a summary of all threads currently in your program.  Use the option
+-a to sort threads alphabetically by name.  Selection of threads can be done
+by supplying a list or ranges of thread ID's, or by using the -r @var{regex}
+option to display only threads with names matching @var{regex}.  Spaces
+between the -r and @var{regex} are ignored.
+
 @value{GDBN} displays for each thread (in this order):
 
 @enumerate
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 0250555..2463cea 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -138,6 +138,10 @@ struct thread_info
      if the thread does not have a user-given name.  */
   char *name;
 
+  /* The name of the thread, as cached by print_thread_info.
+     Used for sorting info threads output.  */
+  char *cached_name;
+
   /* Non-zero means the thread is executing.  Note: this is different
      from saying that there is an active target and we are stopped at
      a breakpoint, for instance.  This is a real indicator whether the
@@ -385,7 +389,7 @@ extern struct cmd_list_element *thread_cmd_list;
    `set print thread-events'.  */
 extern int print_thread_events;
 
-extern void print_thread_info (struct ui_out *uiout, char *threads,
+extern void print_thread_info (struct ui_out *uiout, char *args,
 			       int pid);
 
 extern struct cleanup *make_cleanup_restore_current_thread (void);
diff --git a/gdb/testsuite/gdb.threads/Makefile.in b/gdb/testsuite/gdb.threads/Makefile.in
index 8f9f867..2d24ba4 100644
--- a/gdb/testsuite/gdb.threads/Makefile.in
+++ b/gdb/testsuite/gdb.threads/Makefile.in
@@ -5,7 +5,7 @@ EXECUTABLES = attach-into-signal-nothr attach-into-signal-thr \
 	attach-stopped attachstop-mt \
 	bp_in_thread current-lwp-dead execl execl1 fork-child-threads \
 	fork-thread-pending gcore-pthreads hand-call-in-threads \
-	ia64-sigill interrupted-hand-call killed linux-dp \
+	ia64-sigill info-thread-sort-regex interrupted-hand-call killed linux-dp \
 	local-watch-wrong-thread manythreads multi-create pending-step \
 	print-threads pthreads pthread_cond_wait schedlock sigthread \
 	staticthreads switch-threads thread-execl thread-specific \
diff --git a/gdb/testsuite/gdb.threads/info-thread-sort-regex.c b/gdb/testsuite/gdb.threads/info-thread-sort-regex.c
new file mode 100644
index 0000000..98979ce
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/info-thread-sort-regex.c
@@ -0,0 +1,122 @@
+/* Test case for info threads sort and regex matching.
+
+   Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifndef NR_THREADS
+#define NR_THREADS 4
+#endif
+
+int thread_count;
+
+pthread_mutex_t thread_count_mutex;
+
+pthread_cond_t thread_count_condvar;
+
+void
+incr_thread_count (void)
+{
+  pthread_mutex_lock (&thread_count_mutex);
+  ++thread_count;
+  if (thread_count == NR_THREADS)
+    pthread_cond_signal (&thread_count_condvar);
+  pthread_mutex_unlock (&thread_count_mutex);
+}
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+  pthread_mutex_lock (mut);
+  pthread_cond_wait (cond, mut);
+  pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+  pthread_mutex_t mut;
+  pthread_cond_t cond;
+
+  pthread_mutex_init (&mut, NULL);
+  pthread_cond_init (&cond, NULL);
+
+  /* Wait for a condition that will never be signaled, so we effectively
+     block the thread here.  */
+  cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+  incr_thread_count ();
+  noreturn ();
+}
+
+/* Wait until all threads are running.  */
+
+void
+wait_all_threads_running (void)
+{
+  pthread_mutex_lock (&thread_count_mutex);
+  if (thread_count == NR_THREADS)
+    {
+      pthread_mutex_unlock (&thread_count_mutex);
+      return;
+    }
+  pthread_cond_wait (&thread_count_condvar, &thread_count_mutex);
+  if (thread_count == NR_THREADS)
+    {
+      pthread_mutex_unlock (&thread_count_mutex);
+      return;
+    }
+  pthread_mutex_unlock (&thread_count_mutex);
+  printf ("failed waiting for all threads to start\n");
+  abort ();
+}
+
+/* Called when all threads are running.
+   Easy place for a breakpoint.  */
+
+void
+all_threads_running (void)
+{
+}
+
+int
+main (void)
+{
+  pthread_t forever[NR_THREADS];
+  int i;
+
+  pthread_mutex_init (&thread_count_mutex, NULL);
+  pthread_cond_init (&thread_count_condvar, NULL);
+
+  for (i = 0; i < NR_THREADS; ++i)
+    pthread_create (&forever[i], NULL, forever_pthread, NULL);
+
+  wait_all_threads_running ();
+  all_threads_running ();
+
+  return 0;
+}
+
diff --git a/gdb/testsuite/gdb.threads/info-thread-sort-regex.exp b/gdb/testsuite/gdb.threads/info-thread-sort-regex.exp
new file mode 100644
index 0000000..a49eedf
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/info-thread-sort-regex.exp
@@ -0,0 +1,58 @@
+# Copyright (C) 2004, 2007-2008, 2010-2012 Free Software Foundation,
+# Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test sorting and regex matching in info threads.
+
+set NR_THREADS 4
+
+standard_testfile
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-DNR_THREADS=$NR_THREADS"]] != "" } {
+    return -1
+}
+
+clean_restart ${binfile}
+
+if { ![runto_main] } {
+    fail "Can't run to main"
+    return 0
+}
+
+gdb_test "break all_threads_running" \
+	 "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+	 "breakpoint on all_threads_running"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 2 in all_threads_running().
+
+gdb_test "continue" \
+	 ".*Breakpoint 2, all_threads_running ().*" \
+	 "run to all_threads_running"
+
+# Test that the no threads match message prints correctly.
+gdb_test "info threads -r \$foo" \
+	 "No threads match '\\\$foo'\." \
+	 "info thread no match test"
+
+gdb_test_no_output "thread name a" "set thread name to a"
+
+gdb_test "info threads -a" \
+   "\\s+Id\\s+Target\\s+Id\\s+Frame \r\n\\*\\\s+\\\d+\\\s+Thread\\\s+0x\[A-Fa-f0-9\]+ \\\(LWP \\\d+\\\) \"a\".*" \
+   "check thread a is first"
+
+gdb_test "info threads -r ^info" \
+   "\\s+Id\\s+Target\\s+Id\\s+Frame \r\n\\\s+\\\d+\\\s+Thread\\\s+0x\[A-Fa-f0-9\]+ \\\(LWP \\\d+\\\) \"info.*\".*" \
+   "filter out thread named a"
diff --git a/gdb/thread.c b/gdb/thread.c
index 7e8eec5..68b2dac 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -55,6 +55,7 @@ void _initialize_thread (void);
 /* Prototypes for local functions.  */
 
 struct thread_info *thread_list = NULL;
+static int thread_list_size = 0;
 static int highest_thread_num;
 
 static void thread_command (char *tidstr, int from_tty);
@@ -132,6 +133,7 @@ free_thread (struct thread_info *tp)
 	xfree (tp->private);
     }
 
+  thread_list_size--;
   xfree (tp->name);
   xfree (tp);
 }
@@ -153,6 +155,7 @@ init_thread_list (void)
     }
 
   thread_list = NULL;
+  thread_list_size = 0;
 }
 
 /* Allocate a new thread with target id PTID and add it to the thread
@@ -169,6 +172,7 @@ new_thread (ptid_t ptid)
   tp->num = ++highest_thread_num;
   tp->next = thread_list;
   thread_list = tp;
+  thread_list_size++;
 
   /* Nothing to follow yet.  */
   tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
@@ -748,25 +752,195 @@ finish_thread_state_cleanup (void *arg)
   finish_thread_state (*ptid_p);
 }
 
+/* Returns true if user requested the thread.  */
+
+static int
+print_thread_filter_check (struct thread_info *tp, char *requested_threads,
+			   int pid, regex_t *preg)
+{
+  if (preg)
+    {
+      int err = regexec (preg, tp->cached_name ? tp->cached_name : "",
+			 0, NULL, 0);
+      if (err == 0)
+	return TRUE;
+      else
+	return FALSE;
+    }
+
+  /* No regular expression was supplied, see if there's a match the list
+     of thread id's.  */
+  if (!number_is_in_list (requested_threads, tp->num))
+    return FALSE;
+
+  if (pid != -1 && PIDGET (tp->ptid) != pid)
+    {
+      if (requested_threads != NULL && *requested_threads != '\0')
+	error (_("Requested thread not found in requested process"));
+      return FALSE;
+    }
+
+  if (tp->state == THREAD_EXITED)
+    return FALSE;
+
+  return TRUE;
+}
+
+
+/* Used to Sort threads in lexicographic order by name.  */
+
+static int
+print_thread_sort_cmp (const void *p1, const void *p2)
+{
+  const char *name1 = (*(struct thread_info **) p1)->cached_name;
+  const char *name2 = (*(struct thread_info **) p2)->cached_name;
+  if (name1 && name2)
+    return strcmp (name1, name2);
+
+  /* In case we receive NULL pointers instead of strings.
+     NULL pointers are sorted as empty strings.  */
+  if (!name1 && name2)
+    return -1;
+  if (!name2 && name1)
+    return 1;
+
+  return 0;
+}
+
+/* Prints the info for a single thread.
+   Called by print_thread_info for each thread.  */
+
+static void
+print_thread_info_single (struct ui_out *uiout, struct thread_info *tp,
+			       ptid_t current_ptid)
+{
+  struct cleanup *uiout_cleanup
+    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  int core;
+  char *extra_info, *name, *target_id;
+
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      /* Compatibility.  */
+      if (ptid_equal (tp->ptid, current_ptid))
+	ui_out_text (uiout, "* ");
+      else
+	ui_out_text (uiout, "  ");
+    }
+    else
+    {
+      if (ptid_equal (tp->ptid, current_ptid))
+	ui_out_field_string (uiout, "current", "*");
+      else
+	ui_out_field_skip (uiout, "current");
+    }
+
+  ui_out_field_int (uiout, "id", tp->num);
+
+  /* For the CLI, we stuff everything into the target-id field.
+     This is a gross hack to make the output come out looking
+     correct.  The underlying problem here is that ui-out has no
+     way to specify that a field's space allocation should be
+     shared by several fields.  For MI, we do the right thing
+     instead.  */
+
+  target_id = target_pid_to_str (tp->ptid);
+  extra_info = target_extra_thread_info (tp);
+  if (tp->cached_name)
+    name = tp->cached_name;
+  else
+    name = tp->name ? tp->name : target_thread_name (tp);
+
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "target-id", target_id);
+      if (extra_info)
+	ui_out_field_string (uiout, "details", extra_info);
+      if (name)
+	ui_out_field_string (uiout, "name", name);
+    }
+  else
+    {
+      struct cleanup *str_cleanup;
+      char *contents;
+
+      if (extra_info && name)
+	contents = xstrprintf ("%s \"%s\" (%s)", target_id,
+			       name, extra_info);
+      else if (extra_info)
+	contents = xstrprintf ("%s (%s)", target_id, extra_info);
+      else if (name)
+	contents = xstrprintf ("%s \"%s\"", target_id, name);
+      else
+	contents = xstrdup (target_id);
+      str_cleanup = make_cleanup (xfree, contents);
+
+      ui_out_field_string (uiout, "target-id", contents);
+      do_cleanups (str_cleanup);
+    }
+
+  if (tp->state == THREAD_RUNNING)
+    ui_out_text (uiout, "(running)\n");
+  else
+    {
+      /* The switch below puts us at the top of the stack (leaf
+	 frame).  */
+      switch_to_thread (tp->ptid);
+      print_stack_frame (get_selected_frame (NULL),
+	  /* For MI output, print frame level.  */
+	  ui_out_is_mi_like_p (uiout),
+	  LOCATION);
+    }
+
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      char *state = "stopped";
+
+      if (tp->state == THREAD_RUNNING)
+	state = "running";
+      ui_out_field_string (uiout, "state", state);
+    }
+
+  core = target_core_of_thread (tp->ptid);
+  if (ui_out_is_mi_like_p (uiout) && core != -1)
+    ui_out_field_int (uiout, "core", core);
+
+  do_cleanups (uiout_cleanup);
+}
+
+/* Caches the name that will be shown to the user for a thread.
+   We keep track of this for sorting purposes.  */
+
+static void
+thread_cache_name (struct thread_info *tp)
+{
+  /* Does not need to be freed, is only transient.  */
+  tp->cached_name = tp->name ? tp->name : target_thread_name (tp);
+}
+
 /* Prints the list of threads and their details on UIOUT.
    This is a version of 'info_threads_command' suitable for
    use from MI.
-   If REQUESTED_THREAD is not -1, it's the GDB id of the thread
-   that should be printed.  Otherwise, all threads are
-   printed.
-   If PID is not -1, only print threads from the process PID.
-   Otherwise, threads from all attached PIDs are printed.
-   If both REQUESTED_THREAD and PID are not -1, then the thread
-   is printed if it belongs to the specified process.  Otherwise,
-   an error is raised.  */
+   REQUESTED_THREADS is either a list of numeric thread Id's
+   or the character 'r' followed by a regular expression to
+   match with each thread's name. Any spaces between the 'r' and
+   the regular expression are ignored.
+   If neither is supplied then all threads are printed.
+   Threads are sorted by name unless we are sending to MI.  */
+
 void
-print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
+print_thread_info (struct ui_out *uiout, char *args, int pid)
 {
   struct thread_info *tp;
   ptid_t current_ptid;
   struct cleanup *old_chain;
-  char *extra_info, *name, *target_id;
   int current_thread = -1;
+  struct thread_info **threads = NULL;
+  int n_threads, i, ret;
+  int enable_sort = FALSE;
+  regex_t preg_buffer;
+  regex_t *preg = NULL;
+  char *requested_threads = args;
 
   update_thread_list ();
   current_ptid = inferior_ptid;
@@ -774,27 +948,75 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
   /* We'll be switching threads temporarily.  */
   old_chain = make_cleanup_restore_current_thread ();
 
+  /* Process argument string args for options.  */
+  args = skip_spaces (args);
+  while (args && *args != '\0')
+    {
+      if (*args != '-')
+	break;
+      if (args[1] == 'a')
+	{
+	  enable_sort = TRUE;
+	  args = skip_spaces (args + 2);
+	  requested_threads = args;
+	  continue;
+	}
+      if (args[1] == 'r')
+	{
+	  args = skip_spaces (&args[2]);
+	  ret = regcomp (&preg_buffer, args, REG_NOSUB);
+	  if (ret == 0)
+	    {
+	      preg = &preg_buffer;
+	      make_regfree_cleanup (preg);
+	    }
+	  else
+	    {
+	      char *err =  get_regcomp_error (ret, &preg_buffer);
+	      make_cleanup (xfree, err);
+	      error (_("Invalid regexp (%s): %s"), err, requested_threads);
+	    }
+	  break;
+	}
+	error (_("Bad option (%s)"), &args[1]);
+	break;
+    }
+
   /* For backward compatibility, we make a list for MI.  A table is
      preferable for the CLI, though, because it shows table
-     headers.  */
+     headers.
+     We do not sort the list for MI.  */
   if (ui_out_is_mi_like_p (uiout))
-    make_cleanup_ui_out_list_begin_end (uiout, "threads");
-  else
     {
-      int n_threads = 0;
+      make_cleanup_ui_out_list_begin_end (uiout, "threads");
 
       for (tp = thread_list; tp; tp = tp->next)
 	{
-	  if (!number_is_in_list (requested_threads, tp->num))
-	    continue;
+	  if (ptid_equal (tp->ptid, current_ptid))
+	    current_thread = tp->num;
+
+	  if (print_thread_filter_check (tp, requested_threads, pid, NULL))
+	    print_thread_info_single (uiout, tp, current_ptid);
+	}
+    }
+  else
+    {
+      threads = xmalloc (sizeof (*threads) * thread_list_size);
+      make_cleanup (free, threads);
 
-	  if (pid != -1 && PIDGET (tp->ptid) != pid)
-	    continue;
+      n_threads = 0;
+      for (i = 0, tp = thread_list; tp; tp = tp->next, ++i)
+	{
+	  thread_cache_name (tp);
+	  if (print_thread_filter_check (tp, requested_threads, pid, preg))
+	    {
+	      threads[n_threads] = tp;
+	      ++n_threads;
+	    }
 
-	  if (tp->state == THREAD_EXITED)
-	    continue;
+	  if (ptid_equal (tp->ptid, current_ptid))
+	    current_thread = tp->num;
 
-	  ++n_threads;
 	}
 
       if (n_threads == 0)
@@ -803,7 +1025,7 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
 	    ui_out_message (uiout, 0, _("No threads.\n"));
 	  else
 	    ui_out_message (uiout, 0, _("No threads match '%s'.\n"),
-			    requested_threads);
+					args);
 	  do_cleanups (old_chain);
 	  return;
 	}
@@ -815,115 +1037,15 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
       ui_out_table_header (uiout, 17, ui_left, "target-id", "Target Id");
       ui_out_table_header (uiout, 1, ui_left, "frame", "Frame");
       ui_out_table_body (uiout);
-    }
 
-  for (tp = thread_list; tp; tp = tp->next)
-    {
-      struct cleanup *chain2;
-      int core;
 
-      if (!number_is_in_list (requested_threads, tp->num))
-	continue;
+      if (enable_sort)
+	qsort (threads, n_threads, sizeof (*threads), print_thread_sort_cmp);
 
-      if (pid != -1 && PIDGET (tp->ptid) != pid)
+      for (i = 0; i < n_threads; i++)
 	{
-	  if (requested_threads != NULL && *requested_threads != '\0')
-	    error (_("Requested thread not found in requested process"));
-	  continue;
+	  print_thread_info_single (uiout, threads[i], current_ptid);
 	}
-
-      if (ptid_equal (tp->ptid, current_ptid))
-	current_thread = tp->num;
-
-      if (tp->state == THREAD_EXITED)
-	continue;
-
-      chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-
-      if (ui_out_is_mi_like_p (uiout))
-	{
-	  /* Compatibility.  */
-	  if (ptid_equal (tp->ptid, current_ptid))
-	    ui_out_text (uiout, "* ");
-	  else
-	    ui_out_text (uiout, "  ");
-	}
-      else
-	{
-	  if (ptid_equal (tp->ptid, current_ptid))
-	    ui_out_field_string (uiout, "current", "*");
-	  else
-	    ui_out_field_skip (uiout, "current");
-	}
-
-      ui_out_field_int (uiout, "id", tp->num);
-
-      /* For the CLI, we stuff everything into the target-id field.
-	 This is a gross hack to make the output come out looking
-	 correct.  The underlying problem here is that ui-out has no
-	 way to specify that a field's space allocation should be
-	 shared by several fields.  For MI, we do the right thing
-	 instead.  */
-
-      target_id = target_pid_to_str (tp->ptid);
-      extra_info = target_extra_thread_info (tp);
-      name = tp->name ? tp->name : target_thread_name (tp);
-
-      if (ui_out_is_mi_like_p (uiout))
-	{
-	  ui_out_field_string (uiout, "target-id", target_id);
-	  if (extra_info)
-	    ui_out_field_string (uiout, "details", extra_info);
-	  if (name)
-	    ui_out_field_string (uiout, "name", name);
-	}
-      else
-	{
-	  struct cleanup *str_cleanup;
-	  char *contents;
-
-	  if (extra_info && name)
-	    contents = xstrprintf ("%s \"%s\" (%s)", target_id,
-				   name, extra_info);
-	  else if (extra_info)
-	    contents = xstrprintf ("%s (%s)", target_id, extra_info);
-	  else if (name)
-	    contents = xstrprintf ("%s \"%s\"", target_id, name);
-	  else
-	    contents = xstrdup (target_id);
-	  str_cleanup = make_cleanup (xfree, contents);
-
-	  ui_out_field_string (uiout, "target-id", contents);
-	  do_cleanups (str_cleanup);
-	}
-
-      if (tp->state == THREAD_RUNNING)
-	ui_out_text (uiout, "(running)\n");
-      else
-	{
-	  /* The switch below puts us at the top of the stack (leaf
-	     frame).  */
-	  switch_to_thread (tp->ptid);
-	  print_stack_frame (get_selected_frame (NULL),
-			     /* For MI output, print frame level.  */
-			     ui_out_is_mi_like_p (uiout),
-			     LOCATION);
-	}
-
-      if (ui_out_is_mi_like_p (uiout))
-	{
-	  char *state = "stopped";
-
-	  if (tp->state == THREAD_RUNNING)
-	    state = "running";
-	  ui_out_field_string (uiout, "state", state);
-	}
-
-      core = target_core_of_thread (tp->ptid);
-      if (ui_out_is_mi_like_p (uiout) && core != -1)
-	ui_out_field_int (uiout, "core", core);
-
-      do_cleanups (chain2);
     }
 
   /* Restores the current thread and the frame selected before
-- 
1.7.7.3


  reply	other threads:[~2012-08-24  1:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-21 21:19 Aaron Gamble
2012-08-22 10:06 ` Abid, Hafiz
2012-08-22 17:15 ` Eli Zaretskii
2012-08-22 18:52 ` Tom Tromey
2012-08-22 22:37   ` Aaron Gamble
2012-08-22 23:30     ` Sergio Durigan Junior
2012-08-23 16:00       ` Tom Tromey
2012-08-24  1:09         ` Aaron Gamble [this message]
2012-08-24 17:58           ` Tom Tromey
2012-08-24 22:23             ` Aaron Gamble
2012-08-24 22:32               ` Sergio Durigan Junior
2012-08-24 23:21                 ` Aaron Gamble
2012-08-24 23:28                 ` Aaron Gamble
2012-08-25  3:12                   ` Sergio Durigan Junior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHX8C+L=iiicRcprm7ixcxn2ykd+3aePR7r0=XsrvB1-kbLv2g@mail.gmail.com' \
    --to=agamble@google.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sergiodj@redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox