gnulib: define the path to gnulib's parent dir
[binutils-gdb.git] / gdb / gdbthread.h
index f205e29dd7dd2f1e4957c2ae3473e15a770fa454..eef37f79e6ade577ee8917cde718bf80a0f3c019 100644 (file)
@@ -1,5 +1,5 @@
 /* Multi-process/thread control defs for GDB, the GNU debugger.
-   Copyright (C) 1987-2020 Free Software Foundation, Inc.
+   Copyright (C) 1987-2021 Free Software Foundation, Inc.
    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
    
 
@@ -32,6 +32,7 @@ struct symtab;
 #include "gdbsupport/refcounted-object.h"
 #include "gdbsupport/common-gdbthread.h"
 #include "gdbsupport/forward-scope-exit.h"
+#include "displaced-stepping.h"
 
 struct inferior;
 struct process_stratum_target;
@@ -131,28 +132,10 @@ struct thread_control_state
      any inlined frames).  */
   struct frame_id step_stack_frame_id {};
 
-  /* Nonzero if we are presently stepping over a breakpoint.
-
-     If we hit a breakpoint or watchpoint, and then continue, we need
-     to single step the current thread with breakpoints disabled, to
-     avoid hitting the same breakpoint or watchpoint again.  And we
-     should step just a single thread and keep other threads stopped,
-     so that other threads don't miss breakpoints while they are
-     removed.
-
-     So, this variable simultaneously means that we need to single
-     step the current thread, keep other threads stopped, and that
-     breakpoints should be removed while we step.
-
-     This variable is set either:
-     - in proceed, when we resume inferior on user's explicit request
-     - in keep_going, if handle_inferior_event decides we need to
-     step over breakpoint.
-
-     The variable is cleared in normal_stop.  The proceed calls
-     wait_for_inferior, which calls handle_inferior_event in a loop,
-     and until wait_for_inferior exits, this variable is changed only
-     by keep_going.  */
+  /* True if the the thread is presently stepping over a breakpoint or
+     a watchpoint, either with an inline step over or a displaced (out
+     of line) step, and we're now expecting it to report a trap for
+     the finished single step.  */
   int trap_expected = 0;
 
   /* Nonzero if the thread is being proceeded for a "finish" command
@@ -261,14 +244,14 @@ public:
 
      a) The thread ID (Id).  This consists of the pair of:
 
-        - the number of the thread's inferior and,
+       - the number of the thread's inferior and,
 
-        - the thread's thread number in its inferior, aka, the
-          per-inferior thread number.  This number is unique in the
-          inferior but not unique between inferiors.
+       - the thread's thread number in its inferior, aka, the
+         per-inferior thread number.  This number is unique in the
+         inferior but not unique between inferiors.
 
      b) The global ID (GId).  This is a a single integer unique
-        between all inferiors.
+       between all inferiors.
 
      E.g.:
 
@@ -301,20 +284,20 @@ public:
      if the thread does not have a user-given name.  */
   char *name = NULL;
 
-  /* Non-zero means the thread is executing.  Note: this is different
+  /* True 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.  */
   bool executing = false;
 
-  /* Non-zero if this thread is resumed from infrun's perspective.
+  /* True if this thread is resumed from infrun's perspective.
      Note that a thread can be marked both as not-executing and
      resumed at the same time.  This happens if we try to resume a
      thread that has a wait status pending.  We shouldn't let the
      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 = 0;
+  bool resumed = false;
 
   /* Frontend view of the thread state.  Note that the THREAD_RUNNING/
      THREAD_STOPPED states are different from EXECUTING.  When the
@@ -406,6 +389,9 @@ public:
      fields point to self.  */
   struct thread_info *step_over_prev = NULL;
   struct thread_info *step_over_next = NULL;
+
+  /* Displaced-step state for this thread.  */
+  displaced_step_thread_state displaced_step_state;
 };
 
 /* A gdb::ref_ptr pointer to a thread_info.  */
@@ -413,6 +399,13 @@ public:
 using thread_info_ref
   = gdb::ref_ptr<struct thread_info, refcounted_object_ref_policy>;
 
+/* A gdb::ref_ptr pointer to an inferior.  This would ideally be in
+   inferior.h, but it can't due to header dependencies (inferior.h
+   includes gdbthread.h).  */
+
+using inferior_ref
+  = gdb::ref_ptr<struct inferior, refcounted_object_ref_policy>;
+
 /* Create an empty thread list, or empty the existing one.  */
 extern void init_thread_list (void);
 
@@ -433,12 +426,13 @@ extern struct thread_info *add_thread_with_info (process_stratum_target *targ,
                                                 ptid_t ptid,
                                                 private_thread_info *);
 
