Fixes for StackwalkerAPI on BlueGene
[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    std::string exec_path;
58    LibraryState *library_tracker;
59    Walker *walker;
60    static std::map<Dyninst::PID, ProcessState *> proc_map;
61    std::string executable_path;
62
63    ProcessState(Dyninst::PID pid_ = 0, std::string executable_path_ = std::string(""));
64    void setPid(Dyninst::PID pid_);
65 public:
66
67   //look-up Process-State by pid
68   static ProcessState* getProcessStateByPid(Dyninst::PID pid);
69
70   //Read register in thread
71   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val) = 0;
72   
73   //Read memory in process
74   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
75
76   //Return list of available threads
77   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads) = 0;
78   
79   //Return the default thread
80   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
81
82   //Return PID
83   virtual Dyninst::PID getProcessId();
84
85   //Return the size of an address in process in bytes
86   virtual unsigned getAddressWidth() = 0;
87
88   //Get Architecture, see dyn_regs.h
89   virtual Dyninst::Architecture getArchitecture() = 0;
90
91   virtual ~ProcessState();
92
93   Walker *getWalker() const;
94
95   void setLibraryTracker(LibraryState *);
96   void setDefaultLibraryTracker();
97   LibraryState *getLibraryTracker();
98
99   //Allow initialization/uninitialization
100   virtual bool preStackwalk(Dyninst::THR_ID tid);
101   virtual bool postStackwalk(Dyninst::THR_ID tid);
102
103   virtual bool isFirstParty() = 0;
104
105   std::string getExecutablePath();
106 };
107
108 class ProcSelf : public ProcessState {
109  public:
110   ProcSelf(std::string exe_path = std::string(""));
111   void initialize();
112
113   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val);
114   virtual bool readMem(void *dest, Dyninst::Address source, size_t size);
115   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads);
116   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid);
117   virtual unsigned getAddressWidth();
118   virtual bool isFirstParty();
119   virtual Dyninst::Architecture getArchitecture();
120   virtual ~ProcSelf();
121 };
122
123 typedef enum {
124   ps_neonatal,                // 0
125   ps_attached_intermediate,
126   ps_attached,
127   ps_running,
128   ps_exited,
129   ps_errorstate               // 5
130 } proc_state;
131
132 typedef enum {
133   dbg_err,           // 0
134   dbg_exited,
135   dbg_crashed,
136   dbg_stopped,
137   dbg_other,
138   dbg_noevent,      // 5
139   dbg_libraryload,
140   // BG events are below.
141   dbg_continued,
142   dbg_mem_ack,
143   dbg_setmem_ack,
144   dbg_reg_ack,      // 10
145   dbg_allregs_ack,
146   dbg_setreg_ack,
147   dbg_attached,
148   dbg_thread_info,
149   dbg_detached      // 15
150 } dbg_t;
151
152 class ProcDebug;
153
154 struct DebugEvent {
155    dbg_t dbg;
156    union {
157       int idata;
158       void *pdata;
159    } data;
160    unsigned size;
161    ProcDebug *proc;
162    ThreadState *thr;
163
164    DebugEvent() : dbg(dbg_noevent), size(0), proc(NULL), thr(NULL) {}
165 };
166
167 struct procdebug_ltint
168 {
169    bool operator()(int a, int b) const;
170 };
171
172 class ProcDebug : public ProcessState {
173   friend class Walker;
174   friend class ThreadState;
175  protected:
176   ProcDebug(Dyninst::PID pid, std::string executable="");
177   ProcDebug(std::string executable, 
178             const std::vector<std::string> &argv);
179   
180   /**
181    * attach() is the top-level command, and is implemented by debug_attach and
182    * debug_waitfor_attach. 
183    **/
184   virtual bool attach();
185   static bool multi_attach(std::vector<ProcDebug *> &pids);
186
187
188   virtual bool debug_attach(ThreadState *ts) = 0;
189   virtual bool debug_waitfor_attach(ThreadState *ts);
190   virtual bool debug_post_attach(ThreadState *ts);
191   virtual bool debug_post_create();
192
193   virtual bool create(std::string executable, 
194                       const std::vector<std::string> &argv);
195   virtual bool debug_create(std::string executable, 
196                             const std::vector<std::string> &argv) = 0;
197   virtual bool debug_waitfor_create();
198   
199   /**
200    * pause() is the top-level command (under the public section), and is 
201    * implemented by debug_pause() and debug_waitfor_pause()
202    **/
203   virtual bool pause_thread(ThreadState *thr);
204   virtual bool debug_pause(ThreadState *thr) = 0;
205   virtual bool debug_waitfor_pause(ThreadState *thr);
206
207   virtual bool resume_thread(ThreadState *thr);
208   virtual bool debug_continue(ThreadState *thr) = 0;
209   virtual bool debug_continue_with(ThreadState *thr, long sig) = 0;
210   virtual bool debug_waitfor_continue(ThreadState *thr);
211
212   virtual bool debug_handle_signal(DebugEvent *ev) = 0;
213   virtual bool debug_handle_event(DebugEvent ev) = 0;
214
215   static DebugEvent debug_get_event(bool block);
216   static bool debug_wait_and_handle(bool block, bool flush, bool &handled, dbg_t *event_type = NULL);
217
218   static bool debug_waitfor(dbg_t event_type);
219
220   proc_state state();
221   void setState(proc_state p);
222
223  public:
224   
225   static ProcDebug *newProcDebug(Dyninst::PID pid, std::string executable="");
226   static bool newProcDebugSet(const std::vector<Dyninst::PID> &pids,
227                               std::vector<ProcDebug *> &out_set);
228   static ProcDebug *newProcDebug(std::string executable, 
229                                  const std::vector<std::string> &argv);
230   virtual ~ProcDebug();
231
232   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val) = 0;
233   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
234   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &thrds) = 0;
235   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
236   virtual unsigned getAddressWidth() = 0;
237
238   virtual bool preStackwalk(Dyninst::THR_ID tid);
239   virtual bool postStackwalk(Dyninst::THR_ID tid);
240
241   
242   virtual bool pause(Dyninst::THR_ID tid = NULL_THR_ID);
243   virtual bool resume(Dyninst::THR_ID tid = NULL_THR_ID);
244   virtual bool isTerminated();
245
246   virtual bool detach(bool leave_stopped = false) = 0;
247
248   static int getNotificationFD();
249
250   static bool handleDebugEvent(bool block = false);
251   virtual bool isFirstParty();
252
253   typedef void (*sig_callback_func)(int &signum, ThreadState *thr);
254   void registerSignalCallback(sig_callback_func f);
255
256   virtual Dyninst::Architecture getArchitecture();
257
258  protected:
259   /**
260    * Helper for polling for new threads.  Sees if the thread exists, 
261    * creates a ThreadState if not, and handles errors.  Mechanism for 
262    * finding thread ids is left to derived class.
263    **/
264   virtual bool add_new_thread(Dyninst::THR_ID tid);
265
266   /**
267    * Syntactic sugar for add_new_thread.  Use for adding lots of 
268    * threads from your favorite iterable data structure.
269    **/
270   template <class Iterator>
271   bool add_new_threads(Iterator start, Iterator end) 
272   {
273      bool good = true;
274      for (Iterator i=start; i != end; i++) {
275         if (!add_new_thread(*i)) good = false;
276      }
277      return good;
278   }
279    
280   ThreadState *initial_thread;
281   ThreadState *active_thread;
282   typedef std::map<Dyninst::THR_ID, ThreadState*> thread_map_t;
283   thread_map_t threads;
284   sig_callback_func sigfunc;
285  public:
286   static int pipe_in;
287   static int pipe_out;
288 };
289
290 //LibAddrPair.first = path to library, LibAddrPair.second = load address
291 typedef std::pair<std::string, Address> LibAddrPair;
292 typedef enum { library_load, library_unload} lib_change_t;
293 class LibraryState {
294  protected:
295    ProcessState *procstate;
296  public:
297    LibraryState(ProcessState *parent);
298    virtual bool getLibraryAtAddr(Address addr, LibAddrPair &lib) = 0;
299    virtual bool getLibraries(std::vector<LibAddrPair> &libs) = 0;
300    virtual void notifyOfUpdate() = 0;
301    virtual Address getLibTrapAddress() = 0;
302    virtual bool getLibc(LibAddrPair &lc) = 0;
303    virtual bool getLibthread(LibAddrPair &lt) = 0;
304    virtual bool getAOut(LibAddrPair &ao) = 0;
305    virtual ~LibraryState();
306 };
307
308 class ThreadState {
309  public:
310    static ThreadState* createThreadState(ProcDebug *parent, 
311                                          Dyninst::THR_ID id = NULL_THR_ID,
312                                          bool alrady_attached = false);
313    virtual ~ThreadState();
314
315    bool isStopped();
316    void setStopped(bool s);
317    
318    bool userIsStopped();
319    void setUserStopped(bool u);
320
321    bool shouldResume();
322    void setShouldResume(bool r);
323
324    Dyninst::THR_ID getTid();
325
326    proc_state state();
327    void setState(proc_state s);
328    
329    ProcDebug *proc();
330
331    //For internal use only
332    void markPendingStop();
333    void clearPendingStop();
334    bool hasPendingStop();
335 protected:
336    ThreadState(ProcDebug *p, Dyninst::THR_ID id);
337    bool is_stopped;
338    bool user_stopped;
339    bool should_resume;
340    Dyninst::THR_ID tid;
341    proc_state thr_state;
342    ProcDebug *parent;
343    unsigned pending_sigstops;
344 };
345
346 // ----- Useful functors for dealing with ThreadStates. -----
347 // invokes setStopped on the thread.
348 struct set_stopped {
349   bool value;
350   set_stopped(bool v) : value(v) { }
351   void operator()(ThreadState *ts) { ts->setStopped(value); }
352 };
353
354 // Sets thread state.
355 struct set_state {
356   proc_state value;
357   set_state(proc_state v) : value(v) { }
358   void operator()(ThreadState *ts) { ts->setState(value); }
359 };
360
361 // Sets thread state.
362 struct set_should_resume {
363   bool value;
364   set_should_resume(bool v) : value(v) { }
365   void operator()(ThreadState *ts) { ts->setShouldResume(value); }
366 };
367
368 }
369 }
370
371 #endif