Initial commit of StackwalkerAPI
[dyninst.git] / stackwalk / h / procstate.h
1 /*
2  * Copyright (c) 1996-2007 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 #ifndef PROCSTATE_H_
33 #define PROCSTATE_H_
34
35 #include "basetypes.h"
36
37 #include <vector>
38 #include <map>
39 #include <queue>
40
41 namespace Dyninst {
42 namespace Stackwalker {
43
44 class ProcessState {
45 public:
46   //Read register in thread
47   virtual bool getRegValue(reg_t reg, Dyninst::THR_ID thread, regval_t &val) = 0;
48   
49   //Read memory in process
50   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
51
52   //Return list of available threads
53   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads) = 0;
54   
55   //Return the default thread
56   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
57
58   //Return PID
59   virtual Dyninst::PID getProcessId() = 0;
60
61   //Return the size of an address in process in bytes
62   virtual unsigned getAddressWidth() = 0;
63
64   //Allow initialization/uninitialization
65   virtual void preStackwalk();
66   virtual void postStackwalk();
67   
68   virtual ~ProcessState();
69 };
70
71 class ProcSelf : public ProcessState {
72  protected:
73   Dyninst::PID mypid;
74  public:
75   ProcSelf();
76
77   virtual bool getRegValue(reg_t reg, Dyninst::THR_ID thread, regval_t &val);
78   virtual bool readMem(void *dest, Dyninst::Address source, size_t size);
79   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads);
80   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid);
81   virtual Dyninst::PID getProcessId();
82   virtual unsigned getAddressWidth();
83   virtual ~ProcSelf();
84 };
85
86 typedef enum {
87   ps_neonatal,
88   ps_attached_intermediate,
89   ps_attached,
90   ps_running,
91   ps_exited,
92   ps_errorstate,
93 } proc_state;
94
95 class ProcDebug;
96
97 typedef enum {
98    dbg_err,
99    dbg_exited,
100    dbg_crashed,
101    dbg_stopped,
102    dbg_other,
103    dbg_noevent,
104    //BGL
105    dbg_continued,
106    dbg_mem_ack,
107    dbg_reg_ack,
108    dbg_allregs_ack,
109    dbg_attached,
110 } dbg_t;
111
112 struct DebugEvent {
113    dbg_t dbg;
114    union {
115       int idata;
116       void *pdata;
117    } data;
118    unsigned size;
119    ProcDebug *proc;
120
121    DebugEvent() : dbg(dbg_noevent), size(0), proc(NULL) {}
122 };
123
124 struct procdebug_ltint
125 {
126    bool operator()(int a, int b) const;
127 };
128
129 class ProcDebug : public ProcessState {
130  protected:
131   ProcDebug(Dyninst::PID pid);
132   ProcDebug(const std::string &executable, 
133             const std::vector<std::string> &argv);
134   
135   /**
136    * attach() is the top-level command, and is implemented by debug_attach and
137    * debug_waitfor_attach. 
138    **/
139   virtual bool attach();
140   static bool multi_attach(std::vector<ProcDebug *> &pids);
141
142
143   virtual bool debug_attach() = 0;
144   virtual bool debug_waitfor_attach();
145
146   virtual bool debug_use_intermediate_attach();
147   virtual bool debug_intermediate_attach();
148   virtual bool debug_waitfor_intermediate_attach();
149
150   virtual bool create(const std::string &executable, 
151                       const std::vector<std::string> &argv);
152   virtual bool debug_create(const std::string &executable, 
153                             const std::vector<std::string> &argv) = 0;
154   virtual bool debug_waitfor_create();
155   
156   /**
157    * pause() is the top-level command (under the public section), and is 
158    * implemented by debug_pause() and debug_waitfor_pause()
159    **/
160   virtual bool debug_pause() = 0;
161   virtual bool debug_waitfor_pause();
162
163   virtual bool debug_continue() = 0;
164   virtual bool debug_continue_with(long sig) = 0;
165   virtual bool debug_waitfor_continue();
166
167   virtual bool debug_handle_signal(DebugEvent *ev) = 0;
168   virtual bool debug_handle_event(DebugEvent ev) = 0;
169
170   static DebugEvent debug_get_event(bool block);
171   static bool debug_wait_and_handle(bool block, bool &handled);
172  public:
173   
174   static ProcDebug *newProcDebug(Dyninst::PID pid);
175   static bool newProcDebugSet(const std::vector<Dyninst::PID> &pids,
176                               std::vector<ProcDebug *> &out_set);
177   static ProcDebug *newProcDebug(const std::string &executable, 
178                                  const std::vector<std::string> &argv);
179   virtual ~ProcDebug();
180
181   virtual bool getRegValue(reg_t reg, Dyninst::THR_ID thread, regval_t &val) = 0;
182   virtual bool readMem(void *dest, Dyninst::Address source, size_t size) = 0;
183   virtual bool getThreadIds(std::vector<Dyninst::THR_ID> &threads) = 0;
184   virtual bool getDefaultThread(Dyninst::THR_ID &default_tid) = 0;
185   virtual unsigned getAddressWidth() = 0;
186
187   virtual Dyninst::PID getProcessId();
188   virtual void preStackwalk();
189   virtual void postStackwalk();
190
191   
192   virtual bool pause();
193   virtual bool resume();
194   virtual bool isTerminated();
195
196   static int getNotificationFD();
197   static bool handleDebugEvent(bool block = false);
198  protected:
199   proc_state state;
200   bool isRunning;
201   bool user_isRunning;
202   bool should_resume;
203   Dyninst::PID pid;
204   static std::map<Dyninst::PID, ProcDebug *, procdebug_ltint> proc_map;
205  public:
206   static int pipe_in;
207   static int pipe_out;
208 };
209
210 }
211 }
212
213 #endif