Fix problem with StackwalkerAPI create on SLURM (LLNL) systems.
[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_setreg_ack,
143   dbg_attached,
144   dbg_thread_info,
145   dbg_detached      // 15
146 } dbg_t;
147
148 class ProcDebug;
149
150 struct DebugEvent {
151    dbg_t dbg;
152    union {
153       int idata;
154       void *pdata;
155    } data;
156    unsigned size;
157    ProcDebug *proc;
158    ThreadState *thr;
159
160    DebugEvent() : dbg(dbg_noevent), size(0), proc(NULL), thr(NULL) {}
161 };
162
163 struct procdebug_ltint
164 {
165    bool operator()(int a, int b) const;
166 };
167
168 class ProcDebug : public ProcessState {
169   friend class Walker;
170   friend class ThreadState;
171  protected:
172   ProcDebug(Dyninst::PID pid, std::string executable="");
173   ProcDebug(const std::string &executable, 
174             const std::vector<std::string> &argv);
175   
176   /**
177    * attach() is the top-level command, and is implemented by debug_attach and
178    * debug_waitfor_attach. 
179    **/
180   virtual bool attach();
181   static bool multi_attach(std::vector<ProcDebug *> &pids);
182
183
184   virtual bool debug_attach(ThreadState *ts) = 0;
185   virtual bool debug_waitfor_attach(ThreadState *ts);
186   virtual bool debug_post_attach(ThreadState *ts);
187   virtual bool debug_post_create();
188
189   virtual bool create(const std::string &executable, 
190                       const std::vector<std::string> &argv);
191   virtual bool debug_create(const std::string &executable, 
192                             const std::vector<std::string> &argv) = 0;
193   virtual bool debug_waitfor_create();
194   
195   /**
196    * pause() is the top-level command (under the public section), and is 
197    * implemented by debug_pause() and debug_waitfor_pause()
198    **/
199   virtual bool pause_thread(ThreadState *thr);
200   virtual bool debug_pause(ThreadState *thr) = 0;
201   virtual bool debug_waitfor_pause(ThreadState *thr);
202
203   virtual bool resume_thread(ThreadState *thr);
204   virtual bool debug_continue(ThreadState *thr) = 0;
205   virtual bool debug_continue_with(ThreadState *thr, long sig) = 0;
206   virtual bool debug_waitfor_continue(ThreadState *thr);
207
208   virtual bool debug_handle_signal(DebugEvent *ev) = 0;
209   virtual bool debug_handle_event(DebugEvent ev) = 0;
210
211   static DebugEvent debug_get_event(bool block);
212   static bool debug_wait_and_handle(bool block, bool flush, bool &handled, dbg_t *event_type = NULL);
213
214   static bool debug_waitfor(dbg_t event_type);
215
216   proc_state state();
217   void setState(proc_state p);
218
219  public:
220   
221   static ProcDebug *newProcDebug(Dyninst::PID pid, std::string executable="");
222   static bool newProcDebugSet(const std::vector<Dyninst::PID> &pids,
223                               std::vector<ProcDebug *> &out_set);
224   static ProcDebug *newProcDebug(const std::string &executable, 
225                                  const std::vector<std::string> &argv);
226   virtual ~ProcDebug();
227
228   virtual bool getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID thread, Dyninst::MachRegisterVal &val) = 0;
229   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
230   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &thrds) = 0;
231   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
232   virtual unsigned getAddressWidth() = 0;
233
234   virtual bool preStackwalk(Dyninst::THR_ID tid);
235   virtual bool postStackwalk(Dyninst::THR_ID tid);
236
237   
238   virtual bool pause(Dyninst::THR_ID tid = NULL_THR_ID);
239   virtual bool resume(Dyninst::THR_ID tid = NULL_THR_ID);
240   virtual bool isTerminated();
241
242   virtual bool detach(bool leave_stopped = false) = 0;
243
244   static int getNotificationFD();
245   const std::string& getExecutablePath();
246
247   static bool handleDebugEvent(bool block = false);
248   virtual bool isFirstParty();
249
250   typedef void (*sig_callback_func)(int &signum, ThreadState *thr);
251   void registerSignalCallback(sig_callback_func f);
252
253   virtual Dyninst::Architecture getArchitecture();
254
255  protected:
256   /**
257    * Helper for polling for new threads.  Sees if the thread exists, 
258    * creates a ThreadState if not, and handles errors.  Mechanism for 
259    * finding thread ids is left to derived class.
260    **/
261   virtual bool add_new_thread(Dyninst::THR_ID tid);
262
263   /**
264    * Syntactic sugar for add_new_thread.  Use for adding lots of 
265    * threads from your favorite iterable data structure.
266    **/
267   template <class Iterator>
268   bool add_new_threads(Iterator start, Iterator end) 
269   {
270      bool good = true;
271      for (Iterator i=start; i != end; i++) {
272         if (!add_new_thread(*i)) good = false;
273      }
274      return good;
275   }
276    
277   ThreadState *initial_thread;
278   ThreadState *active_thread;
279   typedef std::map<Dyninst::THR_ID, ThreadState*> thread_map_t;
280   thread_map_t threads;
281   std::string executable_path;
282   sig_callback_func sigfunc;
283  public:
284   static int pipe_in;
285   static int pipe_out;
286 };
287
288 //LibAddrPair.first = path to library, LibAddrPair.second = load address
289 typedef std::pair<std::string, Address> LibAddrPair;
290 typedef enum { library_load, library_unload} lib_change_t;
291 class LibraryState {
292  protected:
293    ProcessState *procstate;
294  public:
295    LibraryState(ProcessState *parent);
296    virtual bool getLibraryAtAddr(Address addr, LibAddrPair &lib) = 0;
297    virtual bool getLibraries(std::vector<LibAddrPair> &libs) = 0;
298    virtual void notifyOfUpdate() = 0;
299    virtual Address getLibTrapAddress() = 0;
300    virtual bool getLibc(LibAddrPair &lc) = 0;
301    virtual bool getLibthread(LibAddrPair &lt) = 0;
302    virtual bool getAOut(LibAddrPair &ao) = 0;
303    virtual ~LibraryState();
304 };
305
306 class ThreadState {
307  public:
308    static ThreadState* createThreadState(ProcDebug *parent, 
309                                          Dyninst::THR_ID id = NULL_THR_ID,
310                                          bool alrady_attached = false);
311    virtual ~ThreadState();
312
313    bool isStopped();
314    void setStopped(bool s);
315    
316    bool userIsStopped();
317    void setUserStopped(bool u);
318
319    bool shouldResume();
320    void setShouldResume(bool r);
321
322    Dyninst::THR_ID getTid();
323
324    proc_state state();
325    void setState(proc_state s);
326    
327    ProcDebug *proc();
328
329    //For internal use only
330    void markPendingStop();
331    void clearPendingStop();
332    bool hasPendingStop();
333 protected:
334    ThreadState(ProcDebug *p, Dyninst::THR_ID id);
335    bool is_stopped;
336    bool user_stopped;
337    bool should_resume;
338    Dyninst::THR_ID tid;
339    proc_state thr_state;
340    ProcDebug *parent;
341    unsigned pending_sigstops;
342 };
343
344 // ----- Useful functors for dealing with ThreadStates. -----
345 // invokes setStopped on the thread.
346 struct set_stopped {
347   bool value;
348   set_stopped(bool v) : value(v) { }
349   void operator()(ThreadState *ts) { ts->setStopped(value); }
350 };
351
352 // Sets thread state.
353 struct set_state {
354   proc_state value;
355   set_state(proc_state v) : value(v) { }
356   void operator()(ThreadState *ts) { ts->setState(value); }
357 };
358
359 // Sets thread state.
360 struct set_should_resume {
361   bool value;
362   set_should_resume(bool v) : value(v) { }
363   void operator()(ThreadState *ts) { ts->setShouldResume(value); }
364 };
365
366 }
367 }
368
369 #endif