-/* Delete an existing thread list entry.  */
+/* Delete thread THREAD and notify of thread exit.  If the thread is
+   currently not deletable, don't actually delete it but still tag it
+   as exited and do the notification.  */
 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.  */
+/* Like delete_thread, but be quiet about it.  Used when the process
+   this thread belonged to has already exited, for example.  */
 extern void delete_thread_silent (struct thread_info *thread);
 
 /* Delete a step_resume_breakpoint from the thread database.  */
@@ -478,15 +472,15 @@ extern bool in_thread_list (process_stratum_target *targ, ptid_t ptid);
    global id, not the system's).  */
 extern int valid_global_thread_id (int global_id);
 
-/* Find thread PTID of inferior INF.  */
+/* Find (non-exited) thread PTID of inferior INF.  */
 extern thread_info *find_thread_ptid (inferior *inf, ptid_t ptid);
 
-/* Search function to lookup a thread by 'pid'.  */
+/* Search function to lookup a (non-exited) thread by 'ptid'.  */
 extern struct thread_info *find_thread_ptid (process_stratum_target *targ,
                                             ptid_t ptid);
 
-/* Search function to lookup a thread by 'ptid'.  Only searches in
-   threads of INF.  */
+/* Search function to lookup a (non-exited) thread by 'ptid'.  Only
+   searches in threads of INF.  */
 extern struct thread_info *find_thread_ptid (inferior *inf, ptid_t ptid);
 
 /* Find thread by GDB global thread ID.  */
@@ -677,13 +671,16 @@ private:
   void restore ();
 
   bool m_dont_restore = false;
-  /* 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;
+  thread_info_ref m_thread;
+  inferior_ref m_inf;
+
   frame_id m_selected_frame_id;
   int m_selected_frame_level;
   bool m_was_stopped;
+  /* Save/restore the language as well, because selecting a frame
+     changes the current language to the frame's language if "set
+     language auto".  */
+  enum language m_lang;
 };
 
 /* Returns a pointer into the thread_info corresponding to
@@ -714,12 +711,8 @@ class enable_thread_stack_temporaries
 public:
 
   explicit enable_thread_stack_temporaries (struct thread_info *thr)
-    : m_thr (thr)
+    : m_thr (thread_info_ref::new_reference (thr))
   {
-    gdb_assert (m_thr != NULL);
-
-    m_thr->incref ();
-
     m_thr->stack_temporaries_enabled = true;
     m_thr->stack_temporaries.clear ();
   }
@@ -728,15 +721,13 @@ public:
   {
     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;
+  thread_info_ref m_thr;
 };
 
 extern bool thread_stack_temporaries_enabled_p (struct thread_info *tp);
@@ -748,23 +739,48 @@ 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.  */
+/* Add TP to the end of the global pending step-over chain.  */
+
+extern void global_thread_step_over_chain_enqueue (thread_info *tp);
+
+/* Append the thread step over chain CHAIN_HEAD to the global thread step over
+   chain. */
+
+extern void global_thread_step_over_chain_enqueue_chain
+  (thread_info *chain_head);
+
+/* Remove TP from step-over chain LIST_P.  */
 
-extern void thread_step_over_chain_enqueue (struct thread_info *tp);
+extern void thread_step_over_chain_remove (thread_info **list_p,
+                                          thread_info *tp);
 
-/* Remove TP from its inferior's pending step-over chain.  */
+/* Remove TP from the global pending step-over chain.  */
 
-extern void thread_step_over_chain_remove (struct thread_info *tp);
+extern void global_thread_step_over_chain_remove (thread_info *tp);
 
-/* Return the next thread in the step-over chain starting at TP.  NULL
-   if TP is the last entry in the chain.  */
+/* Return the thread following TP in the step-over chain whose head is
+   CHAIN_HEAD.  Return NULL if TP is the last entry in the chain.  */
 
-extern struct thread_info *thread_step_over_chain_next (struct thread_info *tp);
+extern thread_info *thread_step_over_chain_next (thread_info *chain_head,
+                                                thread_info *tp);
 
-/* Return true if TP is in the step-over chain.  */
+/* Return the thread following TP in the global step-over chain, or NULL if TP
+   is the last entry in the chain.  */
+
+extern thread_info *global_thread_step_over_chain_next (thread_info *tp);
+
+/* Return true if TP is in any step-over chain.  */
 
 extern int thread_is_in_step_over_chain (struct thread_info *tp);
 
+/* Return the length of the the step over chain TP is in.
+
+   If TP is non-nullptr, the thread must be in a step over chain.
+   TP may be nullptr, in which case it denotes an empty list, so a length of
+   0.  */
+
+extern int thread_step_over_chain_length (thread_info *tp);
+
 /* Cancel any ongoing execution command.  */
 
 extern void thread_cancel_execution_command (struct thread_info *thr);