gdb/python: Use copy-initialization more when possible
[deliverable/binutils-gdb.git] / gdb / gdbthread.h
index 37c2837b20530f58cf24077be54fac32b8edb946..2c402543ddbea731775b9321aa606fec7687ba5c 100644 (file)
@@ -1,5 +1,5 @@
 /* Multi-process/thread control defs for GDB, the GNU debugger.
-   Copyright (C) 1987-2016 Free Software Foundation, Inc.
+   Copyright (C) 1987-2018 Free Software Foundation, Inc.
    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
    
 
@@ -31,6 +31,8 @@ struct symtab;
 #include "common/vec.h"
 #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),...  */
@@ -136,11 +138,6 @@ struct thread_control_state
      at.  */
   bpstat stop_bpstat;
 
-  /* The interpreter that issued the execution command.  NULL if the
-     thread was resumed as a result of a command applied to some other
-     thread (e.g., "next" with scheduler-locking off).  */
-  struct interp *command_interp;
-
   /* Whether the command that started the thread was a stepping
      command.  This is used to decide whether "set scheduler-locking
      step" behaves like "on" or "off".  */
@@ -171,20 +168,62 @@ 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;
+};
 
-struct thread_info
+/* Threads are intrusively refcounted objects.  Being the
+   user-selected thread is normally considered an implicit strong
+   reference and is thus not accounted in the refcount, unlike
+   inferior objects.  This is necessary, because there's no "current
+   thread" pointer.  Instead the current thread is inferred from the
+   inferior_ptid global.  However, when GDB needs to remember the
+   selected thread to later restore it, GDB bumps the thread object's
+   refcount, to prevent something deleting the thread object before
+   reverting back (e.g., due to a "kill" command).  If the thread
+   meanwhile exits before being re-selected, then the thread object is
+   left listed in the thread list, but marked with state
+   THREAD_EXITED.  (See make_cleanup_restore_current_thread and
+   delete_thread).  All other thread references are considered weak
+   references.  Placing a thread in the thread list is an implicit
+   strong reference, and is thus not accounted for in the thread's
+   refcount.  */
+
+class thread_info : public refcounted_object
 {
-  struct thread_info *next;
+public:
+  explicit thread_info (inferior *inf, ptid_t ptid);
+  ~thread_info ();
+
+  bool deletable () const
+  {
+    /* 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 != 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 
                                    kernel thread id, etc.  */
@@ -231,13 +270,13 @@ struct thread_info
 
   /* The name of the thread, as specified by the user.  This is NULL
      if the thread does not have a user-given name.  */
-  char *name;
+  char *name = NULL;
 
   /* Non-zero means the thread is executing.  Note: this is different
      from saying that there is an active target and we are stopped at
      a breakpoint, for instance.  This is a real indicator whether the
      thread is off and running.  */
-  int executing;
+  int executing = 0;
 
   /* Non-zero if this thread is resumed from infrun's perspective.
      Note that a thread can be marked both as not-executing and
@@ -246,30 +285,25 @@ struct thread_info
      thread really run until that wait status has been processed, but
      we should not process that wait status if we didn't try to let
      the thread run.  */
-  int resumed;
+  int resumed = 0;
 
   /* Frontend view of the thread state.  Note that the THREAD_RUNNING/
      THREAD_STOPPED states are different from EXECUTING.  When the
      thread is stopped internally while handling an internal event,
      like a software single-step breakpoint, EXECUTING will be false,
      but STATE will still be THREAD_RUNNING.  */
-  enum thread_state state;
-
-  /* If this is > 0, then it means there's code out there that relies
-     on this thread being listed.  Don't delete it from the lists even
-     if we detect it exiting.  */
-  int refcount;
+  enum thread_state state = THREAD_STOPPED;
 
   /* State of GDB control of inferior thread execution.
      See `struct thread_control_state'.  */
-  struct thread_control_state control;
+  thread_control_state control {};
 
   /* State of inferior thread to restore after GDB is done with an inferior
      call.  See `struct thread_suspend_state'.  */
-  struct thread_suspend_state suspend;
+  thread_suspend_state suspend {};
 
-  int current_line;
-  struct symtab *current_symtab;
+  int current_line = 0;
+  struct symtab *current_symtab = NULL;
 
   /* Internal stepping state.  */
 
@@ -279,20 +313,20 @@ struct thread_info
      by proceed and keep_going, and among other things, it's used in
      adjust_pc_after_break to distinguish a hardware single-step
      SIGTRAP from a breakpoint SIGTRAP.  */
-  CORE_ADDR prev_pc;
+  CORE_ADDR prev_pc = 0;
 
   /* Did we set the thread stepping a breakpoint instruction?  This is
      used in conjunction with PREV_PC to decide whether to adjust the
      PC.  */
-  int stepped_breakpoint;
+  int stepped_breakpoint = 0;
 
   /* Should we step over breakpoint next time keep_going is called?  */
-  int stepping_over_breakpoint;
+  int stepping_over_breakpoint = 0;
 
   /* Should we step over a watchpoint next time keep_going is called?
      This is needed on targets with non-continuable, non-steppable
      watchpoints.  */
-  int stepping_over_watchpoint;
+  int stepping_over_watchpoint = 0;
 
   /* Set to TRUE if we should finish single-stepping over a breakpoint
      after hitting the current step-resume breakpoint.  The context here
@@ -303,12 +337,12 @@ struct thread_info
      step_after_step_resume_breakpoint is set to TRUE at this moment in
      order to keep GDB in mind that there is still a breakpoint to step over
      when GDB gets back SIGTRAP from step_resume_breakpoint.  */
-  int step_after_step_resume_breakpoint;
+  int step_after_step_resume_breakpoint = 0;
 
   /* Pointer to the state machine manager object that handles what is
      left to do for the thread's execution command after the target
      stops.  Several execution commands use it.  */
-  struct thread_fsm *thread_fsm;
+  struct thread_fsm *thread_fsm = NULL;
 
   /* This is used to remember when a fork or vfork event was caught by
      a catchpoint, and thus the event is to be followed at the next
@@ -316,39 +350,40 @@ struct thread_info
   struct target_waitstatus pending_follow;
 
   /* True if this thread has been explicitly requested to stop.  */
-  int stop_requested;
+  int stop_requested = 0;
 
   /* The initiating frame of a nexting operation, used for deciding
      which exceptions to intercept.  If it is null_frame_id no
      bp_longjmp or bp_exception but longjmp has been caught just for
      bp_longjmp_call_dummy.  */
-  struct frame_id initiating_frame;
+  struct frame_id initiating_frame = null_frame_id;
 
   /* Private data used by the target vector implementation.  */
-  struct private_thread_info *priv;
-
-  /* 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 *);
+  std::unique_ptr<private_thread_info> priv;
 
   /* Branch trace information for this thread.  */
-  struct btrace_thread_info btrace;
+  struct btrace_thread_info btrace {};
 
   /* Flag which indicates that the stack temporaries should be stored while
      evaluating expressions.  */
-  int stack_temporaries_enabled;
+  bool stack_temporaries_enabled = false;
 
   /* Values that are stored as temporaries on stack while evaluating
      expressions.  */
-  value_vec *stack_temporaries;
+  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
      fields point to self.  */
-  struct thread_info *step_over_prev;
-  struct thread_info *step_over_next;
+  struct thread_info *step_over_prev = NULL;
+  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);
 
@@ -367,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 *);
@@ -390,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.  */
@@ -414,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
@@ -428,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);
@@ -474,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
@@ -531,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);
 
