This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Implement -thread-info.


Presently, the MI -thread-info and -thread-list-all-threads
commands are not implemented, so a frontend wishing to know
the state of all threads upon stop is required to manually iterate
over threads, or use CLI. This patch implements -thread-info,
that prints essentially the same information as 'info thread' in CLI.
The new command can either print information for all threads, or
for a specific one provided as argument, making -thread-list-all-threads
not necessary. The sample output is:

^done,
   threads=[
    {id="2",target-id="Thread 0xb7e1eb90 (LWP 21429)",frame={addr="0xffffe410",func="__kernel_vsyscall",args=[]}},
    {id="1",target-id="Thread 0xb7e1f6b0 (LWP 21426)",frame={...}}],
   current-thread-id="1"

I'll provide docs patch if the code patch is approved. OK?

- Volodya

	* gdb.h (mi_info_threads): Declare.
	* thread.c (mi_info_threads): New.

	* mi/mi-cmds.c (mi_cmds): Specify a handler
	for -thread-info.
	* mi/mi-cmds.h (mi_cmd_thread_info): Declare.
	* mi/mi-main.c (mi_cmd_thread_info): New.
	(mi_cmd_list_features): Include 'thread-info'.
---
 gdb/gdb.h        |    2 +
 gdb/mi/mi-cmds.c |    3 +-
 gdb/mi/mi-cmds.h |    1 +
 gdb/mi/mi-main.c |   19 +++++++++++++++++
 gdb/thread.c     |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/gdb/gdb.h b/gdb/gdb.h
index fcd3e3b..13523fb 100644
--- a/gdb/gdb.h
+++ b/gdb/gdb.h
@@ -55,4 +55,6 @@ enum gdb_rc gdb_thread_select (struct ui_out *uiout, char *tidstr,
 enum gdb_rc gdb_list_thread_ids (struct ui_out *uiout,
 				 char **error_message);
 
+extern void mi_info_threads (struct ui_out *uiout, int thread);
+
 #endif
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index c651694..89c6376 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -130,8 +130,7 @@ struct mi_cmd mi_cmds[] =
   { "target-list-current-targets", { NULL, 0 }, NULL, NULL },
   { "target-list-parameters", { NULL, 0 }, NULL, NULL },
   { "target-select", { NULL, 0 }, mi_cmd_target_select},
-  { "thread-info", { NULL, 0 }, NULL, NULL },
-  { "thread-list-all-threads", { NULL, 0 }, NULL, NULL },
+  { "thread-info", { NULL, 0 }, NULL, mi_cmd_thread_info },
   { "thread-list-ids", { NULL, 0 }, 0, mi_cmd_thread_list_ids},
   { "thread-select", { NULL, 0 }, 0, mi_cmd_thread_select},
   { "trace-actions", { NULL, 0 }, NULL, NULL },
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 2d0393b..6a033e5 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -105,6 +105,7 @@ extern mi_cmd_argv_ftype mi_cmd_target_file_get;
 extern mi_cmd_argv_ftype mi_cmd_target_file_put;
 extern mi_cmd_argv_ftype mi_cmd_target_file_delete;
 extern mi_cmd_args_ftype mi_cmd_target_select;
+extern mi_cmd_argv_ftype mi_cmd_thread_info;
 extern mi_cmd_argv_ftype mi_cmd_thread_list_ids;
 extern mi_cmd_argv_ftype mi_cmd_thread_select;
 extern mi_cmd_argv_ftype mi_cmd_var_assign;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 41e12d2..5d89847 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -277,6 +277,24 @@ mi_cmd_thread_list_ids (char *command, char **argv, int argc)
 }
 
 enum mi_cmd_result
+mi_cmd_thread_info (char *command, char **argv, int argc)
+{
+  int thread = -1;
+  
+  if (argc != 0 && argc != 1)
+    {
+      mi_error_message = xstrprintf ("Invalid MI command");
+      return MI_CMD_ERROR;
+    }
+
+  if (argc == 1)
+    thread = atoi (argv[0]);
+
+  mi_info_threads (uiout, thread);
+  return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
 mi_cmd_data_list_register_names (char *command, char **argv, int argc)
 {
   int regnum, numregs;
@@ -1055,6 +1073,7 @@ mi_cmd_list_features (char *command, char **argv, int argc)
 
       ui_out_field_string (uiout, NULL, "frozen-varobjs");
       ui_out_field_string (uiout, NULL, "pending-breakpoints");
+      ui_out_field_string (uiout, NULL, "thread-info");
       
       do_cleanups (cleanup);
 
diff --git a/gdb/thread.c b/gdb/thread.c
index 3a39703..d11ef00 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -471,6 +471,66 @@ info_threads_command (char *arg, int from_tty)
     }
 }
 
+/* Prints the list of threads and their details on UIOUT.
+   This is a version of 'info_thread_command' suitable for
+   use from MI.  
+   If REQESTED_THREAD is not -1, it's the GDB id of the thread
+   that should be printed.  Otherwise, all threads are
+   printed.  */
+void
+mi_info_threads (struct ui_out *uiout, int requested_thread)
+{
+  struct thread_info *tp;
+  ptid_t current_ptid;
+  int current_thread = -1;
+  struct cleanup *cleanup_chain;
+  char *extra_info;
+  struct frame_id saved_frame_id;
+
+  saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  cleanup_chain = make_cleanup_restore_current_thread (inferior_ptid, 
+						       saved_frame_id);
+
+  prune_threads ();
+  target_find_new_threads ();
+  current_ptid = inferior_ptid;
+  cleanup_chain = make_cleanup_ui_out_list_begin_end (uiout, "threads");
+
+  for (tp = thread_list; tp; tp = tp->next)
+    {
+      struct cleanup *cleanup2;
+
+      if (requested_thread != -1 && tp->num != requested_thread)
+	continue;
+
+      cleanup2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+      if (ptid_equal (tp->ptid, current_ptid))
+	current_thread = tp->num;
+
+      ui_out_field_int (uiout, "id", tp->num);
+      ui_out_field_string (uiout, "target-id", target_tid_to_str (tp->ptid));
+
+      extra_info = target_extra_thread_info (tp);
+      if (extra_info)
+	ui_out_field_string (uiout, "details", extra_info);
+
+      /* That switch put us at the top of the stack (leaf frame).  */
+      switch_to_thread (tp->ptid);
+      print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
+
+      do_cleanups (cleanup2);
+    }
+  do_cleanups (cleanup_chain);
+  
+  if (requested_thread == -1)
+    {
+      gdb_assert (current_thread != -1);
+      ui_out_field_int (uiout, "current-thread-id", current_thread);
+    }
+}
+
+
 /* Switch from one thread to another. */
 
 void
-- 
1.5.3.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]