/* Record the pc of the thread the last time it stopped. (This is
not the current thread's PC as that may have changed since the
- last stop, e.g., "return" command, or "p $pc = 0xf000"). This is
- used in coordination with stop_reason and waitstatus_pending_p:
- if the thread's PC is changed since it last stopped, a pending
- breakpoint waitstatus is discarded. */
+ last stop, e.g., "return" command, or "p $pc = 0xf000").
+
+ - If the thread's PC has not changed since the thread last
+ stopped, then proceed skips a breakpoint at the current PC,
+ otherwise we let the thread run into the breakpoint.
+
+ - If the thread has an unprocessed event pending, as indicated by
+ waitstatus_pending_p, this is used in coordination with
+ stop_reason: if the thread's PC has changed since the thread
+ last stopped, a pending breakpoint waitstatus is discarded.
+
+ - If the thread is running, this is set to -1, to avoid leaving
+ it with a stale value, to make it easier to catch bugs. */
CORE_ADDR stop_pc;
};
-typedef struct value *value_ptr;
-DEF_VEC_P (value_ptr);
-typedef VEC (value_ptr) value_vec;
-
/* Base class for target-specific thread data. */
struct private_thread_info
{
{
/* If this is the current thread, or there's code out there that
relies on it existing (refcount > 0) we can't delete yet. */
- return (refcount () == 0 && !ptid_equal (ptid, inferior_ptid));
+ return (refcount () == 0 && ptid != inferior_ptid);
}
+ /* Mark this thread as running and notify observers. */
+ void set_running (bool running);
+
struct thread_info *next = NULL;
ptid_t ptid; /* "Actual process id";
In fact, this may be overloaded with
/* Flag which indicates that the stack temporaries should be stored while
evaluating expressions. */
- int stack_temporaries_enabled = 0;
+ bool stack_temporaries_enabled = false;
/* Values that are stored as temporaries on stack while evaluating
expressions. */
- value_vec *stack_temporaries = NULL;
+ std::vector<struct value *> stack_temporaries;
/* Step-over chain. A thread is in the step-over queue if these are
non-NULL. If only a single thread is in the chain, then these
struct thread_info *step_over_next = NULL;
};
+/* A gdb::ref_ptr pointer to a thread_info. */
+
+using thread_info_ref
+ = gdb::ref_ptr<struct thread_info, refcounted_object_ref_policy>;
+
/* Create an empty thread list, or empty the existing one. */
extern void init_thread_list (void);
struct private_thread_info *);
/* Delete an existing thread list entry. */
-extern void delete_thread (ptid_t);
+extern void delete_thread (struct thread_info *thread);
/* Delete an existing thread list entry, and be quiet about it. Used
after the process this thread having belonged to having already
exited, for example. */
-extern void delete_thread_silent (ptid_t);
+extern void delete_thread_silent (struct thread_info *thread);
/* Delete a step_resume_breakpoint from the thread database. */
extern void delete_step_resume_breakpoint (struct thread_info *);
const address_space *aspace,
CORE_ADDR addr);
-/* Translate the global integer thread id (GDB's homegrown id, not the
- system's) into a "pid" (which may be overloaded with extra thread
- information). */
-extern ptid_t global_thread_id_to_ptid (int num);
-
-/* Translate a 'pid' (which may be overloaded with extra thread
- information) into the global integer thread id (GDB's homegrown id,
- not the system's). */
-extern int ptid_to_global_thread_id (ptid_t ptid);
-
/* Returns whether to show inferior-qualified thread IDs, or plain
thread numbers. Inferior-qualified IDs are shown whenever we have
multiple inferiors, or the only inferior left has number > 1. */
circular static buffer, NUMCELLS deep. */
const char *print_thread_id (struct thread_info *thr);
-/* Boolean test for an already-known pid (which may be overloaded with
- extra thread information). */
+/* Boolean test for an already-known ptid. */
extern int in_thread_list (ptid_t ptid);
/* Boolean test for an already-known global thread id (GDB's homegrown
struct thread_info *find_thread_by_handle (struct value *thread_handle,
struct inferior *inf);
-/* Finds the first thread of the inferior given by PID. If PID is -1,
- returns the first thread in the list. */
-struct thread_info *first_thread_of_process (int pid);
+/* Finds the first thread of the specified inferior. */
+extern struct thread_info *first_thread_of_inferior (inferior *inf);
-/* Returns any thread of process PID, giving preference to the current
- thread. */
-extern struct thread_info *any_thread_of_process (int pid);
+/* Returns any thread of inferior INF, giving preference to the
+ current thread. */
+extern struct thread_info *any_thread_of_inferior (inferior *inf);
-/* Returns any non-exited thread of process PID, giving preference to
+/* Returns any non-exited thread of inferior INF, giving preference to
the current thread, and to not executing threads. */
-extern struct thread_info *any_live_thread_of_process (int pid);
+extern struct thread_info *any_live_thread_of_inferior (inferior *inf);
/* Change the ptid of thread OLD_PTID to NEW_PTID. */
void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid);
extern int thread_count (void);
-/* Switch from one thread to another. Does not read registers and
- sets STOP_PC to -1. */
+/* Switch context to thread THR. Also sets the STOP_PC global. */
+extern void switch_to_thread (struct thread_info *thr);
+
+/* Switch context to no thread selected. */
+extern void switch_to_no_thread ();
+
+/* Switch from one thread to another. Does not read registers. */
extern void switch_to_thread_no_regs (struct thread_info *thread);
/* Marks or clears thread(s) PTID as resumed. If PTID is
thread_info. */
extern void set_executing (ptid_t ptid, int executing);
-/* Reports if thread PTID is executing. */
-extern int is_executing (ptid_t ptid);
-
/* True if any (known or unknown) thread is or may be executing. */
extern int threads_are_executing (void);
Notifications are only emitted if the thread state did change. */
extern void finish_thread_state (ptid_t ptid);
-/* Same as FINISH_THREAD_STATE, but with an interface suitable to be
- registered as a cleanup. PTID_P points to the ptid_t that is
- passed to FINISH_THREAD_STATE. */
-extern void finish_thread_state_cleanup (void *ptid_p);
+/* Calls finish_thread_state on scope exit, unless release() is called
+ to disengage. */
+class scoped_finish_thread_state
+{
+public:
+ explicit scoped_finish_thread_state (ptid_t ptid)
+ : m_ptid (ptid)
+ {}
+
+ ~scoped_finish_thread_state ()
+ {
+ if (!m_released)
+ finish_thread_state (m_ptid);
+ }
+
+ /* Disengage. */
+ void release ()
+ {
+ m_released = true;
+ }
+
+ DISABLE_COPY_AND_ASSIGN (scoped_finish_thread_state);
+
+private:
+ bool m_released = false;
+ ptid_t m_ptid;
+};
/* Commands with a prefix of `thread'. */
extern struct cmd_list_element *thread_cmd_list;
int pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread);
-extern struct cleanup *enable_thread_stack_temporaries (ptid_t ptid);
+/* Enable storing stack temporaries for thread THR and disable and
+ clear the stack temporaries on destruction. Holds a strong
+ reference to THR. */
+
+class enable_thread_stack_temporaries
+{
+public:
+
+ explicit enable_thread_stack_temporaries (struct thread_info *thr)
+ : m_thr (thr)
+ {
+ gdb_assert (m_thr != NULL);
+
+ m_thr->incref ();
+
+ m_thr->stack_temporaries_enabled = true;
+ m_thr->stack_temporaries.clear ();
+ }
+
+ ~enable_thread_stack_temporaries ()
+ {
+ m_thr->stack_temporaries_enabled = false;
+ m_thr->stack_temporaries.clear ();
+
+ m_thr->decref ();
+ }
+
+ DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);
+
+private:
+
+ struct thread_info *m_thr;
+};
-extern int thread_stack_temporaries_enabled_p (ptid_t ptid);
+extern bool thread_stack_temporaries_enabled_p (struct thread_info *tp);
-extern void push_thread_stack_temporary (ptid_t ptid, struct value *v);
+extern void push_thread_stack_temporary (struct thread_info *tp, struct value *v);
-extern struct value *get_last_thread_stack_temporary (ptid_t);
+extern value *get_last_thread_stack_temporary (struct thread_info *tp);
-extern int value_in_thread_stack_temporaries (struct value *, ptid_t);
+extern bool value_in_thread_stack_temporaries (struct value *,
+ struct thread_info *thr);
/* Add TP to the end of its inferior's pending step-over chain. */
executing). */
extern void validate_registers_access (void);
-/* Check whether it makes sense to access a register of PTID at this point.
+/* Check whether it makes sense to access a register of THREAD at this point.
Returns true if registers may be accessed; false otherwise. */
-extern bool can_access_registers_ptid (ptid_t ptid);
+extern bool can_access_registers_thread (struct thread_info *thread);
/* Returns whether to show which thread hit the breakpoint, received a
signal, etc. and ended up causing a user-visible stop. This is