Merge branch 'dyn_pc_integration' of ssh://wasabi.cs.wisc.edu/p/paradyn/development...
[dyninst.git] / dyninstAPI / src / pcProcess.h
1 /*
2  * Copyright (c) 1996-2010 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 PCPROCESS_H
33 #define PCPROCESS_H
34 /*
35  * pcProcess.h
36  *
37  * A class that encapsulates a ProcControlAPI Process for the rest of Dyninst.
38  */
39
40 #include <string>
41 #include <map>
42 #include <set>
43
44 #include "addressSpace.h"
45 #include "pcThread.h"
46 #include "pcEventHandler.h"
47 #include "BPatch_hybridAnalysis.h"
48 #include "inst.h"
49 #include "codeRange.h"
50 #include "infHeap.h"
51 #include "ast.h"
52 #include "syscallNotification.h"
53 #include "os.h"
54 #include "baseTramp.h"
55
56 #include "Symtab.h"
57
58 #include "proccontrol/h/Process.h"
59 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
60 #include "stackwalk/h/walker.h"
61 #include "stackwalk/h/framestepper.h"
62 #include "stackwalk/h/symlookup.h"
63
64 #define RPC_LEAVE_AS_IS 0
65 #define RPC_RUN_WHEN_DONE 1
66 #define RPC_STOP_WHEN_DONE 2
67
68 class multiTramp;
69 class bblInstance;
70
71 class PCProcess : public AddressSpace {
72     // Why PCEventHandler is a friend
73     // 
74     // PCProcess needs two interfaces: one that the rest of Dyninst sees and
75     // one that can be used to update the state of the PCProcess during event
76     // handling.
77     //
78     // The argument for having two different interfaces is that it will keep
79     // process control internals from bleeding out into the rest of Dyninst.
80     // This allows changes to the internals to have relatively low impact on the
81     // rest of Dyninst
82     friend class PCEventHandler;
83
84 public:
85     // The desired state of the process, as indicated by the user
86     typedef enum {
87         ps_stopped,
88         ps_running,
89     } processState_t;
90
91     // Process creation and control
92     static PCProcess *createProcess(const std::string file, pdvector<std::string> &argv,
93                                     BPatch_hybridMode analysisMode,
94                                     pdvector<std::string> &envp,
95                                     const std::string dir, int stdin_fd, int stdout_fd,
96                                     int stderr_fd, PCEventHandler *eventHandler);
97
98     static PCProcess *attachProcess(const std::string &progpath, int pid,
99                                     BPatch_hybridMode analysisMode, 
100                                     PCEventHandler *eventHandler);
101     ~PCProcess();
102
103     static std::string createExecPath(const std::string &file, const std::string &dir);
104
105     bool continueProcess();
106     bool stopProcess();
107     bool terminateProcess();
108     bool detachProcess(bool cont);
109
110     // Process status
111     bool isBootstrapped() const; // true if Dyninst has finished it's initialization for the process
112     bool isAttached() const; // true if ok to operate on the process
113     bool isStopped() const; // true if the process is stopped
114     bool isTerminated() const; // true if the process is terminated ( either via normal exit or crash )
115     bool hasExitedNormally() const; // true if the process has exited (via a normal exit)
116     bool isExecing() const; // true if the process is in the middle of an exec
117     processState_t getDesiredProcessState() const;
118     void setDesiredProcessState(processState_t ps);
119
120     // Memory access
121     bool dumpCore(const std::string coreFile); // platform-specific
122     bool writeDataSpace(void *inTracedProcess,
123                         u_int amount, const void *inSelf);
124     bool writeDataWord(void *inTracedProcess,
125                        u_int amount, const void *inSelf);
126     bool readDataSpace(const void *inTracedProcess, u_int amount,
127                        void *inSelf, bool displayErrMsg);
128     bool readDataWord(const void *inTracedProcess, u_int amount,
129                       void *inSelf, bool displayErrMsg);
130     bool writeTextSpace(void *inTracedProcess, u_int amount, const void *inSelf);
131     bool writeTextWord(void *inTracedProcess, u_int amount, const void *inSelf);
132     bool readTextSpace(const void *inTracedProcess, u_int amount,
133                        void *inSelf);
134     bool readTextWord(const void *inTracedProcess, u_int amount,
135                       void *inSelf);
136
137     // Process properties and fields
138     PCThread *getInitialThread() const;
139     PCThread *getThread(dynthread_t tid) const;
140     void getThreads(std::vector<PCThread* > &threads) const;
141     void addThread(PCThread *thread);
142     bool removeThread(dynthread_t tid);
143
144     int getPid() const;
145     unsigned getAddressWidth() const;
146     bool wasRunningWhenAttached() const;
147     bool wasCreatedViaAttach() const;
148     bool wasCreatedViaFork() const;
149     PCEventHandler *getPCEventHandler() const;
150     int incrementThreadIndex();
151
152     // Stackwalking
153     bool walkStacks(pdvector<pdvector<Frame> > &stackWalks);
154     bool getAllActiveFrames(pdvector<Frame> &activeFrames);
155
156     // Inferior Malloc
157     Address inferiorMalloc(unsigned size, inferiorHeapType type=anyHeap,
158                            Address near_=0, bool *err=NULL);
159     void inferiorMallocConstraints(Address near, Address &lo, Address &hi,
160                                    inferiorHeapType /* type */); // platform-specific
161     virtual void inferiorFree(Dyninst::Address);
162     virtual bool inferiorRealloc(Dyninst::Address, unsigned int);
163
164     // Instrumentation support
165     virtual void deleteGeneratedCode(generatedCodeObject *del);
166     bool mappedObjIsDeleted(mapped_object *obj);
167     void installInstrRequests(const pdvector<instMapping*> &requests);
168     bool uninstallMutations();
169     bool reinstallMutations();
170     Address getTOCoffsetInfo(Address dest); // platform-specific
171     Address getTOCoffsetInfo(int_function *func); // platform-specific
172     bool getOPDFunctionAddr(Address &opdAddr); // architecture-specific
173
174     // iRPC interface
175     bool postIRPC(AstNodePtr action,
176                  void *userData,
177                  bool runProcessWhenDone,
178                  PCThread *thread,
179                  bool synchronous,
180                  void **result,
181                  bool userRPC,
182                  bool isMemAlloc = false,
183                  Address addr = 0);
184
185     // Hybrid Mode
186     BPatch_hybridMode getHybridMode();
187
188     // platform-specific
189     int setMemoryAccessRights(Address start, Address size, int rights);
190
191     // code overwrites
192     bool getOverwrittenBlocks(std::map<Address, unsigned char *>& overwrittenPages,//input
193                               std::map<Address,Address>& overwrittenRegions,//output
194                               std::set<bblInstance *> &writtenBBIs); //output
195     bool getDeadCodeFuncs(std::set<bblInstance *> &deadBlocks, // input
196                           std::set<int_function*> &affectedFuncs, //output
197                           std::set<int_function*> &deadFuncs); //output
198     unsigned getMemoryPageSize() const;
199
200
201     // synch modified mapped objects with current memory contents
202     mapped_object *createObjectNoFile(Address addr);
203     void updateMappedFile(std::map<Dyninst::Address,unsigned char*>& owPages,
204                           std::map<Address,Address> owRegions);
205
206     bool isRuntimeHeapAddr(Address addr) const;
207     bool isExploratoryModeOn() const;
208
209     bool hideDebugger(); // platform-specific
210
211     // Active instrumentation tracking
212     int_function *findActiveFuncByAddr(Address addr);
213     void getActiveMultiMap(std::map<Address, multiTramp *> &map);
214     void updateActiveMultis();
215     void addActiveMulti(multiTramp *multi);
216     void fixupActiveStackTargets();
217     void invalidateActiveMultis() { isAMcacheValid_ = false; }
218
219     // No function is pushed onto return vector if address can't be resolved
220     // to a function
221     pdvector<int_function *> pcsToFuncs(pdvector<Frame> stackWalk);
222
223     // architecture-specific
224     virtual bool hasBeenBound(const SymtabAPI::relocationEntry &entry, 
225                            int_function *&target_pdf, Address base_addr);
226
227     // AddressSpace implementations //
228     virtual Address offset() const;
229     virtual Address length() const;
230     virtual Architecture getArch() const;
231     virtual bool multithread_capable(bool ignoreIfMtNotSet = false); // platform-specific
232     virtual bool multithread_ready(bool ignoreIfMtNotSet = false);
233     virtual bool needsPIC();
234     virtual bool registerTrapMapping(Address from, Address to);
235     virtual bool unregisterTrapMapping(Address from);
236
237     // Miscellaneuous
238     void debugSuicide();
239     bool dumpImage(std::string outFile);
240
241     Address setAOutLoadAddress(fileDescriptor &desc); // platform-specific
242
243     // Stackwalking internals
244     bool walkStack(pdvector<Frame> &stackWalk, PCThread *thread);
245     bool getActiveFrame(Frame &frame, PCThread *thread);
246
247     void addSignalHandler(Address, unsigned);
248     bool isInSignalHandler(Address addr);
249
250 protected:
251     typedef enum {
252         bs_attached,
253         bs_readyToLoadRTLib,
254         bs_initialized // RT library has been loaded
255     } bootstrapState_t;
256     
257     typedef enum {
258         not_cached,
259         cached_mt_true,
260         cached_mt_false
261     } mt_cache_result_t;
262
263     static PCProcess *setupExecedProcess(PCProcess *proc, std::string execPath);
264
265     // Process create/exec constructor
266     PCProcess(ProcControlAPI::Process::ptr pcProc, std::string file,
267             BPatch_hybridMode analysisMode, PCEventHandler *eventHandler)
268         : pcProc_(pcProc),
269           parent_(NULL),
270           initialThread_(NULL), 
271           file_(file), 
272           attached_(true),
273           execing_(false),
274           exiting_(false),
275           runningWhenAttached_(false), 
276           createdViaAttach_(false),
277           processState_(ps_stopped),
278           bootstrapState_(bs_attached),
279           main_function_(NULL),
280           curThreadIndex_(0),
281           reportedEvent_(false),
282           savedPid_(pcProc->getPid()),
283           savedArch_(pcProc->getArchitecture()),
284           analysisMode_(analysisMode), 
285           memoryPageSize_(0),
286           isAMcacheValid_(false),
287           sync_event_id_addr_(0),
288           sync_event_arg1_addr_(0),
289           sync_event_arg2_addr_(0),
290           sync_event_arg3_addr_(0),
291           sync_event_breakpoint_addr_(0),
292           eventHandler_(eventHandler),
293           eventCount_(0),
294           tracedSyscalls_(NULL),
295           rtLibLoadHeap_(0),
296           mt_cache_result_(not_cached),
297           isInDebugSuicide_(false),
298           irpcTramp_(NULL),
299           inEventHandling_(false),
300           stackwalker_(NULL)
301     {
302         irpcTramp_ = new baseTramp(NULL, callUnset);
303         irpcTramp_->setRecursive(true);
304         irpcTramp_->setIRPCTramp(true);
305     }
306
307     // Process attach constructor
308     PCProcess(ProcControlAPI::Process::ptr pcProc, BPatch_hybridMode analysisMode,
309             PCEventHandler *eventHandler)
310         : pcProc_(pcProc),
311           parent_(NULL),
312           initialThread_(NULL), 
313           attached_(true), 
314           execing_(false),
315           exiting_(false),
316           runningWhenAttached_(false), 
317           createdViaAttach_(true),
318           processState_(ps_stopped),
319           bootstrapState_(bs_attached), 
320           main_function_(NULL),
321           curThreadIndex_(0),
322           reportedEvent_(false),
323           savedPid_(pcProc->getPid()),
324           savedArch_(pcProc->getArchitecture()),
325           analysisMode_(analysisMode), 
326           memoryPageSize_(0),
327           isAMcacheValid_(false),
328           sync_event_id_addr_(0),
329           sync_event_arg1_addr_(0),
330           sync_event_arg2_addr_(0),
331           sync_event_arg3_addr_(0),
332           sync_event_breakpoint_addr_(0),
333           eventHandler_(eventHandler),
334           eventCount_(0),
335           tracedSyscalls_(NULL),
336           rtLibLoadHeap_(0),
337           mt_cache_result_(not_cached),
338           isInDebugSuicide_(false),
339           irpcTramp_(NULL),
340           inEventHandling_(false),
341           stackwalker_(NULL)
342     {
343         irpcTramp_ = new baseTramp(NULL, callUnset);
344         irpcTramp_->setRecursive(true);
345         irpcTramp_->setIRPCTramp(true);
346     }
347
348     static PCProcess *setupForkedProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc);
349
350     // Process fork constructor
351     PCProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc)
352         : pcProc_(pcProc),
353           parent_(parent),
354           initialThread_(NULL), // filled in during bootstrap
355           file_(parent->file_),
356           attached_(true), 
357           execing_(false),
358           exiting_(false),
359           runningWhenAttached_(false), 
360           createdViaAttach_(false),
361           processState_(ps_stopped),
362           bootstrapState_(bs_attached), 
363           main_function_(parent->main_function_),
364           curThreadIndex_(0), // threads are created from ProcControl threads
365           reportedEvent_(false),
366           savedPid_(pcProc->getPid()),
367           savedArch_(pcProc->getArchitecture()),
368           analysisMode_(parent->analysisMode_), 
369           memoryPageSize_(parent->memoryPageSize_),
370           isAMcacheValid_(parent->isAMcacheValid_),
371           sync_event_id_addr_(parent->sync_event_id_addr_),
372           sync_event_arg1_addr_(parent->sync_event_arg1_addr_),
373           sync_event_arg2_addr_(parent->sync_event_arg2_addr_),
374           sync_event_arg3_addr_(parent->sync_event_arg3_addr_),
375           sync_event_breakpoint_addr_(parent->sync_event_breakpoint_addr_),
376           eventHandler_(parent->eventHandler_),
377           eventCount_(0),
378           tracedSyscalls_(NULL), // filled after construction
379           rtLibLoadHeap_(parent->rtLibLoadHeap_),
380           mt_cache_result_(parent->mt_cache_result_),
381           isInDebugSuicide_(parent->isInDebugSuicide_),
382           irpcTramp_(NULL), // filled after construction
383           inEventHandling_(false),
384           stackwalker_(NULL)
385     {
386     }
387
388     // bootstrapping
389     bool bootstrapProcess();
390     bool hasReachedBootstrapState(bootstrapState_t state) const;
391     void setBootstrapState(bootstrapState_t newState);
392     bool createStackwalker();
393     bool createStackwalkerSteppers(); // platform-specific
394     void createInitialThreads();
395     bool createInitialMappedObjects();
396     bool getExecFileDescriptor(std::string filename,
397                                bool waitForTrap, // Should we wait for process init
398                                fileDescriptor &desc);
399     void findSignalHandler(mapped_object *obj);
400     void setMainFunction();
401     bool setAOut(fileDescriptor &desc);
402     bool hasPassedMain(); // OS-specific
403     bool insertBreakpointAtMain();
404     ProcControlAPI::Breakpoint::ptr getBreakpointAtMain() const;
405     bool removeBreakpointAtMain();
406     Address getLibcStartMainParam(PCThread *thread); // architecture-specific
407     bool copyDanglingMemory(PCProcess *parent);
408     void invalidateMTCache();
409
410     // RT library management
411     bool loadRTLib();
412     AstNodePtr createLoadRTAST(); // architecture-specific
413     AstNodePtr createUnprotectStackAST(); // architecture-specific
414     bool setRTLibInitParams();
415     bool instrumentMTFuncs();
416     bool initTrampGuard();
417     Address findFunctionToHijack(); // OS-specific
418     bool postRTLoadCleanup(); // architecture-specific
419     bool extractBootstrapStruct(DYNINST_bootstrapStruct *bs_record);
420     bool iRPCDyninstInit();
421     bool registerThread(PCThread *thread);
422     bool unregisterThread(dynthread_t tid);
423
424     Address getRTEventBreakpointAddr();
425     Address getRTEventIdAddr();
426     Address getRTEventArg1Addr();
427     Address getRTEventArg2Addr();
428     Address getRTEventArg3Addr();
429
430     // Shared library managment
431     void addASharedObject(mapped_object *newObj);
432     void removeASharedObject(mapped_object *oldObj);
433     bool usesDataLoadAddress() const; // OS-specific
434
435     // Inferior heap management
436     void addInferiorHeap(mapped_object *obj);
437     bool skipHeap(const heapDescriptor &heap); // platform-specific
438     bool inferiorMallocDynamic(int size, Address lo, Address hi);
439
440     // platform-specific (TODO AIX is dataHeap, everything else is anyHeap)
441     inferiorHeapType getDynamicHeapType() const; 
442     
443     // garbage collection instrumentation
444     void gcInstrumentation();
445     void gcInstrumentation(pdvector<pdvector<Frame> > &stackWalks);
446
447     // Hybrid Mode
448     bool triggerStopThread(Address pointAddress, int callbackID, void *calculation);
449     Address stopThreadCtrlTransfer(instPoint *intPoint, Address target);
450
451     // Event Handling
452     void triggerNormalExit(int exitcode);
453
454     // Misc
455
456     // platform-specific, populates the passed map, if the file descriptors differ
457     static void redirectFds(int stdin_fd, int stdout_fd, int stderr_fd, 
458             std::map<int, int> &result);
459
460     // platform-specific, sets LD_PRELOAD with RT library 
461     static bool setEnvPreload(pdvector<std::string> &envp, std::string fileName);
462
463     bool isInDebugSuicide() const;
464     void setReportingEvent(bool b);
465     bool hasReportedEvent() const;
466     void setExecing(bool b);
467     bool isInEventHandling() const;
468     void setInEventHandling(bool b);
469     void setExiting(bool b);
470     bool isExiting() const;
471     bool hasPendingEvents();
472     void incPendingEvents();
473     void decPendingEvents();
474     bool hasRunningSyncRPC() const;
475     void addSyncRPCThread(PCThread *thr);
476     void removeSyncRPCThread(PCThread *thr);
477     bool continueSyncRPCThreads();
478
479     // ProcControl doesn't keep around a process's information after it exits.
480     // However, we allow a Dyninst user to query certain information out of
481     // an exited process. Just make sure no operations are attempted on the
482     // ProcControl process
483     void markExited();
484
485     // Debugging
486     bool setBreakpoint(Address addr);
487     void writeDebugDataSpace(void *inTracedProcess, u_int amount,
488             const void *inSelf);
489     bool startDebugger(); // platform-specific
490
491     // Fields //
492
493     // Underlying ProcControl process
494     ProcControlAPI::Process::ptr pcProc_;
495     PCProcess *parent_;
496
497     // Corresponding threads
498     std::map<dynthread_t, PCThread *> threadsByTid_;
499     PCThread *initialThread_;
500
501     ProcControlAPI::Breakpoint::ptr mainBrkPt_;
502
503     // Properties
504     std::string file_;
505     bool attached_;
506     bool execing_;
507     bool exiting_;
508     bool runningWhenAttached_;
509     bool createdViaAttach_;
510     processState_t processState_;
511     bootstrapState_t bootstrapState_;
512     int_function *main_function_;
513     int curThreadIndex_;
514     // true when Dyninst has reported an event to ProcControlAPI for this process
515     bool reportedEvent_; // indicates the process should remain stopped
516     int savedPid_; // ProcControl doesn't keep around Process objects after exit
517     Dyninst::Architecture savedArch_;
518
519     // Hybrid Analysis
520     BPatch_hybridMode analysisMode_;
521     int memoryPageSize_;
522
523     // Active instrumentation tracking
524     bool isAMcacheValid_;
525     std::set<multiTramp *> activeMultis_;
526     std::map<bblInstance *, Address> activeBBIs_;
527     std::map<int_function *, std::set<Address> *> am_funcRelocs_;
528
529     codeRangeTree signalHandlerLocations_;
530     pdvector<mapped_object *> deletedObjects_;
531     std::vector<heapItem *> dyninstRT_heaps_;
532     pdvector<generatedCodeObject *> pendingGCInstrumentation_;
533
534     // Addresses of variables in RT library
535     Address sync_event_id_addr_;
536     Address sync_event_arg1_addr_;
537     Address sync_event_arg2_addr_;
538     Address sync_event_arg3_addr_;
539     Address sync_event_breakpoint_addr_;
540
541     // The same PCEventHandler held by the BPatch layer
542     PCEventHandler *eventHandler_;
543     Mutex eventCountLock_;
544     int eventCount_;
545
546     syscallNotification *tracedSyscalls_;
547
548     Address rtLibLoadHeap_;
549
550     mt_cache_result_t mt_cache_result_;
551
552     bool isInDebugSuicide_; // Single stepping is only valid in this context
553
554     // Misc.
555     baseTramp *irpcTramp_;
556     bool inEventHandling_;
557     std::set<PCThread *> syncRPCThreads_;
558     Dyninst::Stackwalker::Walker *stackwalker_;
559     std::map<Address, ProcControlAPI::Breakpoint::ptr> installedCtrlBrkpts;
560 };
561
562 class inferiorRPCinProgress : public codeRange {
563 public:
564     inferiorRPCinProgress() :
565         rpc(ProcControlAPI::IRPC::ptr()),
566         rpcStartAddr(0),
567         rpcCompletionAddr(0),
568         resultRegister(REG_NULL),
569         returnValue(NULL),
570         runProcWhenDone(false),
571         isComplete(false),
572         deliverCallbacks(false),
573         userData(NULL),
574         thread(NULL),
575         synchronous(false),
576         memoryAllocated(false)
577     {}
578
579     virtual Address get_address() const { return rpc->getAddress(); }
580     virtual unsigned get_size() const { return (rpcCompletionAddr - rpc->getAddress())+1; }
581     virtual void *getPtrToInstruction(Address /*addr*/) const { assert(0); return NULL; }
582
583     ProcControlAPI::IRPC::ptr rpc;
584     Address rpcStartAddr;
585     Address rpcCompletionAddr;
586
587     Register resultRegister; // register that contains the return value
588     void *returnValue;
589
590     bool runProcWhenDone;
591     bool isComplete;
592     bool deliverCallbacks;
593     void *userData;
594     PCThread *thread;
595     bool synchronous; // caller is responsible for cleaning up this object
596     bool memoryAllocated;
597 };
598
599 class signal_handler_location : public codeRange {
600 public:
601     signal_handler_location(Address addr, unsigned size) :
602         addr_(addr), size_(size) {}
603
604     Address get_address() const {
605         return addr_;
606     }
607     unsigned get_size() const {
608         return size_;
609     }
610
611 private:
612     Address addr_;
613     unsigned size_;
614 };
615
616 class StackwalkSymLookup : public Dyninst::Stackwalker::SymbolLookup {
617   private:
618     PCProcess *proc_;
619
620   public:
621     StackwalkSymLookup(PCProcess *pc);
622     virtual bool lookupAtAddr(Dyninst::Address addr,
623                               std::string &out_name,
624                               void* &out_value);
625     virtual ~StackwalkSymLookup();
626 };
627
628 class StackwalkInstrumentationHelper : public Dyninst::Stackwalker::DyninstDynamicHelper {
629   private:
630     PCProcess *proc_;
631
632   public:
633     StackwalkInstrumentationHelper(PCProcess *pc);
634     virtual bool isInstrumentation(Dyninst::Address ra, Dyninst::Address *orig_ra,
635                                    unsigned *stack_height, bool *entryExit);
636     virtual ~StackwalkInstrumentationHelper();
637 };
638
639 class DynFrameHelper : public Dyninst::Stackwalker::FrameFuncHelper {
640   private:
641     PCProcess *proc_;
642
643   public:
644     DynFrameHelper(PCProcess *pc);
645     virtual Dyninst::Stackwalker::FrameFuncHelper::alloc_frame_t allocatesFrame(Address addr);
646     virtual ~DynFrameHelper();
647 };
648
649 class DynWandererHelper : public Dyninst::Stackwalker::WandererHelper {
650   private:
651     PCProcess *proc_;
652
653   public:
654     DynWandererHelper(PCProcess *pc);
655     virtual bool isPrevInstrACall(Address addr, Address &target);
656     virtual Dyninst::Stackwalker::WandererHelper::pc_state isPCInFunc(Address func_entry, Address pc);
657     virtual bool requireExactMatch();
658     virtual ~DynWandererHelper();
659 };
660
661 #endif