/* Multi-process/thread control defs for GDB, the GNU debugger.
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
#include "inferior.h"
#include "btrace.h"
#include "common/vec.h"
+#include "target/waitstatus.h"
/* Frontend view of the thread state. Possible extensions: stepping,
finishing, until(ling),... */
CORE_ADDR step_range_start; /* Inclusive */
CORE_ADDR step_range_end; /* Exclusive */
+ /* Function the thread was in as of last it started stepping. */
+ struct symbol *step_start_function;
+
/* If GDB issues a target step request, and this is nonzero, the
target should single-step this thread once, and then continue
single-stepping it without GDB core involvement as long as the
int trap_expected;
/* Nonzero if the thread is being proceeded for a "finish" command
- or a similar situation when stop_registers should be saved. */
+ or a similar situation when return value should be printed. */
int proceed_to_finish;
/* Nonzero if the thread is being proceeded for an inferior function
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;
-};
-/* Inferior thread specific part of `struct infcall_suspend_state'.
+ /* 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". */
+ int stepping_command;
+};
- Inferior process counterpart is `struct inferior_suspend_state'. */
+/* Inferior thread specific part of `struct infcall_suspend_state'. */
struct thread_suspend_state
{
should be suppressed, the core will take care of clearing this
before the target is resumed. */
enum gdb_signal stop_signal;
+
+ /* The reason the thread last stopped, if we need to track it
+ (breakpoint, watchpoint, etc.) */
+ enum target_stop_reason stop_reason;
+
+ /* The waitstatus for this thread's last event. */
+ struct target_waitstatus waitstatus;
+ /* If true WAITSTATUS hasn't been handled yet. */
+ int waitstatus_pending_p;
+
+ /* 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. */
+ CORE_ADDR stop_pc;
};
typedef struct value *value_ptr;
thread is off and running. */
int executing;
+ /* Non-zero 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;
+
/* 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,
/* Internal stepping state. */
- /* Record the pc of the thread the last time it stopped. This is
- maintained by proceed and keep_going, and used in
+ /* Record the pc of the thread the last time it was resumed. (It
+ can't be done on stop as the PC may change since the last stop,
+ e.g., "return" command, or "p $pc = 0xf000"). This is maintained
+ 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;
when GDB gets back SIGTRAP from step_resume_breakpoint. */
int step_after_step_resume_breakpoint;
- /* Per-thread command support. */
-
- /* Pointer to what is left to do for an execution command after the
- target stops. Used only in asynchronous mode, by targets that
- support async execution. Several execution commands use it. */
- struct continuation *continuations;
-
- /* Similar to the above, but used when a single execution command
- requires several resume/stop iterations. Used by the step
- command. */
- struct continuation *intermediate_continuations;
-
- /* If stepping, nonzero means step count is > 1 so don't print frame
- next time inferior stops if it stops due to stepping. */
- int step_multi;
+ /* 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;
/* 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
struct frame_id initiating_frame;
/* Private data used by the target vector implementation. */
- struct private_thread_info *private;
+ struct private_thread_info *priv;
/* Function that is called to free PRIVATE. If this is NULL, then
xfree will be called on PRIVATE. */
/* Values that are stored as temporaries on stack while evaluating
expressions. */
value_vec *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;
};
/* Create an empty thread list, or empty the existing one. */
for (T = thread_list; T; T = T->next) \
if ((T)->state != THREAD_EXITED)
-/* Like ALL_NON_EXITED_THREADS, but allows deleting the currently
- iterated thread. */
-#define ALL_NON_EXITED_THREADS_SAFE(T, TMP) \
+/* Traverse all threads, including those that have THREAD_EXITED
+ state. Allows deleting the currently iterated thread. */
+#define ALL_THREADS_SAFE(T, TMP) \
for ((T) = thread_list; \
(T) != NULL ? ((TMP) = (T)->next, 1): 0; \
- (T) = (TMP)) \
- if ((T)->state != THREAD_EXITED)
+ (T) = (TMP))
extern int thread_count (void);
/* Switch from one thread to another. */
extern void switch_to_thread (ptid_t ptid);
+/* Marks or clears thread(s) PTID as resumed. If PTID is
+ MINUS_ONE_PTID, applies to all threads. If ptid_is_pid(PTID) is
+ true, applies to all threads of the process pointed at by PTID. */
+extern void set_resumed (ptid_t ptid, int resumed);
+
/* Marks thread PTID is running, or stopped.
If PTID is minus_one_ptid, marks all threads. */
extern void set_running (ptid_t ptid, int running);
/* Commands with a prefix of `thread'. */
extern struct cmd_list_element *thread_cmd_list;
+extern void thread_command (char *tidstr, int from_tty);
+
/* Print notices on thread events (attach, detach, etc.), set with
`set print thread-events'. */
extern int print_thread_events;
extern void prune_threads (void);
+/* Delete threads marked THREAD_EXITED. Unlike prune_threads, this
+ does not consult the target about whether the thread is alive right
+ now. */
+extern void delete_exited_threads (void);
+
/* Return true if PC is in the stepping range of THREAD. */
int pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread);
extern int value_in_thread_stack_temporaries (struct value *, ptid_t);
+/* Add TP to the end of its inferior's pending step-over chain. */
+
+extern void thread_step_over_chain_enqueue (struct thread_info *tp);
+
+/* Remove TP from its inferior's pending step-over chain. */
+
+extern void thread_step_over_chain_remove (struct 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. */
+
+extern struct thread_info *thread_step_over_chain_next (struct thread_info *tp);
+
+/* Return true if TP is in the step-over chain. */
+
+extern int thread_is_in_step_over_chain (struct thread_info *tp);
+
+/* Cancel any ongoing execution command. */
+
+extern void thread_cancel_execution_command (struct thread_info *thr);
+
extern struct thread_info *thread_list;
#endif /* GDBTHREAD_H */