Automatic date update in version.in
[external/binutils.git] / gdb / gdbthread.h
index 7bf2070..2c40254 100644 (file)
@@ -1,5 +1,5 @@
 /* Multi-process/thread control defs for GDB, the GNU debugger.
-   Copyright (C) 1987-2017 Free Software Foundation, Inc.
+   Copyright (C) 1987-2018 Free Software Foundation, Inc.
    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
    
 
@@ -32,6 +32,7 @@ struct symtab;
 #include "target/waitstatus.h"
 #include "cli/cli-utils.h"
 #include "common/refcounted-object.h"
+#include "common-gdbthread.h"
 
 /* Frontend view of the thread state.  Possible extensions: stepping,
    finishing, until(ling),...  */
@@ -167,16 +168,27 @@ struct thread_suspend_state
 
   /* 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
+{
+  virtual ~private_thread_info () = 0;
+};
 
 /* Threads are intrusively refcounted objects.  Being the
    user-selected thread is normally considered an implicit strong
@@ -205,9 +217,12 @@ public:
   {
     /* 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 
@@ -344,22 +359,18 @@ public:
   struct frame_id initiating_frame = null_frame_id;
 
   /* Private data used by the target vector implementation.  */
-  struct private_thread_info *priv = NULL;
-
-  /* Function that is called to free PRIVATE.  If this is NULL, then
-     xfree will be called on PRIVATE.  */
-  void (*private_dtor) (struct private_thread_info *) = NULL;
+  std::unique_ptr<private_thread_info> priv;
 
   /* Branch trace information for this thread.  */
   struct btrace_thread_info btrace {};
 
   /* 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
@@ -368,6 +379,11 @@ public:
   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);
 
@@ -386,12 +402,12 @@ extern struct thread_info *add_thread_with_info (ptid_t ptid,
                                                 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 *);
@@ -409,19 +425,9 @@ extern int thread_has_single_step_breakpoints_set (struct thread_info *tp);
 /* Check whether the thread has software single stepping breakpoints
    set at PC.  */
 extern int thread_has_single_step_breakpoint_here (struct thread_info *tp,
-                                                  struct address_space *aspace,
+                                                  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.  */
@@ -433,8 +439,7 @@ extern int show_inferior_qualified_tids (void);
    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
@@ -447,17 +452,20 @@ extern struct thread_info *find_thread_ptid (ptid_t ptid);
 /* Find thread by GDB global thread ID.  */
 struct thread_info *find_thread_global_id (int global_id);
 
-/* 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);
+/* Find thread by thread library specific handle in inferior INF.  */
+struct thread_info *find_thread_by_handle (struct value *thread_handle,
+                                          struct inferior *inf);
 
-/* Returns any thread of process PID, giving preference to the current
-   thread.  */
-extern struct thread_info *any_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 non-exited thread of process PID, giving preference to
+/* 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 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);
@@ -493,12 +501,13 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
 
 extern int thread_count (void);
 
-/* Switch from one thread to another.  Also sets the STOP_PC
-   global.  */
-extern void switch_to_thread (ptid_t ptid);
+/* 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 and
-   sets STOP_PC to -1.  */
+/* 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
@@ -550,9 +559,6 @@ extern int is_stopped (ptid_t ptid);
    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);
 
@@ -568,15 +574,38 @@ 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;
 
-extern void thread_command (char *tidstr, int from_tty);
+extern void thread_command (const char *tidstr, int from_tty);
 
 /* Print notices on thread events (attach, detach, etc.), set with
    `set print thread-events'.  */
@@ -600,14 +629,12 @@ public:
   scoped_restore_current_thread ();
   ~scoped_restore_current_thread ();
 
-  /* Disable copy.  */
-  scoped_restore_current_thread
-    (const scoped_restore_current_thread &) = delete;
-  void operator=
-    (const scoped_restore_current_thread &) = delete;
+  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);
 
 private:
-  thread_info *m_thread;
+  /* Use the "class" keyword here, because of a clash with a "thread_info"
+     function in the Darwin API.  */
+  class thread_info *m_thread;
   inferior *m_inf;
   frame_id m_selected_frame_id;
   int m_selected_frame_level;
@@ -633,15 +660,48 @@ extern void delete_exited_threads (void);
 
 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 ();
 
-extern int thread_stack_temporaries_enabled_p (ptid_t ptid);
+    m_thr->decref ();
+  }
 
-extern void push_thread_stack_temporary (ptid_t ptid, struct value *v);
+  DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);
 
-extern struct value *get_last_thread_stack_temporary (ptid_t);
+private:
 
-extern int value_in_thread_stack_temporaries (struct value *, ptid_t);
+  struct thread_info *m_thr;
+};
+
+extern bool thread_stack_temporaries_enabled_p (struct thread_info *tp);
+
+extern void push_thread_stack_temporary (struct thread_info *tp, struct value *v);
+
+extern value *get_last_thread_stack_temporary (struct thread_info *tp);
+
+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.  */
 
@@ -669,9 +729,9 @@ extern void thread_cancel_execution_command (struct thread_info *thr);
    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
@@ -682,6 +742,12 @@ extern int show_thread_that_caused_stop (void);
 extern void print_selected_thread_frame (struct ui_out *uiout,
                                         user_selected_what selection);
 
+/* Helper for the CLI's "thread" command and for MI's -thread-select.
+   Selects thread THR.  TIDSTR is the original string the thread ID
+   was parsed from.  This is used in the error message if THR is not
+   alive anymore.  */
+extern void thread_select (const char *tidstr, class thread_info *thr);
+
 extern struct thread_info *thread_list;
 
 #endif /* GDBTHREAD_H */