X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdbthread.h;h=0f9734d0a06b93c969f636376084c79921758b16;hb=3043c1aba16b1b5bfdf6813d90ec661988ddfa3f;hp=d8cb4b34a481a2803b25e032ef013def4b4fda65;hpb=e09875d41026beb03eae1a65510ca40ed3a5d6c1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index d8cb4b34a4..0f9734d0a0 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -1,6 +1,5 @@ /* Multi-process/thread control defs for GDB, the GNU debugger. - Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1997, 1998, 1999, - 2000, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1987-2015 Free Software Foundation, Inc. Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. @@ -28,44 +27,40 @@ struct symtab; #include "frame.h" #include "ui-out.h" #include "inferior.h" +#include "btrace.h" +#include "common/vec.h" +#include "target/waitstatus.h" -struct thread_info +/* Frontend view of the thread state. Possible extensions: stepping, + finishing, until(ling),... */ +enum thread_state { - struct thread_info *next; - ptid_t ptid; /* "Actual process id"; - In fact, this may be overloaded with - kernel thread id, etc. */ - int num; /* Convenient handle (GDB thread id) */ + THREAD_STOPPED, + THREAD_RUNNING, + THREAD_EXITED, +}; - /* 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. */ - /* This field is internal to thread.c. Never access it directly, - use is_executing instead. */ - int executing_; - - /* Frontend view of the thread state. Note that the RUNNING/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 running will - still be true. As a possible future extension, this could turn - into enum { stopped, exited, stepping, finishing, until(ling), - running ... } */ - /* This field is internal to thread.c. Never access it directly, - use is_running instead. */ - int state_; +/* Inferior thread specific part of `struct infcall_control_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; + Inferior process counterpart is `struct inferior_control_state'. */ +struct thread_control_state +{ /* User/external stepping state. */ /* Step-resume or longjmp-resume breakpoint. */ struct breakpoint *step_resume_breakpoint; + /* Exception-resume breakpoint. */ + struct breakpoint *exception_resume_breakpoint; + + /* Breakpoints used for software single stepping. Plural, because + it may have multiple locations. E.g., if stepping over a + conditional branch instruction we can't decode the condition for, + we'll need to put a breakpoint at the branch destination, and + another at the instruction after the branch. */ + struct breakpoint *single_step_breakpoints; + /* Range to single step within. If this is nonzero, respond to a single-step signal by continuing @@ -75,24 +70,29 @@ struct thread_info step for a single instruction (FIXME: it might clean up wait_for_inferior in a minor way if this were changed to the address of the instruction and that address plus one. But maybe - not.). */ + not). */ 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 + thread stops in the step range above. If this is zero, the + target should ignore the step range, and only issue one single + step. */ + int may_range_step; + /* Stack frame address as of when stepping command was issued. This is how we know when we step into a subroutine call, and how to set the frame for the breakpoint used to step out. */ struct frame_id step_frame_id; - int current_line; - struct symtab *current_symtab; - /* 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 - adjust_pc_after_break to distinguish a hardware single-step - SIGTRAP from a breakpoint SIGTRAP. */ - CORE_ADDR prev_pc; + /* Similarly, the frame ID of the underlying stack frame (skipping + any inlined frames). */ + struct frame_id step_stack_frame_id; /* Nonzero if we are presently stepping over a breakpoint. @@ -118,38 +118,8 @@ struct thread_info by keep_going. */ int trap_expected; - /* Should we step over breakpoint next time keep_going is called? */ - int stepping_over_breakpoint; - - /* Set to TRUE if we should finish single-stepping over a breakpoint - after hitting the current step-resume breakpoint. */ - int step_after_step_resume_breakpoint; - - /* This is set TRUE when a catchpoint of a shared library event - triggers. Since we don't wish to leave the inferior in the - solib hook when we report the event, we step the inferior - back to user code before stopping and reporting the event. */ - int stepping_through_solib_after_catch; - - /* When stepping_through_solib_after_catch is TRUE, this is a - list of the catchpoints that should be reported as triggering - when we finally do stop stepping. */ - bpstat stepping_through_solib_catchpoints; - - /* 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; - /* 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 @@ -161,27 +131,182 @@ struct thread_info /* Nonzero if stopped due to a step command. */ int stop_step; - /* 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; + /* Chain containing status of breakpoint(s) the thread stopped + 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". */ + int stepping_command; +}; + +/* Inferior thread specific part of `struct infcall_suspend_state'. */ + +struct thread_suspend_state +{ + /* Last signal that the inferior received (why it stopped). When + the thread is resumed, this signal is delivered. Note: the + target should not check whether the signal is in pass state, + because the signal may have been explicitly passed with the + "signal" command, which overrides "handle nopass". If the signal + 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; +DEF_VEC_P (value_ptr); +typedef VEC (value_ptr) value_vec; + +struct thread_info +{ + struct thread_info *next; + ptid_t ptid; /* "Actual process id"; + In fact, this may be overloaded with + kernel thread id, etc. */ + int num; /* Convenient handle (GDB thread id) */ + + /* 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; + + /* 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; + + /* 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, + 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; + + /* State of GDB control of inferior thread execution. + See `struct thread_control_state'. */ + struct 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; + + int current_line; + struct symtab *current_symtab; + + /* Internal stepping state. */ + + /* 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; + + /* 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; + + /* Should we step over breakpoint next time keep_going is called? */ + int stepping_over_breakpoint; + + /* 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; + + /* Set to TRUE if we should finish single-stepping over a breakpoint + after hitting the current step-resume breakpoint. The context here + is that GDB is to do `next' or `step' while signal arrives. + When stepping over a breakpoint and signal arrives, GDB will attempt + to skip signal handler, so it inserts a step_resume_breakpoint at the + signal return address, and resume inferior. + 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; + + /* 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 resume of the thread, and not immediately. */ struct target_waitstatus pending_follow; - /* Last signal that the inferior received (why it stopped). */ - enum target_signal stop_signal; - - /* Chain containing status of breakpoint(s) the thread stopped - at. */ - bpstat stop_bpstat; - /* True if this thread has been explicitly requested to stop. */ int stop_requested; + /* 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; + /* 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. */ + void (*private_dtor) (struct private_thread_info *); + + /* 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; + + /* 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. */ @@ -209,9 +334,25 @@ extern void delete_thread (ptid_t); exited, for example. */ extern void delete_thread_silent (ptid_t); -/* Delete a step_resume_breakpoint from the thread database. */ +/* Delete a step_resume_breakpoint from the thread database. */ extern void delete_step_resume_breakpoint (struct thread_info *); +/* Delete an exception_resume_breakpoint from the thread database. */ +extern void delete_exception_resume_breakpoint (struct thread_info *); + +/* Delete the single-step breakpoints of thread TP, if any. */ +extern void delete_single_step_breakpoints (struct thread_info *tp); + +/* Check if the thread has software single stepping breakpoints + set. */ +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, + CORE_ADDR addr); + /* Translate the 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 thread_id_to_pid (int); @@ -238,6 +379,14 @@ struct thread_info *find_thread_id (int num); returns the first thread in the list. */ struct thread_info *first_thread_of_process (int pid); +/* Returns any thread of process PID, giving preference to the current + thread. */ +extern struct thread_info *any_thread_of_process (int pid); + +/* Returns any non-exited thread of process PID, giving preference to + the current thread, and to not executing threads. */ +extern struct thread_info *any_live_thread_of_process (int pid); + /* Change the ptid of thread OLD_PTID to NEW_PTID. */ void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); @@ -246,13 +395,32 @@ void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); typedef int (*thread_callback_func) (struct thread_info *, void *); extern struct thread_info *iterate_over_threads (thread_callback_func, void *); +/* Traverse all threads, except those that have THREAD_EXITED + state. */ + +#define ALL_NON_EXITED_THREADS(T) \ + for (T = thread_list; T; T = T->next) \ + if ((T)->state != THREAD_EXITED) + +/* 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)) + 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 PIDGET (PTID) is -1, marks all threads. */ + If PTID is minus_one_ptid, marks all threads. */ extern void set_running (ptid_t ptid, int running); /* Marks or clears thread(s) PTID as having been requested to stop. @@ -287,20 +455,20 @@ extern int is_exited (ptid_t ptid); /* In the frontend's perpective, is this thread stopped? */ extern int is_stopped (ptid_t ptid); -/* In the frontend's perpective is there any thread running? */ -extern int any_running (void); - -/* Marks thread PTID as executing, or not. If PIDGET (PTID) is -1, +/* Marks thread PTID as executing, or not. If PTID is minus_one_ptid, marks all threads. Note that this is different from the running state. See the - description of state_ and executing_ fields of struct + description of state and executing fields of struct 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); + /* Merge the executing property of thread PTID over to its thread state property (frontend running/stopped view). @@ -308,7 +476,7 @@ extern int is_executing (ptid_t ptid); "executing" -> "running" "exited" -> "exited" - If PIDGET (PTID) is -1, go over all threads. + If PTID is minus_one_ptid, go over all threads. Notifications are only emitted if the thread state did change. */ extern void finish_thread_state (ptid_t ptid); @@ -321,11 +489,13 @@ extern void finish_thread_state_cleanup (void *ptid_p); /* 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 print_thread_info (struct ui_out *uiout, int thread, +extern void print_thread_info (struct ui_out *uiout, char *threads, int pid); extern struct cleanup *make_cleanup_restore_current_thread (void); @@ -334,4 +504,52 @@ extern struct cleanup *make_cleanup_restore_current_thread (void); INFERIOR_PTID. INFERIOR_PTID *must* be in the thread list. */ extern struct thread_info* inferior_thread (void); +extern void update_thread_list (void); + +/* Delete any thread the target says is no longer alive. */ + +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 struct cleanup *enable_thread_stack_temporaries (ptid_t ptid); + +extern int thread_stack_temporaries_enabled_p (ptid_t ptid); + +extern void push_thread_stack_temporary (ptid_t ptid, struct value *v); + +extern struct value *get_last_thread_stack_temporary (ptid_t); + +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 */