@@ -549,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'.  */
@@ -573,7 +621,25 @@ extern int print_thread_events;
 extern void print_thread_info (struct ui_out *uiout, char *requested_threads,
                               int pid);
 
-extern struct cleanup *make_cleanup_restore_current_thread (void);
+/* Save/restore current inferior/thread/frame.  */
+
+class scoped_restore_current_thread
+{
+public:
+  scoped_restore_current_thread ();
+  ~scoped_restore_current_thread ();
+
+  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);
+
+private:
+  /* 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;
+  bool m_was_stopped;
+};
 
 /* Returns a pointer into the thread_info corresponding to
    INFERIOR_PTID.  INFERIOR_PTID *must* be in the thread list.  */
@@ -594,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 ();
 
-extern int thread_stack_temporaries_enabled_p (ptid_t ptid);
+    m_thr->stack_temporaries_enabled = true;
+    m_thr->stack_temporaries.clear ();
+  }
 
-extern void push_thread_stack_temporary (ptid_t ptid, struct value *v);
+  ~enable_thread_stack_temporaries ()
+  {
+    m_thr->stack_temporaries_enabled = false;
+    m_thr->stack_temporaries.clear ();
 
-extern struct value *get_last_thread_stack_temporary (ptid_t);
+    m_thr->decref ();
+  }
 
-extern int value_in_thread_stack_temporaries (struct value *, ptid_t);
+  DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);
+
+private:
+
+  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.  */
 
@@ -630,6 +729,25 @@ 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 THREAD at this point.
+   Returns true if registers may be accessed; false otherwise.  */
+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
+   true iff we ever detected multiple threads.  */
+extern int show_thread_that_caused_stop (void);
+
+/* Print the message for a thread or/and frame selected.  */
+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 */
This page took 0.030658 seconds and 4 git commands to generate.