X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdbthread.h;h=cd24eaf2fb08e57aae782c55caa635b3cfb0e95b;hb=080017175b5248f1e5b0d48a55a06634244db459;hp=653dd65c16a15318934a832678f5b23b1fb6ea69;hpb=1996fae84682e8ddd146215dd2959ad1ec924c09;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 653dd65c16..cd24eaf2fb 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -1,121 +1,355 @@ /* Multi-process/thread control defs for GDB, the GNU debugger. - Copyright 1987, 88, 89, 90, 91, 92, 1993, 1998 - + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1997, 1998, 1999, + 2000, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. - Free Software Foundation, Inc. + -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifndef GDBTHREAD_H #define GDBTHREAD_H -/* For bpstat */ +struct symtab; + #include "breakpoint.h" +#include "frame.h" +#include "ui-out.h" +#include "inferior.h" -extern void init_thread_list PARAMS ((void)); +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) */ -extern void add_thread PARAMS ((int pid)); + /* 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_; -extern void delete_thread PARAMS ((int)); - -extern int thread_id_to_pid PARAMS ((int)); + /* 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_; -extern int in_thread_list PARAMS ((int pid)); + /* 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; -extern int pid_to_thread_id PARAMS ((int pid)); + /* User/external stepping state. */ -extern int valid_thread_id PARAMS ((int thread)); + /* Step-resume or longjmp-resume breakpoint. */ + struct breakpoint *step_resume_breakpoint; -extern void load_infrun_state PARAMS ((int, CORE_ADDR *, CORE_ADDR *, char **, - int *, struct breakpoint **, - struct breakpoint **, CORE_ADDR *, - CORE_ADDR *, CORE_ADDR *, int *, int *, - int *, bpstat *, int *)); + /* Range to single step within. -extern void save_infrun_state PARAMS ((int, CORE_ADDR, CORE_ADDR, char *, - int, struct breakpoint *, - struct breakpoint *, CORE_ADDR, - CORE_ADDR, CORE_ADDR, int, int, - int, bpstat, int)); + If this is nonzero, respond to a single-step signal by continuing + to step if the pc is in this range. -/* Commands with a prefix of `thread'. */ -extern struct cmd_list_element *thread_cmd_list; + If step_range_start and step_range_end are both 1, it means to + 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.). */ + CORE_ADDR step_range_start; /* Inclusive */ + CORE_ADDR step_range_end; /* Exclusive */ -/* Support for external (remote) systems with threads (processes) */ -/* For example real time operating systems */ - -#define OPAQUETHREADBYTES 8 -/* a 64 bit opaque identifier */ -typedef unsigned char threadref[OPAQUETHREADBYTES] ; -/* WARNING: This threadref data structure comes from the remote O.S., libstub - protocol encoding, and remote.c. it is not particularly changable */ + /* 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; -/* Right now, the internal structure is int. We want it to be bigger. - Plan to fix this. - */ -typedef int gdb_threadref ; /* internal GDB thread reference */ + /* Similarly, the frame ID of the underlying stack frame (skipping + any inlined frames). */ + struct frame_id step_stack_frame_id; -/* gdb_ext_thread_info is an internal GDB data structure which is - equivalint to the reply of the remote threadinfo packet */ + int current_line; + struct symtab *current_symtab; -struct gdb_ext_thread_info -{ - threadref threadid ; /* External form of thread reference */ - int active ; /* Has state interesting to GDB? , regs, stack */ - char display[256] ; /* Brief state display, name, blocked/syspended */ - char shortname[32] ; /* To be used to name threads */ - char more_display[256] ; /* Long info, statistics, queue depth, whatever */ -} ; - -/* The volume of remote transfers can be limited by submitting - a mask containing bits specifying the desired information. - Use a union of these values as the 'selection' parameter to - get_thread_info. FIXME: Make these TAG names more thread specific. - */ -#define TAG_THREADID 1 -#define TAG_EXISTS 2 -#define TAG_DISPLAY 4 -#define TAG_THREADNAME 8 -#define TAG_MOREDISPLAY 16 - -/* Always initialize an instance of this structure using run time assignments */ -/* Because we are likely to add entrtries to it. */ -/* Alternatly, WE COULD ADD THESE TO THE TARGET VECTOR */ - -struct target_thread_vector -{ - int (*find_new_threads)PARAMS((void)) ; - int (*get_thread_info) PARAMS(( - gdb_threadref * ref, - int selection, - struct gdb_ext_thread_info * info - )) ; - /* to_thread_alive - Already in the target vector */ - /* to_switch_thread - Done via select frame */ -} ; + /* 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; + + /* 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. */ + 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. */ + int proceed_to_finish; + + /* Nonzero if the thread is being proceeded for an inferior function + call. */ + int in_infcall; + + enum step_over_calls_kind step_over_calls; + + /* 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; + + /* 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; + + /* Private data used by the target vector implementation. */ + struct private_thread_info *private; + + /* 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 *); +}; + +/* Create an empty thread list, or empty the existing one. */ +extern void init_thread_list (void); + +/* Add a thread to the thread list, print a message + that a new thread is found, and return the pointer to + the new thread. Caller my use this pointer to + initialize the private thread data. */ +extern struct thread_info *add_thread (ptid_t ptid); + +/* Same as add_thread, but does not print a message + about new thread. */ +extern struct thread_info *add_thread_silent (ptid_t ptid); + +/* Same as add_thread, and sets the private info. */ +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); + +/* 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); + +/* Delete a step_resume_breakpoint from the thread database. */ +extern void delete_step_resume_breakpoint (struct thread_info *); + +/* 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); + +/* Translate a 'pid' (which may be overloaded with extra thread information) + into the integer thread id (GDB's homegrown id, not the system's). */ +extern int pid_to_thread_id (ptid_t ptid); + +/* Boolean test for an already-known pid (which may be overloaded with + extra thread information). */ +extern int in_thread_list (ptid_t ptid); + +/* Boolean test for an already-known thread id (GDB's homegrown id, + not the system's). */ +extern int valid_thread_id (int thread); + +/* Search function to lookup a thread by 'pid'. */ +extern struct thread_info *find_thread_ptid (ptid_t ptid); + +/* Find thread by GDB user-visible thread number. */ +struct thread_info *find_thread_id (int num); + +/* 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); + +/* Returns any thread of process PID. */ +extern struct thread_info *any_thread_of_process (int pid); + +/* Returns any non-exited thread of process PID, giving preference for + already stopped 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); + +/* Iterator function to call a user-provided callback function + once for each known thread. */ +typedef int (*thread_callback_func) (struct thread_info *, void *); +extern struct thread_info *iterate_over_threads (thread_callback_func, void *); + +extern int thread_count (void); + +/* Switch from one thread to another. */ +extern void switch_to_thread (ptid_t ptid); + +/* Marks thread PTID is running, or stopped. + If PIDGET (PTID) is -1, marks all threads. */ +extern void set_running (ptid_t ptid, int running); + +/* Marks or clears thread(s) PTID as having been requested to stop. + 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. If STOP, then the THREAD_STOP_REQUESTED + observer is called with PTID as argument. */ +extern void set_stop_requested (ptid_t ptid, int stop); + +/* NOTE: Since the thread state is not a boolean, most times, you do + not want to check it with negation. If you really want to check if + the thread is stopped, + + use (good): + + if (is_stopped (ptid)) + + instead of (bad): + + if (!is_running (ptid)) + + The latter also returns true on exited threads, most likelly not + what you want. */ + +/* Reports if in the frontend's perpective, thread PTID is running. */ +extern int is_running (ptid_t ptid); + +/* Is this thread listed, but known to have exited? We keep it listed + (but not visible) until it's safe to delete. */ +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 all threads. + + Note that this is different from the running state. See the + 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); + +/* Merge the executing property of thread PTID over to its thread + state property (frontend running/stopped view). + + "not executing" -> "stopped" + "executing" -> "running" + "exited" -> "exited" + + If PIDGET (PTID) is -1, go over all threads. + + 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); + +/* Commands with a prefix of `thread'. */ +extern struct cmd_list_element *thread_cmd_list; + +/* Print notices on thread events (attach, detach, etc.), set with + `set print thread-events'. */ +extern int print_thread_events; -extern void bind_target_thread_vector PARAMS((struct target_thread_vector * vec)) ; +extern void print_thread_info (struct ui_out *uiout, int thread, + int pid); -extern struct target_thread_vector * unbind_target_thread_vector PARAMS ((void)) ; +extern struct cleanup *make_cleanup_restore_current_thread (void); -extern int target_get_thread_info PARAMS(( - gdb_threadref * ref, - int selection, - struct gdb_ext_thread_info * info)) ; +/* Returns a pointer into the thread_info corresponding to + INFERIOR_PTID. INFERIOR_PTID *must* be in the thread list. */ +extern struct thread_info* inferior_thread (void); +extern void update_thread_list (void); -#endif /* GDBTHREAD_H */ +#endif /* GDBTHREAD_H */