diff options
Diffstat (limited to 'gdb/thread.c')
-rw-r--r-- | gdb/thread.c | 122 |
1 files changed, 73 insertions, 49 deletions
diff --git a/gdb/thread.c b/gdb/thread.c index b659463..0228027 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1038,6 +1038,37 @@ pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread) && pc < thread->control.step_range_end); } +/* The options for the "info threads" command. */ + +struct info_threads_opts +{ + /* For "-gid". */ + bool show_global_ids = false; + /* For "-running". */ + bool show_running_threads = false; + /* For "-stopped". */ + bool show_stopped_threads = false; +}; + +static const gdb::option::option_def info_threads_option_defs[] = { + + gdb::option::flag_option_def<info_threads_opts> { + "gid", + [] (info_threads_opts *opts) { return &opts->show_global_ids; }, + N_("Show global thread IDs."), + }, + gdb::option::flag_option_def<info_threads_opts> { + "running", + [] (info_threads_opts *opts) { return &opts->show_running_threads; }, + N_("Show running threads only."), + }, + gdb::option::flag_option_def<info_threads_opts> { + "stopped", + [] (info_threads_opts *opts) { return &opts->show_stopped_threads; }, + N_("Show stopped threads only."), + }, +}; + /* Helper for print_thread_info. Returns true if THR should be printed. If REQUESTED_THREADS, a list of GDB ids/ranges, is not NULL, only print THR if its ID is included in the list. GLOBAL_IDS @@ -1046,11 +1077,13 @@ pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread) is a thread from the process PID. Otherwise, threads from all attached PIDs are printed. If both REQUESTED_THREADS is not NULL and PID is not -1, then the thread is printed if it belongs to the - specified process. Otherwise, an error is raised. */ + specified process. Otherwise, an error is raised. OPTS is the + options of the "info threads" command. */ static bool -should_print_thread (const char *requested_threads, int default_inf_num, - int global_ids, int pid, struct thread_info *thr) +should_print_thread (const char *requested_threads, + const info_threads_opts &opts, int default_inf_num, + int global_ids, int pid, thread_info *thr) { if (requested_threads != NULL && *requested_threads != '\0') { @@ -1075,7 +1108,17 @@ should_print_thread (const char *requested_threads, int default_inf_num, if (thr->state == THREAD_EXITED) return false; - return true; + bool is_stopped = (thr->state == THREAD_STOPPED); + if (opts.show_stopped_threads && is_stopped) + return true; + + bool is_running = (thr->state == THREAD_RUNNING); + if (opts.show_running_threads && is_running) + return true; + + /* If the user did not pass a filter flag, show the thread. */ + return (!opts.show_stopped_threads + && !opts.show_running_threads); } /* Return the string to display in "info threads"'s "Target Id" @@ -1104,8 +1147,8 @@ thread_target_id_str (thread_info *tp) static void do_print_thread (ui_out *uiout, const char *requested_threads, - int global_ids, int pid, int show_global_ids, - int default_inf_num, thread_info *tp, + const info_threads_opts &opts, int global_ids, + int pid, int default_inf_num, thread_info *tp, thread_info *current_thread) { int core; @@ -1114,7 +1157,7 @@ do_print_thread (ui_out *uiout, const char *requested_threads, if (current_thread != nullptr) switch_to_thread (current_thread); - if (!should_print_thread (requested_threads, default_inf_num, + if (!should_print_thread (requested_threads, opts, default_inf_num, global_ids, pid, tp)) return; @@ -1130,7 +1173,7 @@ do_print_thread (ui_out *uiout, const char *requested_threads, uiout->field_string ("id-in-tg", print_thread_id (tp)); } - if (show_global_ids || uiout->is_mi_like_p ()) + if (opts.show_global_ids || uiout->is_mi_like_p ()) uiout->field_signed ("id", tp->global_num); /* Switch to the thread (and inferior / target). */ @@ -1191,23 +1234,22 @@ do_print_thread (ui_out *uiout, const char *requested_threads, static void print_thread (ui_out *uiout, const char *requested_threads, - int global_ids, int pid, int show_global_ids, + const info_threads_opts &opts, int global_ids, int pid, int default_inf_num, thread_info *tp, thread_info *current_thread) { do_with_buffered_output (do_print_thread, uiout, requested_threads, - global_ids, pid, show_global_ids, - default_inf_num, tp, current_thread); + opts, global_ids, pid, default_inf_num, tp, + current_thread); } /* Like print_thread_info, but in addition, GLOBAL_IDS indicates whether REQUESTED_THREADS is a list of global or per-inferior - thread ids. */ + thread ids. OPTS is the options of the "info threads" command. */ static void print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, - int global_ids, int pid, - int show_global_ids) + const info_threads_opts &opts, int global_ids, int pid) { int default_inf_num = current_inferior ()->num; @@ -1235,19 +1277,21 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, list_emitter.emplace (uiout, "threads"); else { - int n_threads = 0; + int n_matching_threads = 0; /* The width of the "Target Id" column. Grown below to accommodate the largest entry. */ size_t target_id_col_width = 17; for (thread_info *tp : all_threads ()) { + any_thread = true; + /* In case REQUESTED_THREADS contains $_thread. */ if (current_thread != nullptr) switch_to_thread (current_thread); - if (!should_print_thread (requested_threads, default_inf_num, - global_ids, pid, tp)) + if (!should_print_thread (requested_threads, opts, + default_inf_num, global_ids, pid, tp)) continue; /* Switch inferiors so we're looking at the right @@ -1258,25 +1302,24 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, = std::max (target_id_col_width, thread_target_id_str (tp).size ()); - ++n_threads; + ++n_matching_threads; } - if (n_threads == 0) + if (n_matching_threads == 0) { - if (requested_threads == NULL || *requested_threads == '\0') + if (!any_thread) uiout->message (_("No threads.\n")); else - uiout->message (_("No threads match '%s'.\n"), - requested_threads); + uiout->message (_("No threads matched.\n")); return; } - table_emitter.emplace (uiout, show_global_ids ? 5 : 4, - n_threads, "threads"); + table_emitter.emplace (uiout, opts.show_global_ids ? 5 : 4, + n_matching_threads, "threads"); uiout->table_header (1, ui_left, "current", ""); uiout->table_header (4, ui_left, "id-in-tg", "Id"); - if (show_global_ids) + if (opts.show_global_ids) uiout->table_header (4, ui_left, "id", "GId"); uiout->table_header (target_id_col_width, ui_left, "target-id", "Target Id"); @@ -1287,13 +1330,11 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, for (inferior *inf : all_inferiors ()) for (thread_info *tp : inf->threads ()) { - any_thread = true; - if (tp == current_thread && tp->state == THREAD_EXITED) current_exited = true; - print_thread (uiout, requested_threads, global_ids, pid, - show_global_ids, default_inf_num, tp, current_thread); + print_thread (uiout, requested_threads, opts, global_ids, pid, + default_inf_num, tp, current_thread); } /* This end scope restores the current thread and the frame @@ -1322,27 +1363,10 @@ void print_thread_info (struct ui_out *uiout, const char *requested_threads, int pid) { - print_thread_info_1 (uiout, requested_threads, 1, pid, 0); + info_threads_opts opts; + print_thread_info_1 (uiout, requested_threads, opts, 1, pid); } -/* The options for the "info threads" command. */ - -struct info_threads_opts -{ - /* For "-gid". */ - bool show_global_ids = false; -}; - -static const gdb::option::option_def info_threads_option_defs[] = { - - gdb::option::flag_option_def<info_threads_opts> { - "gid", - [] (info_threads_opts *opts) { return &opts->show_global_ids; }, - N_("Show global thread IDs."), - }, - -}; - /* Create an option_def_group for the "info threads" options, with IT_OPTS as context. */ @@ -1367,7 +1391,7 @@ info_threads_command (const char *arg, int from_tty) gdb::option::process_options (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp); - print_thread_info_1 (current_uiout, arg, 0, -1, it_opts.show_global_ids); + print_thread_info_1 (current_uiout, arg, it_opts, 0, -1); } /* Completer for the "info threads" command. */ |