Move the address lookup implementation from SymtabAPI to libcommon, so it can be...
[dyninst.git] / stackwalk / h / procstate.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 //TODO: isRunning(), isStopped()...
33 //TODO: Bug if trying to stop an already stopped process
34
35 #ifndef PROCSTATE_H_
36 #define PROCSTATE_H_
37
38 #include "basetypes.h"
39 #include "dyn_regs.h"
40
41 #include <vector>
42 #include <map>
43 #include <queue>
44 #include <string>
45
46 namespace Dyninst {
47 namespace Stackwalker {
48
49 class LibraryState;
50 class ThreadState;
51 class Walker;
52
53 class ProcessState {
54    friend class Walker;
55 protected:
56    Dyninst::PID pid;
57    LibraryState *library_tracker;
58    Walker *walker;
59    static std::map<Dyninst::PID, ProcessState *> proc_map;
60
61    ProcessState(Dyninst::PID pid_ = 0);
62    void setPid(Dyninst::PID pid_);
63 public:
64
65   //look-up Process-State by pid
66   static ProcessState* getProcessStateByPid(Dyninst::PID pid);
67
68   //Read register in thread
69   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val) = 0;
70   
71   //Read memory in process
72   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
73
74   //Return list of available threads
75   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads) = 0;
76   
77   //Return the default thread
78   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
79
80   //Return PID
81   virtual Dyninst::PID getProcessId();
82
83   //Return the size of an address in process in bytes
84   virtual unsigned getAddressWidth() = 0;
85
86   //Get Architecture, see dyn_regs.h
87   virtual Dyninst::Architecture getArchitecture() = 0;
88
89   virtual ~ProcessState();
90
91   Walker *getWalker() const;
92
93   void setLibraryTracker(LibraryState *);
94   void setDefaultLibraryTracker();
95   LibraryState *getLibraryTracker();
96
97   //Allow initialization/uninitialization
98   virtual bool preStackwalk(Dyninst::THR_ID tid);
99   virtual bool postStackwalk(Dyninst::THR_ID tid);
100
101   virtual bool isFirstParty() = 0;
102 };
103
104 class ProcSelf : public ProcessState {
105  public:
106   ProcSelf();
107   void initialize();
108
109   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val);
110   virtual bool readMem(void *dest, Dyninst::Address source, size_t size);
111   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads);
112   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid);
113   virtual unsigned getAddressWidth();
114   virtual bool isFirstParty();
115   virtual Dyninst::Architecture getArchitecture();
116   virtual ~ProcSelf();
117 };
118
119 typedef enum {
120   ps_neonatal,                // 0
121   ps_attached_intermediate,
122   ps_attached,
123   ps_running,
124   ps_exited,
125   ps_errorstate,              // 5
126 } proc_state;
127
128 typedef enum {
129   dbg_err,           // 0
130   dbg_exited,
131   dbg_crashed,
132   dbg_stopped,
133   dbg_other,
134   dbg_noevent,      // 5
135   dbg_libraryload,
136   // BG events are below.
137   dbg_continued,
138   dbg_mem_ack,
139   dbg_setmem_ack,
140   dbg_reg_ack,      // 10
141   dbg_allregs_ack,
142   dbg_attached,
143   dbg_thread_info,
144 } dbg_t;
145
146 class ProcDebug;
147
148 struct DebugEvent {
149    dbg_t dbg;
150    union {
151       int idata;
152       void *pdata;
153    } data;
154    unsigned size;
155    ProcDebug *proc;
156    ThreadState *thr;
157
158    DebugEvent() : dbg(dbg_noevent), size(0), proc(NULL), thr(NULL) {}
159 };
160
161 struct procdebug_ltint
162 {
163    bool operator()(int a, int b) const;
164 };
165
166 class ProcDebug : public ProcessState {
167   friend class Walker;
168   friend class ThreadState;
169  protected:
170   ProcDebug(Dyninst::PID pid, std::string executable="");
171   ProcDebug(const std::string &executable, 
172             const std::vector<std::string> &argv);
173   
174   /**
175    * attach() is the top-level command, and is implemented by debug_attach and
176    * debug_waitfor_attach. 
177    **/
178   virtual bool attach();
179   static bool multi_attach(std::vector<ProcDebug *> &pids);
180
181
182   virtual bool debug_attach(ThreadState *ts) = 0;
183   virtual bool debug_waitfor_attach(ThreadState *ts);
184   virtual bool debug_post_attach(ThreadState *ts);
185   virtual bool debug_post_create();
186
187   virtual bool create(const std::string &executable, 
188                       const std::vector<std::string> &argv);
189   virtual bool debug_create(const std::string &executable, 
190                             const std::vector<std::string> &argv) = 0;
191   virtual bool debug_waitfor_create();
192   
193   /**
194    * pause() is the top-level command (under the public section), and is 
195    * implemented by debug_pause() and debug_waitfor_pause()
196    **/
197   virtual bool pause_thread(ThreadState *thr);
198   virtual bool debug_pause(ThreadState *thr) = 0;
199   virtual bool debug_waitfor_pause(ThreadState *thr);
200
201   virtual bool resume_thread(ThreadState *thr);
202   virtual bool debug_continue(ThreadState *thr) = 0;
203   virtual bool debug_continue_with(ThreadState *thr, long sig) = 0;
204   virtual bool debug_waitfor_continue(ThreadState *thr);
205
206   virtual bool debug_handle_signal(DebugEvent *ev) = 0;
207   virtual bool debug_handle_event(DebugEvent ev) = 0;
208
209   static DebugEvent debug_get_event(bool block);
210   static bool debug_wait_and_handle(bool block, bool flush, bool &handled, dbg_t *event_type = NULL);
211
212   static bool debug_waitfor(dbg_t event_type);
213
214   proc_state state();
215   void setState(proc_state p);
216
217  public:
218   
219   static ProcDebug *newProcDebug(Dyninst::PID pid, std::string executable="");
220   static bool newProcDebugSet(const std::vector<Dyninst::PID> &pids,
221                               std::vector<ProcDebug *> &out_set);
222   static ProcDebug *newProcDebug(const std::string &executable, 
223                                  const std::vector<std::string> &argv);
224   virtual ~ProcDebug();
225
226   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val) = 0;
227   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
228   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &thrds) = 0;
229   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
230   virtual unsigned getAddressWidth() = 0;
231
232   virtual bool preStackwalk(Dyninst::THR_ID tid);
233   virtual bool postStackwalk(Dyninst::THR_ID tid);
234
235   
236   virtual bool pause(Dyninst::THR_ID tid = NULL_THR_ID);
237   virtual bool resume(Dyninst::THR_ID tid = NULL_THR_ID);
238   virtual bool isTerminated();
239
240   virtual bool detach(bool leave_stopped = false) = 0;
241
242   static int getNotificationFD();
243   const std::string& getExecutablePath();
244
245   static bool handleDebugEvent(bool block = false);
246   virtual bool isFirstParty();
247
248   typedef void (*sig_callback_func)(int &signum, ThreadState *thr);
249   void registerSignalCallback(sig_callback_func f);
250
251   virtual Dyninst::Architecture getArchitecture();
252
253  protected:
254   /**
255    * Helper for polling for new threads.  Sees if the thread exists, 
256    * creates a ThreadState if not, and handles errors.  Mechanism for 
257    * finding thread ids is left to derived class.
258    **/
259   virtual bool add_new_thread(Dyninst::THR_ID tid);
260
261   /**
262    * Syntactic sugar for add_new_thread.  Use for adding lots of 
263    * threads from your favorite iterable data structure.
264    **/
265   template <class Iterator>
266   bool add_new_threads(Iterator start, Iterator end) 
267   {
268      bool good = true;
269      for (Iterator i=start; i != end; i++) {
270         if (!add_new_thread(*i)) good = false;
271      }
272      return good;
273   }
274    
275   ThreadState *initial_thread;
276   ThreadState *active_thread;
277   typedef std::map<Dyninst::THR_ID, ThreadState*> thread_map_t;
278   thread_map_t threads;
279   std::string executable_path;
280   sig_callback_func sigfunc;
281  public:
282   static int pipe_in;
283   static int pipe_out;
284 };
285
286 //LibAddrPair.first = path to library, LibAddrPair.second = load address
287 typedef std::pair<std::string, Address> LibAddrPair;
288 typedef enum { library_load, library_unload} lib_change_t;
289 class LibraryState {
290  protected:
291    ProcessState *procstate;
292  public:
293    LibraryState(ProcessState *parent);
294    virtual bool getLibraryAtAddr(Address addr, LibAddrPair &lib) = 0;
295    virtual bool getLibraries(std::vector<LibAddrPair> &libs) = 0;
296    virtual void notifyOfUpdate() = 0;
297    virtual Address getLibTrapAddress() = 0;
298    virtual ~LibraryState();
299 };
300
301 class ThreadState {
302  public:
303    static ThreadState* createThreadState(ProcDebug *parent, 
304                                          Dyninst::THR_ID id = NULL_THR_ID,
305                                          bool alrady_attached = false);
306    virtual ~ThreadState();
307
308    bool isStopped();
309    void setStopped(bool s);
310    
311    bool userIsStopped();
312    void setUserStopped(bool u);
313
314    bool shouldResume();
315    void setShouldResume(bool r);
316
317    Dyninst::THR_ID getTid();
318
319    proc_state state();
320    void setState(proc_state s);
321    
322    ProcDebug *proc();
323  protected:
324    ThreadState(ProcDebug *p, Dyninst::THR_ID id);
325    bool is_stopped;
326    bool user_stopped;
327    bool should_resume;
328    Dyninst::THR_ID tid;
329    proc_state thr_state;
330    ProcDebug *parent;
331 };
332
333 // ----- Useful functors for dealing with ThreadStates. -----
334 // invokes setStopped on the thread.
335 struct set_stopped {
336   bool value;
337   set_stopped(bool v) : value(v) { }
338   void operator()(ThreadState *ts) { ts->setStopped(value); }
339 };
340
341 // Sets thread state.
342 struct set_state {
343   proc_state value;
344   set_state(proc_state v) : value(v) { }
345   void operator()(ThreadState *ts) { ts->setState(value); }
346 };
347
348 // Sets thread state.
349 struct set_should_resume {
350   bool value;
351   set_should_resume(bool v) : value(v) { }
352   void operator()(ThreadState *ts) { ts->setShouldResume(value); }
353 };
354
355 }
356 }
357
358 #endif