[RFA] Implement -thread-info.
Vladimir Prus
vladimir@codesourcery.com
Sun Feb 17 15:33:00 GMT 2008
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
More information about the Gdb-patches
mailing list