1 #include "proccontrol/h/Handler.h"
2 #include "proccontrol/h/PCErrors.h"
3 #include "proccontrol/h/Process.h"
4 #include "proccontrol/src/int_process.h"
5 #include "proccontrol/src/int_handler.h"
6 #include "proccontrol/src/procpool.h"
7 #include "proccontrol/src/irpc.h"
8 #include "dynutil/h/dyn_regs.h"
10 using namespace Dyninst;
14 Handler::Handler(std::string name_) :
23 int Handler::getPriority() const
25 return DefaultPriority;
28 Event::ptr Handler::convertEventForCB(Event::ptr /*orig*/)
33 std::string Handler::getName() const
38 HandlerPool::HandlerPool()
42 HandlerPool::~HandlerPool()
44 for (HandlerMap_t::iterator i = handlers.begin(); i != handlers.end(); i++) {
47 //Do not delete actual Handler* objects.
51 void HandlerPool::addHandlerInt(EventType etype, Handler *handler)
53 pthrd_printf("Handler %s will handle event %s\n", handler->getName().c_str(),
54 etype.name().c_str());
55 assert(etype.time() != EventType::Any);
56 HandlerMap_t::iterator i = handlers.find(etype);
57 HandlerSet_t *theset = NULL;
58 if (i == handlers.end()) {
59 theset = new HandlerSet_t();
60 handlers[etype] = theset;
65 theset->insert(handler);
67 HandleCallbacks *cb = HandleCallbacks::getCB();
69 cb->alleventtypes.insert(etype);
70 if (!(etype.code() >= EventType::InternalEvents && etype.code() < EventType::MaxProcCtrlEvent))
71 addHandlerInt(etype, cb);
75 void HandlerPool::addHandler(Handler *handler)
77 std::vector<EventType> etypes;
78 handler->getEventTypesHandled(etypes);
80 for (std::vector<EventType>::iterator i = etypes.begin(); i != etypes.end(); i++)
82 if ((*i).time() == EventType::Any) {
83 addHandlerInt(EventType(EventType::Pre, (*i).code()), handler);
84 addHandlerInt(EventType(EventType::Post, (*i).code()), handler);
85 addHandlerInt(EventType(EventType::None, (*i).code()), handler);
88 addHandlerInt(*i, handler);
95 bool operator()(const pair<Event::ptr, Handler*> &a,
96 const pair<Event::ptr, Handler*> &b)
98 if (a.second->getPriority() != b.second->getPriority())
99 return a.second->getPriority() < b.second->getPriority();
100 if (a.first->subservientTo().lock() == b.first)
102 if (b.first->subservientTo().lock() == a.first)
105 return cmp(a.first->getEventType(), b.first->getEventType());
109 bool HandlerPool::handleEvent(Event::ptr ev)
111 EventType etype = ev->getEventType();
112 Event::ptr cb_replacement_ev = Event::ptr();
115 * An event and its subservient events are a set of events that
116 * are processed at the same time. As an example, on SysV systems
117 * a Library event is triggered by a breakpoint. We want to do both the
118 * breakpoint handling and the library handling at the same time,
119 * but don't want to seperate the handling of these events. In this
120 * example the Library event is subservient to the Breakpoint event.
122 * We'll take the event and all its subservient set and run handlers
125 set<Event::ptr> all_events;
126 all_events.insert(ev);
127 for (vector<Event::ptr>::iterator i = ev->subservient_events.begin();
128 i != ev->subservient_events.end(); i++)
130 all_events.insert(*i);
133 typedef set<pair<Event::ptr, Handler *>, eh_cmp_func > ev_hndler_set_t;
134 ev_hndler_set_t events_and_handlers;
135 for (set<Event::ptr>::iterator i = all_events.begin(); i != all_events.end(); i++)
138 EventType etype = ev->getEventType();
139 HandlerMap_t::iterator j = handlers.find(etype);
140 if (j == handlers.end()) {
141 perr_printf("Event %s has no handlers registered\n", etype.name().c_str());
144 HandlerSet_t *hset = j->second;
145 for (HandlerSet_t::iterator k = hset->begin(); k != hset->end(); k++)
148 events_and_handlers.insert(pair<Event::ptr, Handler*>(ev, hnd));
153 * We should have all events and handlers properly sorted into the
154 * events_and_handlers set in the order we want to run them in.
155 * Now it's finally time to run the handlers.
157 bool handled_something = false;
158 ev_hndler_set_t::iterator i;
159 for (i = events_and_handlers.begin(); i != events_and_handlers.end(); i++)
161 handled_something = true;
162 Event::ptr event = i->first;
163 Handler *handler = i->second;
164 EventType etype = ev->getEventType();
166 pthrd_printf("Handling event '%s' with handler '%s'\n", etype.name().c_str(),
167 handler->getName().c_str());
169 bool result = handler->handleEvent(event);
171 pthrd_printf("Error handling event %s with %s\n", etype.name().c_str(),
172 handler->getName().c_str());
176 return handled_something;
179 HandleBootstrap::HandleBootstrap() :
180 Handler(std::string("Bootstrap"))
184 HandleBootstrap::~HandleBootstrap()
188 void HandleBootstrap::getEventTypesHandled(std::vector<EventType> &etypes)
190 etypes.push_back(EventType(EventType::None, EventType::Bootstrap));
193 bool HandleBootstrap::handleEvent(Event::ptr ev)
195 int_process *p = ev->getProcess()->llproc();
197 pthrd_printf("Handling bootstrap for %d\n", p->getPid());
199 if (p->getState() != int_process::neonatal_intermediate)
202 bool all_bootstrapped = true;
203 int_threadPool *tp = ev->getProcess()->llproc()->threadPool();
204 for (int_threadPool::iterator i = tp->begin(); i != tp->end(); i++) {
205 int_thread *thr = *i;
206 if (thr->getHandlerState() == int_thread::neonatal_intermediate) {
207 pthrd_printf("Thread %d is not yet bootstrapped\n", thr->getLWP());
208 all_bootstrapped = false;
213 if (all_bootstrapped) {
214 pthrd_printf("All threads are bootstrapped, marking process bootstrapped\n");
215 p->setState(int_process::running);
221 HandleSignal::HandleSignal() :
222 Handler(std::string("Signal"))
226 HandleSignal::~HandleSignal()
230 void HandleSignal::getEventTypesHandled(std::vector<EventType> &etypes)
232 etypes.push_back(EventType(EventType::None, EventType::Signal));
235 bool HandleSignal::handleEvent(Event::ptr ev)
237 int_thread *thrd = ev->getThread()->llthrd();
239 EventSignal *sigev = static_cast<EventSignal *>(ev.get());
240 thrd->setContSignal(sigev->getSignal());
245 HandlePostExit::HandlePostExit() :
250 HandlePostExit::~HandlePostExit()
254 void HandlePostExit::getEventTypesHandled(std::vector<EventType> &etypes)
256 etypes.push_back(EventType(EventType::Post, EventType::Exit));
259 bool HandlePostExit::handleEvent(Event::ptr ev)
261 int_process *proc = ev->getProcess()->llproc();
262 int_thread *thrd = ev->getThread()->llthrd();
265 EventExit *event = static_cast<EventExit *>(ev.get());
266 pthrd_printf("Handling post-exit for process %d on thread %d\n",
267 proc->getPid(), thrd->getLWP());
268 proc->setExitCode(event->getExitCode());
270 ProcPool()->condvar()->lock();
272 proc->setState(int_process::exited);
273 ProcPool()->rmProcess(proc);
274 ProcPool()->rmThread(thrd);
276 ProcPool()->condvar()->signal();
277 ProcPool()->condvar()->unlock();
279 if (int_process::in_waitHandleProc == proc) {
280 pthrd_printf("Postponing delete due to being in waitAndHandleForProc\n");
287 HandleCrash::HandleCrash() :
292 HandleCrash::~HandleCrash()
296 void HandleCrash::getEventTypesHandled(std::vector<EventType> &etypes)
298 etypes.push_back(EventType(EventType::Post, EventType::Crash));
301 bool HandleCrash::handleEvent(Event::ptr ev)
303 int_process *proc = ev->getProcess()->llproc();
304 int_thread *thrd = ev->getThread()->llthrd();
307 pthrd_printf("Handling crash for process %d on thread %d\n",
308 proc->getPid(), thrd->getLWP());
309 EventCrash *event = static_cast<EventCrash *>(ev.get());
310 proc->setCrashSignal(event->getTermSignal());
312 ProcPool()->condvar()->lock();
314 proc->setState(int_process::exited);
315 ProcPool()->rmProcess(proc);
317 ProcPool()->condvar()->signal();
318 ProcPool()->condvar()->unlock();
325 HandlePreExit::HandlePreExit() :
330 HandlePreExit::~HandlePreExit()
334 void HandlePreExit::getEventTypesHandled(std::vector<EventType> &etypes)
336 etypes.push_back(EventType(EventType::Pre, EventType::Exit));
339 bool HandlePreExit::handleEvent(Event::ptr ev)
341 pthrd_printf("Handling pre-exit for process %d on thread %d\n",
342 ev->getProcess()->llproc()->getPid(),
343 ev->getThread()->llthrd()->getLWP());
348 HandleThreadCreate::HandleThreadCreate() :
349 Handler("Thread Create")
353 HandleThreadCreate::~HandleThreadCreate()
357 void HandleThreadCreate::getEventTypesHandled(std::vector<EventType> &etypes)
359 etypes.push_back(EventType(EventType::None, EventType::ThreadCreate));
362 bool HandleThreadCreate::handleEvent(Event::ptr ev)
364 int_process *proc = ev->getProcess()->llproc();
365 int_thread *thrd = ev->getThread()->llthrd();
366 EventNewThread *threadev = static_cast<EventNewThread *>(ev.get());
368 pthrd_printf("Handle thread create for %d/%d with new thread %d\n",
369 proc->getPid(), thrd ? thrd->getLWP() : -1, threadev->getLWP());
371 ProcPool()->condvar()->lock();
373 int_thread *newthr = int_thread::createThread(proc, 0, threadev->getLWP(), false);
374 //New threads start stopped, but inherit the user state of the creating
375 // thread (which should be 'running').
376 newthr->setGeneratorState(int_thread::stopped);
377 newthr->setHandlerState(int_thread::stopped);
378 newthr->setInternalState(thrd->getUserState());
379 newthr->setUserState(thrd->getUserState());
381 ProcPool()->condvar()->signal();
382 ProcPool()->condvar()->unlock();
387 HandleThreadDestroy::HandleThreadDestroy() :
388 Handler("Thread Destroy")
392 HandleThreadDestroy::~HandleThreadDestroy()
396 void HandleThreadDestroy::getEventTypesHandled(std::vector<EventType> &etypes)
398 etypes.push_back(EventType(EventType::Any, EventType::ThreadDestroy));
401 bool HandleThreadDestroy::handleEvent(Event::ptr ev)
403 int_thread *thrd = ev->getThread()->llthrd();
404 int_process *proc = ev->getProcess()->llproc();
405 if (ev->getEventType().time() == EventType::Pre) {
406 pthrd_printf("Handling pre-thread destroy for %d\n", thrd->getLWP());
410 pthrd_printf("Handling post-thread destroy for %d\n", thrd->getLWP());
411 ProcPool()->condvar()->lock();
413 thrd->setHandlerState(int_thread::exited);
414 thrd->setInternalState(int_thread::exited);
415 thrd->setUserState(int_thread::exited);
416 ProcPool()->rmThread(thrd);
417 proc->threadPool()->rmThread(thrd);
421 ProcPool()->condvar()->signal();
422 ProcPool()->condvar()->unlock();
426 HandleThreadStop::HandleThreadStop() :
427 Handler(std::string("Thread Stop"))
431 HandleThreadStop::~HandleThreadStop()
435 void HandleThreadStop::getEventTypesHandled(std::vector<EventType> &etypes)
437 etypes.push_back(EventType(EventType::None, EventType::Stop));
440 bool HandleThreadStop::handleEvent(Event::ptr ev)
442 int_thread *thrd = ev->getThread()->llthrd();
443 int_process *proc = ev->getProcess()->llproc();
444 pthrd_printf("Handling thread stop for %d/%d\n", proc->getPid(), thrd->getLWP());
446 assert(thrd->hasPendingStop());
447 thrd->setPendingStop(false);
449 thrd->setInternalState(int_thread::stopped);
450 if (thrd->hasPendingUserStop()) {
451 thrd->setUserState(int_thread::stopped);
452 thrd->setPendingUserStop(false);
458 HandlePostFork::HandlePostFork() :
463 HandlePostFork::~HandlePostFork()
467 void HandlePostFork::getEventTypesHandled(std::vector<EventType> &etypes)
469 etypes.push_back(EventType(EventType::Post, EventType::Fork));
472 bool HandlePostFork::handleEvent(Event::ptr ev)
474 EventFork *efork = static_cast<EventFork *>(ev.get());
475 Dyninst::PID child_pid = efork->getPID();
476 int_process *parent_proc = ev->getProcess()->llproc();
477 pthrd_printf("Handling fork for parent %d to child %d\n",
478 parent_proc->getPid(), child_pid);
480 int_process *child_proc = int_process::createProcess(child_pid, parent_proc);
482 return child_proc->forked();
485 HandlePostExec::HandlePostExec() :
490 HandlePostExec::~HandlePostExec()
494 void HandlePostExec::getEventTypesHandled(std::vector<EventType> &etypes)
496 etypes.push_back(EventType(EventType::Post, EventType::Exec));
499 bool HandlePostExec::handleEvent(Event::ptr ev)
501 EventExec *eexec = static_cast<EventExec *>(ev.get());
502 int_process *proc = ev->getProcess()->llproc();
503 pthrd_printf("Handling exec for process %d\n",
506 bool result = proc->execed();
510 eexec->setExecPath(proc->getExecutable());
511 eexec->setThread(proc->threadPool()->initialThread()->thread());
515 HandleSingleStep::HandleSingleStep() :
516 Handler("Single Step")
520 HandleSingleStep::~HandleSingleStep()
524 void HandleSingleStep::getEventTypesHandled(vector<EventType> &etypes)
526 etypes.push_back(EventType(EventType::None, EventType::SingleStep));
529 bool HandleSingleStep::handleEvent(Event::ptr ev)
531 pthrd_printf("Handling event single step on %d/%d\n",
532 ev->getProcess()->llproc()->getPid(),
533 ev->getThread()->llthrd()->getLWP());
534 ev->getThread()->llthrd()->setUserState(int_thread::stopped);
535 ev->getThread()->llthrd()->setInternalState(int_thread::stopped);
539 HandleBreakpoint::HandleBreakpoint() :
540 Handler("Breakpoint")
544 HandleBreakpoint::~HandleBreakpoint()
548 void HandleBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
550 etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
553 bool HandleBreakpoint::handleEvent(Event::ptr ev)
555 pthrd_printf("Handling breakpoint\n");
556 int_process *proc = ev->getProcess()->llproc();
558 EventBreakpoint *ebp = static_cast<EventBreakpoint *>(ev.get());
559 std::vector<Breakpoint::ptr> hl_bps;
560 ebp->getBreakpoints(hl_bps);
561 bool has_user_breakpoints = !hl_bps.empty();
563 if (has_user_breakpoints)
565 int_threadPool *pool = proc->threadPool();
566 for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
567 (*i)->setUserState(int_thread::stopped);
574 HandlePostBreakpoint::HandlePostBreakpoint() :
575 Handler("Post Breakpoint")
579 HandlePostBreakpoint::~HandlePostBreakpoint()
583 void HandlePostBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
585 etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
588 bool HandlePostBreakpoint::handleEvent(Event::ptr ev)
590 int_process *proc = ev->getProcess()->llproc();
591 int_thread *thrd = ev->getThread()->llthrd();
594 * TODO: Ctrl transfer breakpoints
598 * Stop all other threads in the job while we remove the breakpoint, single step
599 * through the instruction and then resume the other threads
601 pthrd_printf("Marking all threads in %d stopped for internal breakpoint handling\n",
603 int_threadPool *pool = proc->threadPool();
604 for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
605 if ((*i)->getInternalState() == int_thread::running) {
606 (*i)->setInternalState(int_thread::stopped);
610 EventBreakpoint *evbp = static_cast<EventBreakpoint *>(ev.get());
611 installed_breakpoint *bp = evbp->installedbp();
613 pthrd_printf("Setting breakpoint thread to single step mode\n");
614 thrd->setSingleStepMode(true);
615 thrd->markClearingBreakpoint(bp);
617 pthrd_printf("Removing breakpoint from memory\n");
618 bool result = bp->suspend(proc);
621 pthrd_printf("Restoring PC to original location location at %lx\n", bp->getAddr());
622 MachRegister pcreg = MachRegister::getPC(proc->getTargetArch());
623 result = thrd->setRegister(pcreg, (MachRegisterVal) bp->getAddr());
626 thrd->setInternalState(int_thread::running);
631 HandleBreakpointClear::HandleBreakpointClear() :
632 Handler("Breakpoint Clear")
636 HandleBreakpointClear::~HandleBreakpointClear()
640 void HandleBreakpointClear::getEventTypesHandled(vector<EventType> &etypes)
642 etypes.push_back(EventType(EventType::None, EventType::BreakpointClear));
645 bool HandleBreakpointClear::handleEvent(Event::ptr ev)
647 int_process *proc = ev->getProcess()->llproc();
648 int_thread *thrd = ev->getThread()->llthrd();
649 EventBreakpointClear *bpc = static_cast<EventBreakpointClear *>(ev.get());
650 installed_breakpoint *bp = bpc->bp();
652 pthrd_printf("Resuming breakpoint at %lx\n", bp->getAddr());
655 pthrd_printf("Restoring process state\n");
656 thrd->setSingleStepMode(false);
657 thrd->markClearingBreakpoint(NULL);
658 thrd->setInternalState(int_thread::stopped);
660 proc->threadPool()->restoreInternalState(false);
665 int HandlePostBreakpoint::getPriority() const
667 return Handler::PostCallbackPriority;
670 HandleLibrary::HandleLibrary() :
671 Handler("SysV Library Handler")
675 HandleLibrary::~HandleLibrary()
679 bool HandleLibrary::handleEvent(Event::ptr ev)
681 pthrd_printf("Handling library load/unload\n");
682 EventLibrary *lev = static_cast<EventLibrary *>(ev.get());
684 int_process *proc = ev->getProcess()->llproc();
685 set<int_library *> ll_added, ll_rmd;
686 bool result = proc->refresh_libraries(ll_added, ll_rmd);
688 pthrd_printf("Failed to refresh library list\n");
691 if (ll_added.empty() && ll_rmd.empty()) {
692 pthrd_printf("Could not find actual changes in lib state\n");
696 set<Library::ptr> added, rmd;
697 for (set<int_library*>::iterator i = ll_added.begin(); i != ll_added.end(); i++) {
698 added.insert((*i)->getUpPtr());
700 for (set<int_library*>::iterator i = ll_rmd.begin(); i != ll_rmd.end(); i++) {
701 rmd.insert((*i)->getUpPtr());
703 lev->setLibs(added, rmd);
707 void HandleLibrary::getEventTypesHandled(std::vector<EventType> &etypes)
709 etypes.push_back(EventType(EventType::None, EventType::Library));
712 HandleCallbacks::HandleCallbacks() :
717 HandleCallbacks::~HandleCallbacks()
721 HandleCallbacks *HandleCallbacks::getCB()
723 static HandleCallbacks *cb = NULL;
725 cb = new HandleCallbacks();
731 int HandleCallbacks::getPriority() const
733 return CallbackPriority;
736 void HandleCallbacks::getEventTypesHandled(std::vector<EventType> & /*etypes*/)
738 //Callbacks are special cased, they respond to all event types.
741 bool HandleCallbacks::hasCBs(Event::const_ptr ev)
743 return cbfuncs.find(ev->getEventType()) != cbfuncs.end();
746 bool HandleCallbacks::requiresCB(Event::const_ptr ev)
748 return hasCBs(ev) && !ev->suppressCB();
751 bool HandleCallbacks::handleEvent(Event::ptr ev)
753 EventType evtype = ev->getEventType();
754 std::map<EventType, std::set<Process::cb_func_t>, eventtype_cmp>::iterator i = cbfuncs.find(evtype);
755 if (i == cbfuncs.end()) {
756 pthrd_printf("No callback registered for event type '%s'\n", ev->name().c_str());
759 int_process *proc = ev->getProcess()->llproc();
761 (proc->getState() == int_process::neonatal ||
762 proc->getState() == int_process::neonatal_intermediate))
764 pthrd_printf("No callback for neonatal process %d\n", proc->getPid());
767 const std::set<Process::cb_func_t> &cbs = i->second;
769 return deliverCallback(ev, cbs);
772 static const char *action_str(Process::cb_action_t action)
775 case Process::cbThreadContinue:
776 return "cbThreadContinue";
777 case Process::cbThreadStop:
778 return "cbThreadStop";
779 case Process::cbProcContinue:
780 return "cbProcContinue";
781 case Process::cbProcStop:
783 case Process::cbDefault:
792 bool HandleCallbacks::handleCBReturn(Process::const_ptr proc, Thread::const_ptr thrd,
793 Process::cb_action_t ret)
796 case Process::cbThreadContinue:
797 if (thrd == Thread::const_ptr()) {
798 perr_printf("User returned invalid action %s for event\n",
802 pthrd_printf("Callbacks returned thread continue\n");
803 thrd->llthrd()->setUserState(int_thread::running);
804 thrd->llthrd()->setInternalState(int_thread::running);
806 case Process::cbThreadStop:
807 if (thrd == Thread::const_ptr()) {
808 perr_printf("User returned invalid action %s for event\n",
812 pthrd_printf("Callbacks returned thread stop\n");
813 thrd->llthrd()->setUserState(int_thread::stopped);
814 thrd->llthrd()->setInternalState(int_thread::stopped);
816 case Process::cbProcContinue: {
817 if (proc == Process::const_ptr()) {
818 perr_printf("User returned invalid action %s for event\n",
822 pthrd_printf("Callbacks returned process continue\n");
823 int_threadPool *tp = proc->llproc()->threadPool();
824 for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
825 (*j)->setUserState(int_thread::running);
826 (*j)->setInternalState(int_thread::running);
830 case Process::cbProcStop: {
831 if (proc == Process::const_ptr()) {
832 perr_printf("User returned invalid action %s for event\n",
836 pthrd_printf("Callbacks returned process stop\n");
837 int_threadPool *tp = proc->llproc()->threadPool();
838 for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
839 (*j)->setUserState(int_thread::stopped);
840 (*j)->setInternalState(int_thread::stopped);
844 case Process::cbDefault:
845 pthrd_printf("Callbacks returned default\n");
851 bool HandleCallbacks::deliverCallback(Event::ptr ev, const set<Process::cb_func_t> &cbset)
853 if (ev->suppressCB()) {
854 pthrd_printf("Suppressing callbacks for event %s\n", ev->name().c_str());
855 if (mt()->getThreadMode() == Process::HandlerThreading &&
856 notify()->hasEvents())
858 notify()->clearEvent();
863 //The following code loops over each callback registered for this event type
864 // and triggers the callback for the user. Return results are aggregated.
865 assert(!(isHandlerThread() && mt()->getThreadMode() != Process::CallbackThreading));
867 pthrd_printf("Triggering callback for event '%s'\n", ev->name().c_str());
868 Process::cb_action_t parent_result = Process::cbDefault;
869 Process::cb_action_t child_result = Process::cbDefault;
870 std::set<Process::cb_func_t>::iterator j;
871 for (j = cbset.begin(); j != cbset.end(); j++, k++) {
872 pthrd_printf("Triggering callback #%u for event '%s'\n", k, ev->name().c_str());
873 int_process::setInCB(true);
874 Process::cb_ret_t ret = (*j)(ev);
875 int_process::setInCB(false);
877 if (ret.parent != Process::cbDefault)
878 parent_result = ret.parent;
879 if (ret.child != Process::cbDefault)
880 child_result = ret.child;
882 pthrd_printf("Callback #%u return %s/%s\n", k, action_str(ret.parent),
883 action_str(ret.child));
886 //Given the callback return result, change the user state to the appropriate
888 pthrd_printf("Handling return value for main process\n");
889 handleCBReturn(ev->getProcess(), ev->getThread(), parent_result);
891 pthrd_printf("Handling return value for child process/thread\n");
892 Process::const_ptr child_proc = Process::const_ptr();
893 Thread::const_ptr child_thread = Thread::const_ptr();
894 bool event_has_child = false;
895 switch (ev->getEventType().code()) {
896 case EventType::Fork:
897 event_has_child = true;
898 child_proc = static_cast<EventFork *>(ev.get())->getChildProcess();
900 case EventType::ThreadCreate:
901 event_has_child = true;
902 child_thread = static_cast<EventNewThread *>(ev.get())->getNewThread();
906 handleCBReturn(child_proc, child_thread, child_result);
908 if (mt()->getThreadMode() == Process::HandlerThreading &&
909 notify()->hasEvents())
911 notify()->clearEvent();
917 bool HandleCallbacks::registerCallback_int(EventType ev, Process::cb_func_t func)
919 pthrd_printf("Registering event %s with callback function %p\n", ev.name().c_str(), func);
920 std::set<EventType>::iterator i = alleventtypes.find(ev);
921 if (i == alleventtypes.end()) {
922 pthrd_printf("Event %s does not have any handler\n", ev.name().c_str());
925 cbfuncs[ev].insert(func);
929 bool HandleCallbacks::registerCallback(EventType ev, Process::cb_func_t func)
933 case EventType::Post:
934 case EventType::None: {
935 bool result = registerCallback_int(ev, func);
937 pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
938 setLastError(err_noevents, "EventType does not exist");
943 case EventType::Any: {
944 bool result1 = registerCallback_int(EventType(EventType::Pre, ev.code()), func);
945 bool result2 = registerCallback_int(EventType(EventType::Post, ev.code()), func);
946 bool result3 = registerCallback_int(EventType(EventType::None, ev.code()), func);
947 if (!result1 && !result2 && !result3) {
948 pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
949 setLastError(err_noevents, "EventType does not exist");
958 bool HandleCallbacks::removeCallback_int(EventType et, Process::cb_func_t func)
960 cbfuncs_t::iterator i = cbfuncs.find(et);
961 if (i == cbfuncs.end()) {
964 set<Process::cb_func_t> &func_set = i->second;
965 set<Process::cb_func_t>::iterator j = func_set.find(func);
966 if (j == func_set.end()) {
973 bool HandleCallbacks::removeCallback(EventType et, Process::cb_func_t func)
978 case EventType::Post:
979 case EventType::None: {
980 result = removeCallback_int(et, func);
982 case EventType::Any: {
983 bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()), func);
984 bool result2 = removeCallback_int(EventType(EventType::Post,et.code()), func);
985 bool result3 = removeCallback_int(EventType(EventType::None,et.code()), func);
986 result = (result1 || result2 || result3);
990 perr_printf("Attempted to remove non-existant callback %s\n",
992 setLastError(err_badparam, "Callback does not exist");
998 bool HandleCallbacks::removeCallback_int(EventType et)
1000 cbfuncs_t::iterator i = cbfuncs.find(et);
1001 if (i == cbfuncs.end()) {
1008 bool HandleCallbacks::removeCallback(EventType et)
1010 bool result = false;
1011 switch (et.time()) {
1012 case EventType::Pre:
1013 case EventType::Post:
1014 case EventType::None: {
1015 result = removeCallback_int(et);
1017 case EventType::Any: {
1018 bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()));
1019 bool result2 = removeCallback_int(EventType(EventType::Post,et.code()));
1020 bool result3 = removeCallback_int(EventType(EventType::None,et.code()));
1021 result = (result1 || result2 || result3);
1025 perr_printf("Attempted to remove non-existant callback %s\n",
1027 setLastError(err_badparam, "Callback does not exist");
1033 bool HandleCallbacks::removeCallback(Process::cb_func_t func)
1035 bool rmd_something = false;
1036 for (cbfuncs_t::iterator i = cbfuncs.begin(); i != cbfuncs.end(); i++)
1038 EventType et = i->first;
1039 bool result = removeCallback_int(et, func);
1041 rmd_something = true;
1043 if (!rmd_something) {
1044 perr_printf("Attempted to remove non-existant callback %p\n", func);
1045 setLastError(err_badparam, "Callback does not exist");
1051 HandlerPool *createDefaultHandlerPool()
1053 static bool initialized = false;
1054 static HandleBootstrap *hbootstrap = NULL;
1055 static HandleSignal *hsignal = NULL;
1056 static HandlePostExit *hpostexit = NULL;
1057 static HandlePreExit *hpreexit = NULL;
1058 static HandleThreadCreate *hthreadcreate = NULL;
1059 static HandleThreadDestroy *hthreaddestroy = NULL;
1060 static HandleThreadStop *hthreadstop = NULL;
1061 static HandleSingleStep *hsinglestep = NULL;
1062 static HandleCrash *hcrash = NULL;
1063 static HandleBreakpoint *hbpoint = NULL;
1064 static HandlePostBreakpoint *hpost_bpoint = NULL;
1065 static HandleBreakpointClear *hbpclear = NULL;
1066 static HandleLibrary *hlibrary = NULL;
1067 static HandlePostFork *hpostfork = NULL;
1068 static HandlePostExec *hpostexec = NULL;
1069 static iRPCHandler *hrpc = NULL;
1071 hbootstrap = new HandleBootstrap();
1072 hsignal = new HandleSignal();
1073 hpostexit = new HandlePostExit();
1074 hpreexit = new HandlePreExit();
1075 hthreadcreate = new HandleThreadCreate();
1076 hthreaddestroy = new HandleThreadDestroy();
1077 hthreadstop = new HandleThreadStop();
1078 hsinglestep = new HandleSingleStep();
1079 hcrash = new HandleCrash();
1080 hbpoint = new HandleBreakpoint();
1081 hpost_bpoint = new HandlePostBreakpoint();
1082 hbpclear = new HandleBreakpointClear();
1083 hrpc = new iRPCHandler();
1084 hlibrary = new HandleLibrary();
1085 hpostfork = new HandlePostFork();
1086 hpostexec = new HandlePostExec();
1089 HandlerPool *hpool = new HandlerPool();
1090 hpool->addHandler(hbootstrap);
1091 hpool->addHandler(hsignal);
1092 hpool->addHandler(hpostexit);
1093 hpool->addHandler(hpreexit);
1094 hpool->addHandler(hthreadcreate);
1095 hpool->addHandler(hthreaddestroy);
1096 hpool->addHandler(hthreadstop);
1097 hpool->addHandler(hsinglestep);
1098 hpool->addHandler(hcrash);
1099 hpool->addHandler(hbpoint);
1100 hpool->addHandler(hpost_bpoint);
1101 hpool->addHandler(hbpclear);
1102 hpool->addHandler(hrpc);
1103 hpool->addHandler(hlibrary);
1104 hpool->addHandler(hpostfork);
1105 hpool->addHandler(hpostexec);
1106 plat_createDefaultHandlerPool(hpool);