+validate_registers_access (void)
+{
+ /* No selected thread, no registers. */
+ if (inferior_ptid == null_ptid)
+ error (_("No thread selected."));
+
+ /* Don't try to read from a dead thread. */
+ if (is_exited (inferior_ptid))
+ error (_("The current thread has terminated"));
+
+ /* ... or from a spinning thread. FIXME: This isn't actually fully
+ correct. It'll allow an user-requested access (e.g., "print $pc"
+ at the prompt) when a thread is not executing for some internal
+ reason, but is marked running from the user's perspective. E.g.,
+ the thread is waiting for its turn in the step-over queue. */
+ if (is_executing (inferior_ptid))
+ error (_("Selected thread is running."));
+}
+
+/* See gdbthread.h. */
+
+bool
+can_access_registers_ptid (ptid_t ptid)
+{
+ /* No thread, no registers. */
+ if (ptid == null_ptid)
+ return false;
+
+ /* Don't try to read from a dead thread. */
+ if (is_exited (ptid))
+ return false;
+
+ /* ... or from a spinning thread. FIXME: see validate_registers_access. */
+ if (is_executing (ptid))
+ return false;
+
+ return true;
+}
+
+int
+pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread)
+{
+ return (pc >= thread->control.step_range_start
+ && pc < thread->control.step_range_end);
+}
+
+/* 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
+ is true if REQUESTED_THREADS is list of global IDs, false if a list
+ of per-inferior thread ids. If PID is not -1, only print THR if it
+ 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. */
+
+static int
+should_print_thread (const char *requested_threads, int default_inf_num,
+ int global_ids, int pid, struct thread_info *thr)
+{
+ if (requested_threads != NULL && *requested_threads != '\0')
+ {
+ int in_list;
+
+ if (global_ids)
+ in_list = number_is_in_list (requested_threads, thr->global_num);
+ else
+ in_list = tid_is_in_list (requested_threads, default_inf_num,
+ thr->inf->num, thr->per_inf_num);
+ if (!in_list)
+ return 0;
+ }
+
+ if (pid != -1 && ptid_get_pid (thr->ptid) != pid)
+ {
+ if (requested_threads != NULL && *requested_threads != '\0')
+ error (_("Requested thread not found in requested process"));
+ return 0;
+ }
+
+ if (thr->state == THREAD_EXITED)
+ return 0;
+
+ return 1;
+}
+
+/* Like print_thread_info, but in addition, GLOBAL_IDS indicates
+ whether REQUESTED_THREADS is a list of global or per-inferior
+ thread ids. */
+
+static void
+print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
+ int global_ids, int pid,
+ int show_global_ids)