A first pass at implementing thread stop and continue on FreeBSD.
[dyninst.git] / proccontrol / src / int_process.h
1 #if !defined(INT_PROCESS_H_)
2 #define INT_PROCESS_H_
3
4 #include "proccontrol/h/Process.h"
5 #include "proccontrol/h/PCErrors.h"
6 #include "proccontrol/h/Event.h"
7
8 #include "dynutil/h/dyn_regs.h"
9 #include "common/h/dthread.h"
10
11 #include <vector>
12 #include <map>
13 #include <list>
14 #include <set>
15 #include <utility>
16 #include <queue>
17
18 using namespace Dyninst;
19 using namespace ProcControlAPI;
20
21 class int_thread;
22 class int_threadPool;
23 class handlerpool;
24 class int_iRPC;
25
26 typedef dyn_detail::boost::shared_ptr<int_iRPC> int_iRPC_ptr;
27 typedef std::map<Dyninst::MachRegister, std::pair<unsigned int, unsigned int> > dynreg_to_user_t;
28
29 typedef std::list<int_iRPC_ptr> rpc_list_t;
30
31 class installed_breakpoint;
32 class int_library;
33 class int_process;
34
35 class mem_state
36 {
37   public:
38    typedef mem_state* ptr;
39    mem_state(int_process *proc);
40    mem_state(mem_state &m, int_process *proc);
41    ~mem_state();
42
43    void addProc(int_process *p);
44    void rmProc(int_process *p, bool &should_clean);
45
46    std::set<int_process *> procs;
47    std::set<int_library *> libs;
48    std::map<Dyninst::Address, installed_breakpoint *> breakpoints;
49    std::map<Dyninst::Address, unsigned long> inf_malloced_memory;
50 };
51
52 class int_process
53 {
54    friend class Dyninst::ProcControlAPI::Process;
55  protected:
56    int_process(Dyninst::PID p, std::string e, std::vector<std::string> a);
57    int_process(Dyninst::PID pid_, int_process *p);
58  public:
59    static int_process *createProcess(Dyninst::PID p, std::string e);
60    static int_process *createProcess(std::string e, std::vector<std::string> a);
61    static int_process *createProcess(Dyninst::PID pid_, int_process *p);
62    virtual ~int_process();
63  protected:
64    bool create();
65    virtual bool plat_create() = 0;
66    virtual bool post_create();
67
68    bool attach();
69    virtual bool plat_attach() = 0;
70    bool attachThreads();
71    virtual bool post_attach();
72
73   public:
74    void setContSignal(int sig);
75    int getContSignal() const;
76    virtual bool plat_contProcess() = 0;
77
78    bool forked();
79   protected:
80    virtual bool plat_forked() = 0;
81    virtual bool post_forked();
82
83   public:
84    bool execed();
85   protected:
86    virtual bool plat_execed() = 0;
87    virtual bool plat_detach() = 0;
88    virtual bool plat_terminate(bool &needs_sync) = 0;
89
90    virtual bool needIndividualThreadAttach() = 0;
91    virtual bool getThreadLWPs(std::vector<Dyninst::LWP> &lwps);
92
93    static bool multi_attach(std::vector<int_process *> &pids);
94    bool waitfor_startup();
95
96    void setPid(Dyninst::PID pid);
97    int_thread *findStoppedThread();
98
99   public:
100    typedef enum {
101       neonatal = 0,
102       neonatal_intermediate,
103       running,
104       exited,
105       errorstate
106    } State;
107    State getState() const;
108    void setState(State s);
109
110    Dyninst::PID getPid() const;
111    int_threadPool *threadPool() const;
112
113    Process::ptr proc() const;
114    mem_state::ptr memory() const;
115
116    bool detach(bool &should_clean);
117    bool terminate(bool &needs_sync);
118    void updateSyncState(Event::ptr ev, bool gen);
119    virtual Dyninst::Architecture getTargetArch() = 0;
120    virtual unsigned getTargetPageSize() = 0;
121    virtual Dyninst::Address mallocExecMemory(unsigned size);
122    virtual Dyninst::Address plat_mallocExecMemory(Dyninst::Address min, unsigned size) = 0;
123    virtual void freeExecMemory(Dyninst::Address addr);
124
125    static bool waitAndHandleEvents(bool block);
126    static bool waitAndHandleForProc(bool block, int_process *proc, bool &proc_exited);
127    static const char *stateName(State s);
128    void initializeProcess(Process::ptr p);
129
130    void setExitCode(int c);
131    void setCrashSignal(int s);
132    bool getExitCode(int &c);
133    bool getCrashSignal(int &s);
134
135    virtual bool plat_individualRegAccess() = 0;
136
137    void addProcStopper(Event::ptr ev);
138    Event::ptr removeProcStopper();
139    bool hasQueuedProcStoppers() const;
140
141    int getAddressWidth();
142    HandlerPool *handlerPool() const;
143
144    bool addBreakpoint(Dyninst::Address addr, int_breakpoint *bp);
145    bool rmBreakpoint(Dyninst::Address addr, int_breakpoint *bp);
146    installed_breakpoint *getBreakpoint(Dyninst::Address addr);
147
148    Dyninst::Address infMalloc(unsigned long size, bool use_addr = false, Dyninst::Address addr = 0x0);
149    bool infFree(Dyninst::Address addr);
150
151    bool readMem(void *local, Dyninst::Address remote, size_t size);
152    bool writeMem(void *local, Dyninst::Address remote, size_t size);
153    virtual bool plat_readMem(int_thread *thr, void *local, 
154                              Dyninst::Address remote, size_t size) = 0;
155    virtual bool plat_writeMem(int_thread *thr, void *local, 
156                               Dyninst::Address remote, size_t size) = 0;
157    
158    typedef enum {
159        NoLWPControl = 0,
160        HybridLWPControl,
161        IndependentLWPControl
162    } ThreadControlMode;
163    static ThreadControlMode getThreadControlMode();
164    static bool isInCB();
165    static void setInCB(bool b);
166
167    int_library *getLibraryByName(std::string s) const;
168    size_t numLibs() const;
169    virtual bool refresh_libraries(std::set<int_library *> &added_libs,
170                                   std::set<int_library *> &rmd_libs) = 0;
171    virtual bool initLibraryMechanism() = 0;
172
173    bool forceGeneratorBlock() const;
174    void setForceGeneratorBlock(bool b);
175
176    std::string getExecutable() const;
177    static bool isInCallback();
178
179    static int_process *in_waitHandleProc;
180  protected:
181    State state;
182    Dyninst::PID pid;
183    std::string executable;
184    std::vector<std::string> argv;
185    Dyninst::Architecture arch;
186    int_threadPool *threadpool;
187    Process::ptr up_proc;
188    HandlerPool *handlerpool;
189    LibraryPool libpool;
190    bool hasCrashSignal;
191    int crashSignal;
192    bool hasExitCode;
193    bool forceGenerator;
194    int exitCode;
195    static bool in_callback;
196    mem_state::ptr mem;
197    std::map<Dyninst::Address, unsigned> exec_mem_cache;
198    std::queue<Event::ptr> proc_stoppers;
199    int continueSig;
200 };
201
202 class int_registerPool
203 {
204  public:
205    int_registerPool();
206    int_registerPool(const int_registerPool &c);
207    ~int_registerPool();
208    
209    typedef std::map<Dyninst::MachRegister, Dyninst::MachRegisterVal> reg_map_t;
210    reg_map_t regs;
211    bool full;
212    int_thread *thread;
213
214    typedef reg_map_t::iterator iterator;
215    typedef reg_map_t::const_iterator const_iterator;
216 };
217
218 class thread_exitstate
219 {
220   public:
221    Dyninst::LWP lwp;
222    Dyninst::THR_ID thr_id;
223    Process::ptr proc_ptr;
224 };
225
226 class proc_exitstate
227 {
228   public:
229    Dyninst::PID pid;
230    bool exited;
231    bool crashed;
232    int crash_signal;
233    int exit_code;
234 };
235
236 /**
237  * ON THREADING STATES:
238  *
239  * Each thread has four different states, which mostly monitor running/stopped
240  * status:
241  *   GeneratorState - Thread state as seen by the generator object
242  *   HandlerState - Thread state as seen by the handler object
243  *   InternalState - Target thread state desired by int_* layer
244  *   UserState - Target Thread state as desired by the user
245  *
246  * The GeneratorState and HandlerState represent an event as it moves through the 
247  * system.  For example, an event that stops the thread may first appear
248  * in the Generator object, and move the GeneratorState to 'stopped'.  It is then
249  * seen by the handler, which moves the HandlerState to 'stopped'.  If the thread is 
250  * then continued, the HandlerState and GeneratorStates will go back to 'running'.
251  * These are primarily seperated to prevent race conditions with the handler and
252  * generators modifying the same variable, since they run in seperate threads.
253  * 
254  * The InternalState and UserState are used to make policy decisions about whether
255  * a thread should be running or stopped.  For example, after handling an event
256  * we may check the UserState to see if the user wants us to run/stop a thread.
257  * The InternalState usually matches the UserState, but may override it for 
258  * stop/run decisions in a few scenarios.  For example, if the user posts a iRPC
259  * to a running process (UserState = running) we may have to temporarily stop the
260  * process to install the iRPC.  We don't want to change the UserState, since the user
261  * still wants the process running, so we set the InternalState to stopped while we
262  * set up the iRPC, and then return it to the UserState value when the iRPC is ready.
263  *
264  * There are a couple of important assertions about the relationship between these thread
265  * states:
266  *  (GeneratorState == running) implies (HandlerState == running)
267  *  (HandlerState == running)  implies (InternalState == running)
268  *  (InternalState == stopped)  implies (HandlerState == stopped)
269  *  (HandlerState == stopped)  implies (GeneratorState == stopped)
270  **/
271 class int_thread
272 {
273    friend class int_threadPool;
274  protected:
275    int_thread(int_process *p, Dyninst::THR_ID t, Dyninst::LWP l);
276    static int_thread *createThreadPlat(int_process *proc, 
277                                        Dyninst::THR_ID thr_id, 
278                                        Dyninst::LWP lwp_id,
279                                        bool initial_thrd);
280  public:
281    static int_thread *createThread(int_process *proc, 
282                                    Dyninst::THR_ID thr_id, 
283                                    Dyninst::LWP lwp_id,
284                                    bool initial_thrd);
285    Process::ptr proc() const;
286    int_process *llproc() const;
287
288    Dyninst::THR_ID getTid() const;
289    Dyninst::LWP getLWP() const;
290
291    typedef enum {
292       neonatal,
293       neonatal_intermediate,
294       running,
295       stopped,
296       exited,
297       errorstate
298    } State;
299
300    //State management, see above comment on states
301    State getHandlerState() const;
302    State getUserState() const;
303    State getGeneratorState() const;
304    State getInternalState() const;
305    bool setHandlerState(State s);
306    bool setUserState(State s);
307    bool setGeneratorState(State s);
308    bool setInternalState(State s);
309    void restoreInternalState(bool sync = true);
310    void desyncInternalState();
311
312    //Process control
313    bool userCont();
314    bool userStop();
315    bool intStop(bool sync = true);
316    bool intCont();
317
318    void setContSignal(int sig);
319    int getContSignal();
320    bool contWithSignal(int sigOverride = -1);
321    virtual bool plat_cont(bool user_cont) = 0;
322    virtual bool plat_stop() = 0;
323    void setPendingUserStop(bool b);
324    bool hasPendingUserStop() const;
325    void setPendingStop(bool b);
326    bool hasPendingStop() const;
327    void setPendingUserContinue(bool b);
328    bool hasPendingUserContinue() const;
329    void setPendingContinue(bool b);
330    bool hasPendingContinue() const;
331
332    //Single-step
333    bool singleStepMode() const;
334    void setSingleStepMode(bool s);
335    bool singleStepUserMode() const;
336    void setSingleStepUserMode(bool s);
337    bool singleStep() const;   
338    void markClearingBreakpoint(installed_breakpoint *bp);
339    installed_breakpoint *isClearingBreakpoint();
340
341    //RPC Management
342    void addPostedRPC(int_iRPC_ptr rpc_);
343    rpc_list_t *getPostedRPCs();
344    bool hasPostedRPCs();
345    void setRunningRPC(int_iRPC_ptr rpc_);
346    void clearRunningRPC();
347    int_iRPC_ptr runningRPC() const;
348    bool saveRegsForRPC();
349    bool restoreRegsForRPC(bool clear);
350    bool hasSavedRPCRegs();
351    bool runningInternalRPC() const;
352    void incSyncRPCCount();
353    void decSyncRPCCount();
354    bool hasSyncRPC();
355    int_iRPC_ptr nextPostedIRPC() const;
356    bool handleNextPostedIRPC(bool block);
357    int_iRPC_ptr hasRunningProcStopperRPC() const;
358
359    //Register Management
360    bool getAllRegisters(int_registerPool &pool);
361    bool getRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal &val);
362    bool setAllRegisters(int_registerPool &pool);
363    bool setRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal val);
364    virtual bool plat_getAllRegisters(int_registerPool &pool) = 0;
365    virtual bool plat_getRegister(Dyninst::MachRegister reg, 
366                                  Dyninst::MachRegisterVal &val) = 0;
367    virtual bool plat_setAllRegisters(int_registerPool &pool) = 0;
368    virtual bool plat_setRegister(Dyninst::MachRegister reg, 
369                                  Dyninst::MachRegisterVal val) = 0;
370
371    //Misc
372    virtual bool attach() = 0;
373    Thread::ptr thread();
374
375    virtual ~int_thread();
376    static const char *stateStr(int_thread::State s);
377  protected:
378    Dyninst::THR_ID tid;
379    Dyninst::LWP lwp;
380    int_process *proc_;
381    Thread::ptr up_thread;
382    int continueSig_;
383    State handler_state;
384    State user_state;
385    State generator_state;
386    State internal_state;
387
388    int_registerPool cached_regpool;
389    Mutex regpool_lock;
390    int_iRPC_ptr running_rpc;
391    rpc_list_t posted_rpcs;
392    int_registerPool rpc_regs;
393    unsigned sync_rpc_count;
394    bool pending_user_stop;
395    bool pending_stop;
396    bool pending_user_continue;
397    bool pending_continue;
398    int num_locked_stops;
399    bool user_single_step;
400    bool single_step;
401    installed_breakpoint *clearing_breakpoint;
402
403    bool setAnyState(int_thread::State *from, int_thread::State to);
404
405    //Stop/Continue
406    typedef enum {
407       sc_error,
408       sc_success,
409       sc_success_pending,
410       sc_skip
411    } stopcont_ret_t;
412    bool stop(bool user_stop, bool sync);
413    bool cont(bool user_cont);
414    stopcont_ret_t stop(bool user_stop);
415    stopcont_ret_t cont(bool user_cont, bool has_proc_lock);
416 };
417
418 class int_threadPool {
419    friend class Dyninst::ProcControlAPI::ThreadPool;
420    friend class Dyninst::ProcControlAPI::ThreadPool::iterator;
421  private:
422    std::vector<int_thread *> threads;
423    std::vector<Thread::ptr> hl_threads;
424    std::map<Dyninst::LWP, int_thread *> thrds_by_lwp;
425
426    int_thread *initial_thread;
427    int_process *proc_;
428    ThreadPool *up_pool;
429  public:
430    int_threadPool(int_process *p);
431    ~int_threadPool();
432
433    void setInitialThread(int_thread *thrd);
434    void addThread(int_thread *thrd);
435    void rmThread(int_thread *thrd);
436    void restoreInternalState(bool sync);
437    void desyncInternalState();
438    void clear();
439
440    typedef std::vector<int_thread *>::iterator iterator;
441    iterator begin() { return threads.begin(); }
442    iterator end() { return threads.end(); }
443
444    unsigned size() const;
445
446    int_process *proc() const;
447    ThreadPool *pool() const;
448
449    int_thread *findThreadByLWP(Dyninst::LWP lwp);
450    int_thread *initialThread() const;
451    bool allStopped();
452    
453    bool userCont();
454    bool userStop();
455    bool intStop(bool sync = true);
456    bool intCont();
457  private:
458    bool cont(bool user_cont);
459    bool stop(bool user_stop, bool sync);
460 };
461
462 class int_library
463 {
464    friend class Dyninst::ProcControlAPI::LibraryPool;
465    friend class Dyninst::ProcControlAPI::LibraryPool::iterator;
466    friend class Dyninst::ProcControlAPI::LibraryPool::const_iterator;
467   private:
468    std::string name;
469    Dyninst::Address load_address;
470    Dyninst::Address data_load_address;
471    bool has_data_load;
472    bool marked;
473    Library::ptr up_lib;
474   public:
475    int_library(std::string n, Dyninst::Address load_addr);
476    int_library(std::string n, Dyninst::Address load_addr, 
477                Dyninst::Address data_load_addr);
478    int_library(int_library *l);
479    ~int_library();
480    std::string getName();
481    Dyninst::Address getAddr();
482    Dyninst::Address getDataAddr();
483    bool hasDataAddr();
484    
485    void setMark(bool b);
486    bool isMarked() const;
487    
488    Library::ptr getUpPtr() const;
489 };
490
491 class int_breakpoint
492 {
493    friend class installed_breakpoint;
494  private:
495    Breakpoint::weak_ptr up_bp;
496    Dyninst::Address to;
497    bool isCtrlTransfer_;
498    void *data;
499  public:
500    int_breakpoint(Breakpoint::ptr up);
501    int_breakpoint(Dyninst::Address to, Breakpoint::ptr up);
502    ~int_breakpoint();
503
504    bool isCtrlTransfer() const;
505    Dyninst::Address toAddr() const;
506    Dyninst::Address getAddress(int_process *p) const;
507    void *getData() const;
508    void setData(void *v);
509    Breakpoint::weak_ptr upBreakpoint() const;
510 };
511
512 class installed_breakpoint
513 {
514    friend class Dyninst::ProcControlAPI::EventBreakpoint;
515  private:
516    mem_state::ptr memory;
517    std::set<int_breakpoint *> bps;
518    std::set<Breakpoint::ptr> hl_bps;
519
520    unsigned char buffer[4]; //At least as large as any arch's trap instruction
521    int buffer_size;
522    bool installed;
523    int suspend_count;
524    Dyninst::Address addr;
525  public:
526    installed_breakpoint(mem_state::ptr memory_, Dyninst::Address addr_);
527    installed_breakpoint(mem_state::ptr memory_, const installed_breakpoint *ip);
528    ~installed_breakpoint();
529
530    bool addBreakpoint(int_process *proc, int_breakpoint *bp);
531    bool rmBreakpoint(int_process *proc, int_breakpoint *bp, bool &empty);
532    bool install(int_process *proc);
533    bool uninstall(int_process *proc);
534    bool plat_install(int_process *proc, bool should_save);
535
536    bool suspend(int_process *proc);
537    bool resume(int_process *proc);
538
539    bool isInstalled() const;
540    Dyninst::Address getAddr() const;
541 };
542
543 class int_notify {
544    friend int_notify *notify();
545    friend EventNotify *Dyninst::ProcControlAPI::evNotify();
546  private:
547    static int_notify *the_notify;
548    EventNotify *up_notify;
549    std::set<EventNotify::notify_cb_t> cbs;
550    int pipe_in;
551    int pipe_out;
552    int pipe_count;
553    int events_noted;
554    void writeToPipe();
555    void readFromPipe();
556    bool createPipe();
557  public:
558    int_notify();
559    
560    void noteEvent();
561    void clearEvent();
562    void registerCB(EventNotify::notify_cb_t cb);
563    void removeCB(EventNotify::notify_cb_t cb);
564    bool hasEvents();
565    int getPipeIn();
566 };
567 int_notify *notify();
568
569 extern void setGeneratorThread(long t);
570 void setHandlerThread(long t);
571 bool isGeneratorThread();
572 bool isHandlerThread();
573 HandlerPool *createDefaultHandlerPool();
574 HandlerPool *plat_createDefaultHandlerPool(HandlerPool *hpool);
575
576 class MTManager {
577   friend MTManager *mt();
578   friend class MTLock;
579 private:
580   static MTManager *mt_;
581   DThread evhandler_thread;
582   CondVar pending_event_lock;
583   Mutex work_lock;
584   bool have_queued_events;
585   bool is_running;
586   bool should_exit;
587   Process::thread_mode_t threadMode;
588   
589   void evhandler_main();
590   static void evhandler_main_wrapper(void *);
591   void eventqueue_cb();
592   static void eventqueue_cb_wrapper();
593   
594 public:
595   static const Process::thread_mode_t default_thread_mode = Process::HandlerThreading;
596   MTManager();
597   ~MTManager();
598   
599   void run();
600   void stop();
601
602   void startWork();
603   void endWork();
604   
605   bool handlerThreading();
606   Process::thread_mode_t getThreadMode();
607   bool setThreadMode(Process::thread_mode_t tm, bool init = false);
608 }; 
609
610 inline MTManager *mt() { 
611    return MTManager::mt_; 
612 };
613
614 class MTLock
615 {
616  private:
617    bool should_unlock;
618  public:
619    typedef enum {allow_init} initialize;
620    typedef enum {allow_generator} generator;
621    typedef enum {nocb, deliver_callbacks} callbacks;
622    MTLock(initialize, callbacks c = nocb)
623    {
624       should_unlock = true;
625       if (!MTManager::mt_) {
626          MTManager::mt_ = new MTManager();
627          if (MTManager::default_thread_mode == Process::HandlerThreading ||
628              MTManager::default_thread_mode == Process::CallbackThreading) {
629             mt()->startWork();
630          }
631          mt()->setThreadMode(MTManager::default_thread_mode, true);
632       }
633       else if (mt()->handlerThreading()) {
634          mt()->startWork();
635          if (c == deliver_callbacks && 
636              MTManager::default_thread_mode == Process::HandlerThreading && 
637              notify()->hasEvents()) 
638          {
639             pthrd_printf("MTLock triggered event handling\n");
640             int_process::waitAndHandleEvents(false);
641             pthrd_printf("MTLock triggered event handling finished\n");
642          }
643       }
644    }
645
646    MTLock(generator)
647    {
648       if (isGeneratorThread()) {
649          should_unlock = false;
650          return;
651       }
652       should_unlock = true;
653       if (mt()->handlerThreading()) {
654          mt()->startWork();
655       }
656    }
657
658    MTLock(callbacks) 
659    {
660       assert(!isGeneratorThread());
661       should_unlock = true;
662       if (mt()->handlerThreading()) {
663          mt()->startWork();
664          if (notify()->hasEvents() && 
665              MTManager::default_thread_mode == Process::HandlerThreading) 
666          {
667             pthrd_printf("MTLock triggered event handling\n");
668             int_process::waitAndHandleEvents(false);
669             pthrd_printf("MTLock triggered event handling finished\n");
670          }
671       }
672    }
673
674    MTLock()
675    {
676       assert(!isGeneratorThread());
677       should_unlock = true;
678       if (mt()->handlerThreading())
679          mt()->startWork();
680    }
681
682    ~MTLock() {
683       if (should_unlock && mt()->handlerThreading())
684          mt()->endWork();
685    }
686 };
687
688 #endif