1 #if !defined(INT_PROCESS_H_)
4 #include "proccontrol/h/Process.h"
5 #include "proccontrol/h/PCErrors.h"
6 #include "proccontrol/h/Event.h"
8 #include "dynutil/h/dyn_regs.h"
9 #include "common/h/dthread.h"
18 using namespace Dyninst;
19 using namespace ProcControlAPI;
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;
29 typedef std::list<int_iRPC_ptr> rpc_list_t;
31 class installed_breakpoint;
38 typedef mem_state* ptr;
39 mem_state(int_process *proc);
40 mem_state(mem_state &m, int_process *proc);
43 void addProc(int_process *p);
44 void rmProc(int_process *p, bool &should_clean);
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;
54 friend class Dyninst::ProcControlAPI::Process;
56 int_process(Dyninst::PID p, std::string e, std::vector<std::string> a);
57 int_process(Dyninst::PID pid_, int_process *p);
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();
65 virtual bool plat_create() = 0;
66 virtual bool post_create();
69 virtual bool plat_attach() = 0;
71 virtual bool post_attach();
74 void setContSignal(int sig);
75 int getContSignal() const;
76 virtual bool plat_contProcess() = 0;
80 virtual bool plat_forked() = 0;
81 virtual bool post_forked();
86 virtual bool plat_execed() = 0;
87 virtual bool plat_detach() = 0;
88 virtual bool plat_terminate(bool &needs_sync) = 0;
90 virtual bool needIndividualThreadAttach() = 0;
91 virtual bool getThreadLWPs(std::vector<Dyninst::LWP> &lwps);
93 static bool multi_attach(std::vector<int_process *> &pids);
94 bool waitfor_startup();
96 void setPid(Dyninst::PID pid);
97 int_thread *findStoppedThread();
102 neonatal_intermediate,
107 State getState() const;
108 void setState(State s);
110 Dyninst::PID getPid() const;
111 int_threadPool *threadPool() const;
113 Process::ptr proc() const;
114 mem_state::ptr memory() const;
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);
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);
130 void setExitCode(int c);
131 void setCrashSignal(int s);
132 bool getExitCode(int &c);
133 bool getCrashSignal(int &s);
135 virtual bool plat_individualRegAccess() = 0;
137 void addProcStopper(Event::ptr ev);
138 Event::ptr removeProcStopper();
139 bool hasQueuedProcStoppers() const;
141 int getAddressWidth();
142 HandlerPool *handlerPool() const;
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);
148 Dyninst::Address infMalloc(unsigned long size, bool use_addr = false, Dyninst::Address addr = 0x0);
149 bool infFree(Dyninst::Address addr);
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;
161 IndependentLWPControl
163 static ThreadControlMode getThreadControlMode();
164 static bool isInCB();
165 static void setInCB(bool b);
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;
173 bool forceGeneratorBlock() const;
174 void setForceGeneratorBlock(bool b);
176 std::string getExecutable() const;
177 static bool isInCallback();
179 static int_process *in_waitHandleProc;
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;
195 static bool in_callback;
197 std::map<Dyninst::Address, unsigned> exec_mem_cache;
198 std::queue<Event::ptr> proc_stoppers;
202 class int_registerPool
206 int_registerPool(const int_registerPool &c);
209 typedef std::map<Dyninst::MachRegister, Dyninst::MachRegisterVal> reg_map_t;
214 typedef reg_map_t::iterator iterator;
215 typedef reg_map_t::const_iterator const_iterator;
218 class thread_exitstate
222 Dyninst::THR_ID thr_id;
223 Process::ptr proc_ptr;
237 * ON THREADING STATES:
239 * Each thread has four different states, which mostly monitor running/stopped
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
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.
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.
264 * There are a couple of important assertions about the relationship between these thread
266 * (GeneratorState == running) implies (HandlerState == running)
267 * (HandlerState == running) implies (InternalState == running)
268 * (InternalState == stopped) implies (HandlerState == stopped)
269 * (HandlerState == stopped) implies (GeneratorState == stopped)
273 friend class int_threadPool;
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,
281 static int_thread *createThread(int_process *proc,
282 Dyninst::THR_ID thr_id,
285 Process::ptr proc() const;
286 int_process *llproc() const;
288 Dyninst::THR_ID getTid() const;
289 Dyninst::LWP getLWP() const;
293 neonatal_intermediate,
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();
315 bool intStop(bool sync = true);
318 void setContSignal(int sig);
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;
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();
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();
355 int_iRPC_ptr nextPostedIRPC() const;
356 bool handleNextPostedIRPC(bool block);
357 int_iRPC_ptr hasRunningProcStopperRPC() const;
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;
372 virtual bool attach() = 0;
373 Thread::ptr thread();
375 virtual ~int_thread();
376 static const char *stateStr(int_thread::State s);
381 Thread::ptr up_thread;
385 State generator_state;
386 State internal_state;
388 int_registerPool cached_regpool;
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;
396 bool pending_user_continue;
397 bool pending_continue;
398 int num_locked_stops;
399 bool user_single_step;
401 installed_breakpoint *clearing_breakpoint;
403 bool setAnyState(int_thread::State *from, int_thread::State to);
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);
418 class int_threadPool {
419 friend class Dyninst::ProcControlAPI::ThreadPool;
420 friend class Dyninst::ProcControlAPI::ThreadPool::iterator;
422 std::vector<int_thread *> threads;
423 std::vector<Thread::ptr> hl_threads;
424 std::map<Dyninst::LWP, int_thread *> thrds_by_lwp;
426 int_thread *initial_thread;
430 int_threadPool(int_process *p);
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();
440 typedef std::vector<int_thread *>::iterator iterator;
441 iterator begin() { return threads.begin(); }
442 iterator end() { return threads.end(); }
444 unsigned size() const;
446 int_process *proc() const;
447 ThreadPool *pool() const;
449 int_thread *findThreadByLWP(Dyninst::LWP lwp);
450 int_thread *initialThread() const;
455 bool intStop(bool sync = true);
458 bool cont(bool user_cont);
459 bool stop(bool user_stop, bool sync);
464 friend class Dyninst::ProcControlAPI::LibraryPool;
465 friend class Dyninst::ProcControlAPI::LibraryPool::iterator;
466 friend class Dyninst::ProcControlAPI::LibraryPool::const_iterator;
469 Dyninst::Address load_address;
470 Dyninst::Address data_load_address;
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);
480 std::string getName();
481 Dyninst::Address getAddr();
482 Dyninst::Address getDataAddr();
485 void setMark(bool b);
486 bool isMarked() const;
488 Library::ptr getUpPtr() const;
493 friend class installed_breakpoint;
495 Breakpoint::weak_ptr up_bp;
497 bool isCtrlTransfer_;
500 int_breakpoint(Breakpoint::ptr up);
501 int_breakpoint(Dyninst::Address to, Breakpoint::ptr up);
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;
512 class installed_breakpoint
514 friend class Dyninst::ProcControlAPI::EventBreakpoint;
516 mem_state::ptr memory;
517 std::set<int_breakpoint *> bps;
518 std::set<Breakpoint::ptr> hl_bps;
520 unsigned char buffer[4]; //At least as large as any arch's trap instruction
524 Dyninst::Address addr;
526 installed_breakpoint(mem_state::ptr memory_, Dyninst::Address addr_);
527 installed_breakpoint(mem_state::ptr memory_, const installed_breakpoint *ip);
528 ~installed_breakpoint();
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);
536 bool suspend(int_process *proc);
537 bool resume(int_process *proc);
539 bool isInstalled() const;
540 Dyninst::Address getAddr() const;
544 friend int_notify *notify();
545 friend EventNotify *Dyninst::ProcControlAPI::evNotify();
547 static int_notify *the_notify;
548 EventNotify *up_notify;
549 std::set<EventNotify::notify_cb_t> cbs;
562 void registerCB(EventNotify::notify_cb_t cb);
563 void removeCB(EventNotify::notify_cb_t cb);
567 int_notify *notify();
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);
577 friend MTManager *mt();
580 static MTManager *mt_;
581 DThread evhandler_thread;
582 CondVar pending_event_lock;
584 bool have_queued_events;
587 Process::thread_mode_t threadMode;
589 void evhandler_main();
590 static void evhandler_main_wrapper(void *);
591 void eventqueue_cb();
592 static void eventqueue_cb_wrapper();
595 static const Process::thread_mode_t default_thread_mode = Process::HandlerThreading;
605 bool handlerThreading();
606 Process::thread_mode_t getThreadMode();
607 bool setThreadMode(Process::thread_mode_t tm, bool init = false);
610 inline MTManager *mt() {
611 return MTManager::mt_;
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)
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) {
631 mt()->setThreadMode(MTManager::default_thread_mode, true);
633 else if (mt()->handlerThreading()) {
635 if (c == deliver_callbacks &&
636 MTManager::default_thread_mode == Process::HandlerThreading &&
637 notify()->hasEvents())
639 pthrd_printf("MTLock triggered event handling\n");
640 int_process::waitAndHandleEvents(false);
641 pthrd_printf("MTLock triggered event handling finished\n");
648 if (isGeneratorThread()) {
649 should_unlock = false;
652 should_unlock = true;
653 if (mt()->handlerThreading()) {
660 assert(!isGeneratorThread());
661 should_unlock = true;
662 if (mt()->handlerThreading()) {
664 if (notify()->hasEvents() &&
665 MTManager::default_thread_mode == Process::HandlerThreading)
667 pthrd_printf("MTLock triggered event handling\n");
668 int_process::waitAndHandleEvents(false);
669 pthrd_printf("MTLock triggered event handling finished\n");
676 assert(!isGeneratorThread());
677 should_unlock = true;
678 if (mt()->handlerThreading())
683 if (should_unlock && mt()->handlerThreading())