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");
288 HandleCrash::HandleCrash() :
293 HandleCrash::~HandleCrash()
297 void HandleCrash::getEventTypesHandled(std::vector<EventType> &etypes)
299 etypes.push_back(EventType(EventType::Post, EventType::Crash));
302 bool HandleCrash::handleEvent(Event::ptr ev)
304 int_process *proc = ev->getProcess()->llproc();
305 int_thread *thrd = ev->getThread()->llthrd();
308 pthrd_printf("Handling crash for process %d on thread %d\n",
309 proc->getPid(), thrd->getLWP());
310 EventCrash *event = static_cast<EventCrash *>(ev.get());
311 proc->setCrashSignal(event->getTermSignal());
313 ProcPool()->condvar()->lock();
315 proc->setState(int_process::exited);
316 ProcPool()->rmProcess(proc);
318 ProcPool()->condvar()->signal();
319 ProcPool()->condvar()->unlock();
326 HandlePreExit::HandlePreExit() :
331 HandlePreExit::~HandlePreExit()
335 void HandlePreExit::getEventTypesHandled(std::vector<EventType> &etypes)
337 etypes.push_back(EventType(EventType::Pre, EventType::Exit));
340 bool HandlePreExit::handleEvent(Event::ptr ev)
342 pthrd_printf("Handling pre-exit for process %d on thread %d\n",
343 ev->getProcess()->llproc()->getPid(),
344 ev->getThread()->llthrd()->getLWP());
349 HandleThreadCreate::HandleThreadCreate() :
350 Handler("Thread Create")
354 HandleThreadCreate::~HandleThreadCreate()
358 void HandleThreadCreate::getEventTypesHandled(std::vector<EventType> &etypes)
360 etypes.push_back(EventType(EventType::None, EventType::ThreadCreate));
363 bool HandleThreadCreate::handleEvent(Event::ptr ev)
365 int_process *proc = ev->getProcess()->llproc();
366 int_thread *thrd = ev->getThread()->llthrd();
367 EventNewThread *threadev = static_cast<EventNewThread *>(ev.get());
369 pthrd_printf("Handle thread create for %d/%d with new thread %d\n",
370 proc->getPid(), thrd ? thrd->getLWP() : -1, threadev->getLWP());
372 ProcPool()->condvar()->lock();
374 int_thread *newthr = int_thread::createThread(proc, 0, threadev->getLWP(), false);
375 //New threads start stopped, but inherit the user state of the creating
376 // thread (which should be 'running').
377 newthr->setGeneratorState(int_thread::stopped);
378 newthr->setHandlerState(int_thread::stopped);
379 newthr->setInternalState(thrd->getUserState());
380 newthr->setUserState(thrd->getUserState());
382 ProcPool()->condvar()->signal();
383 ProcPool()->condvar()->unlock();
388 HandleThreadDestroy::HandleThreadDestroy() :
389 Handler("Thread Destroy")
393 HandleThreadDestroy::~HandleThreadDestroy()
397 void HandleThreadDestroy::getEventTypesHandled(std::vector<EventType> &etypes)
399 etypes.push_back(EventType(EventType::Any, EventType::ThreadDestroy));
402 bool HandleThreadDestroy::handleEvent(Event::ptr ev)
404 int_thread *thrd = ev->getThread()->llthrd();
405 int_process *proc = ev->getProcess()->llproc();
406 if (ev->getEventType().time() == EventType::Pre) {
407 pthrd_printf("Handling pre-thread destroy for %d\n", thrd->getLWP());
411 pthrd_printf("Handling post-thread destroy for %d\n", thrd->getLWP());
412 ProcPool()->condvar()->lock();
414 thrd->setHandlerState(int_thread::exited);
415 thrd->setInternalState(int_thread::exited);
416 thrd->setUserState(int_thread::exited);
417 ProcPool()->rmThread(thrd);
418 proc->threadPool()->rmThread(thrd);
422 ProcPool()->condvar()->signal();
423 ProcPool()->condvar()->unlock();
427 HandleThreadStop::HandleThreadStop() :
428 Handler(std::string("Thread Stop"))
432 HandleThreadStop::~HandleThreadStop()
436 void HandleThreadStop::getEventTypesHandled(std::vector<EventType> &etypes)
438 etypes.push_back(EventType(EventType::None, EventType::Stop));
441 bool HandleThreadStop::handleEvent(Event::ptr ev)
443 int_thread *thrd = ev->getThread()->llthrd();
444 int_process *proc = ev->getProcess()->llproc();
445 pthrd_printf("Handling thread stop for %d/%d\n", proc->getPid(), thrd->getLWP());
447 assert(thrd->hasPendingStop());
448 thrd->setPendingStop(false);
450 thrd->setInternalState(int_thread::stopped);
451 if (thrd->hasPendingUserStop()) {
452 thrd->setUserState(int_thread::stopped);
453 thrd->setPendingUserStop(false);
459 HandlePostFork::HandlePostFork() :
464 HandlePostFork::~HandlePostFork()
468 void HandlePostFork::getEventTypesHandled(std::vector<EventType> &etypes)
470 etypes.push_back(EventType(EventType::Post, EventType::Fork));
473 bool HandlePostFork::handleEvent(Event::ptr ev)
475 EventFork *efork = static_cast<EventFork *>(ev.get());
476 Dyninst::PID child_pid = efork->getPID();
477 int_process *parent_proc = ev->getProcess()->llproc();
478 pthrd_printf("Handling fork for parent %d to child %d\n",
479 parent_proc->getPid(), child_pid);
481 int_process *child_proc = int_process::createProcess(child_pid, parent_proc);
483 return child_proc->forked();
486 HandlePostExec::HandlePostExec() :
491 HandlePostExec::~HandlePostExec()
495 void HandlePostExec::getEventTypesHandled(std::vector<EventType> &etypes)
497 etypes.push_back(EventType(EventType::Post, EventType::Exec));
500 bool HandlePostExec::handleEvent(Event::ptr ev)
502 EventExec *eexec = static_cast<EventExec *>(ev.get());
503 int_process *proc = ev->getProcess()->llproc();
504 pthrd_printf("Handling exec for process %d\n",
507 bool result = proc->execed();
511 eexec->setExecPath(proc->getExecutable());
512 eexec->setThread(proc->threadPool()->initialThread()->thread());
516 HandleSingleStep::HandleSingleStep() :
517 Handler("Single Step")
521 HandleSingleStep::~HandleSingleStep()
525 void HandleSingleStep::getEventTypesHandled(vector<EventType> &etypes)
527 etypes.push_back(EventType(EventType::None, EventType::SingleStep));
530 bool HandleSingleStep::handleEvent(Event::ptr ev)
532 pthrd_printf("Handling event single step on %d/%d\n",
533 ev->getProcess()->llproc()->getPid(),
534 ev->getThread()->llthrd()->getLWP());
535 ev->getThread()->llthrd()->setUserState(int_thread::stopped);
536 ev->getThread()->llthrd()->setInternalState(int_thread::stopped);
540 HandleBreakpoint::HandleBreakpoint() :
541 Handler("Breakpoint")
545 HandleBreakpoint::~HandleBreakpoint()
549 void HandleBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
551 etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
554 bool HandleBreakpoint::handleEvent(Event::ptr ev)
556 pthrd_printf("Handling breakpoint\n");
557 int_process *proc = ev->getProcess()->llproc();
559 EventBreakpoint *ebp = static_cast<EventBreakpoint *>(ev.get());
560 std::vector<Breakpoint::ptr> hl_bps;
561 ebp->getBreakpoints(hl_bps);
562 bool has_user_breakpoints = !hl_bps.empty();
564 if (has_user_breakpoints)
566 int_threadPool *pool = proc->threadPool();
567 for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
568 (*i)->setUserState(int_thread::stopped);
575 HandlePostBreakpoint::HandlePostBreakpoint() :
576 Handler("Post Breakpoint")
580 HandlePostBreakpoint::~HandlePostBreakpoint()
584 void HandlePostBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
586 etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
589 bool HandlePostBreakpoint::handleEvent(Event::ptr ev)
591 int_process *proc = ev->getProcess()->llproc();
592 int_thread *thrd = ev->getThread()->llthrd();
595 * TODO: Ctrl transfer breakpoints
599 * Stop all other threads in the job while we remove the breakpoint, single step
600 * through the instruction and then resume the other threads
602 pthrd_printf("Marking all threads in %d stopped for internal breakpoint handling\n",
604 int_threadPool *pool = proc->threadPool();
605 for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
606 if ((*i)->getInternalState() == int_thread::running) {
607 (*i)->setInternalState(int_thread::stopped);
611 EventBreakpoint *evbp = static_cast<EventBreakpoint *>(ev.get());
612 installed_breakpoint *bp = evbp->installedbp();
614 pthrd_printf("Setting breakpoint thread to single step mode\n");
615 thrd->setSingleStepMode(true);
616 thrd->markClearingBreakpoint(bp);
618 pthrd_printf("Removing breakpoint from memory\n");
619 bool result = bp->suspend(proc);
622 pthrd_printf("Restoring PC to original location location at %lx\n", bp->getAddr());
623 MachRegister pcreg = MachRegister::getPC(proc->getTargetArch());
624 result = thrd->setRegister(pcreg, (MachRegisterVal) bp->getAddr());
627 thrd->setInternalState(int_thread::running);
632 HandleBreakpointClear::HandleBreakpointClear() :
633 Handler("Breakpoint Clear")
637 HandleBreakpointClear::~HandleBreakpointClear()
641 void HandleBreakpointClear::getEventTypesHandled(vector<EventType> &etypes)
643 etypes.push_back(EventType(EventType::None, EventType::BreakpointClear));
646 bool HandleBreakpointClear::handleEvent(Event::ptr ev)
648 int_process *proc = ev->getProcess()->llproc();
649 int_thread *thrd = ev->getThread()->llthrd();
650 EventBreakpointClear *bpc = static_cast<EventBreakpointClear *>(ev.get());
651 installed_breakpoint *bp = bpc->bp();
653 pthrd_printf("Resuming breakpoint at %lx\n", bp->getAddr());
656 pthrd_printf("Restoring process state\n");
657 thrd->setSingleStepMode(false);
658 thrd->markClearingBreakpoint(NULL);
659 thrd->setInternalState(int_thread::stopped);
661 proc->threadPool()->restoreInternalState(false);
666 int HandlePostBreakpoint::getPriority() const
668 return Handler::PostCallbackPriority;
671 HandleLibrary::HandleLibrary() :
672 Handler("SysV Library Handler")
676 HandleLibrary::~HandleLibrary()
680 bool HandleLibrary::handleEvent(Event::ptr ev)
682 pthrd_printf("Handling library load/unload\n");
683 EventLibrary *lev = static_cast<EventLibrary *>(ev.get());
685 int_process *proc = ev->getProcess()->llproc();
686 set<int_library *> ll_added, ll_rmd;
687 bool result = proc->refresh_libraries(ll_added, ll_rmd);
689 pthrd_printf("Failed to refresh library list\n");
692 if (ll_added.empty() && ll_rmd.empty()) {
693 pthrd_printf("Could not find actual changes in lib state\n");
697 set<Library::ptr> added, rmd;
698 for (set<int_library*>::iterator i = ll_added.begin(); i != ll_added.end(); i++) {
699 added.insert((*i)->getUpPtr());
701 for (set<int_library*>::iterator i = ll_rmd.begin(); i != ll_rmd.end(); i++) {
702 rmd.insert((*i)->getUpPtr());
704 lev->setLibs(added, rmd);
708 void HandleLibrary::getEventTypesHandled(std::vector<EventType> &etypes)
710 etypes.push_back(EventType(EventType::None, EventType::Library));
713 HandleCallbacks::HandleCallbacks() :
718 HandleCallbacks::~HandleCallbacks()
722 HandleCallbacks *HandleCallbacks::getCB()
724 static HandleCallbacks *cb = NULL;
726 cb = new HandleCallbacks();
732 int HandleCallbacks::getPriority() const
734 return CallbackPriority;
737 void HandleCallbacks::getEventTypesHandled(std::vector<EventType> & /*etypes*/)
739 //Callbacks are special cased, they respond to all event types.
742 bool HandleCallbacks::hasCBs(Event::const_ptr ev)
744 return cbfuncs.find(ev->getEventType()) != cbfuncs.end();
747 bool HandleCallbacks::requiresCB(Event::const_ptr ev)
749 return hasCBs(ev) && !ev->suppressCB();
752 bool HandleCallbacks::handleEvent(Event::ptr ev)
754 EventType evtype = ev->getEventType();
755 std::map<EventType, std::set<Process::cb_func_t>, eventtype_cmp>::iterator i = cbfuncs.find(evtype);
756 if (i == cbfuncs.end()) {
757 pthrd_printf("No callback registered for event type '%s'\n", ev->name().c_str());
760 int_process *proc = ev->getProcess()->llproc();
762 (proc->getState() == int_process::neonatal ||
763 proc->getState() == int_process::neonatal_intermediate))
765 pthrd_printf("No callback for neonatal process %d\n", proc->getPid());
768 const std::set<Process::cb_func_t> &cbs = i->second;
770 return deliverCallback(ev, cbs);
773 static const char *action_str(Process::cb_action_t action)
776 case Process::cbThreadContinue:
777 return "cbThreadContinue";
778 case Process::cbThreadStop:
779 return "cbThreadStop";
780 case Process::cbProcContinue:
781 return "cbProcContinue";
782 case Process::cbProcStop:
784 case Process::cbDefault:
793 bool HandleCallbacks::handleCBReturn(Process::const_ptr proc, Thread::const_ptr thrd,
794 Process::cb_action_t ret)
797 case Process::cbThreadContinue:
798 if (thrd == Thread::const_ptr()) {
799 perr_printf("User returned invalid action %s for event\n",
803 pthrd_printf("Callbacks returned thread continue\n");
804 thrd->llthrd()->setUserState(int_thread::running);
805 thrd->llthrd()->setInternalState(int_thread::running);
807 case Process::cbThreadStop:
808 if (thrd == Thread::const_ptr()) {
809 perr_printf("User returned invalid action %s for event\n",
813 pthrd_printf("Callbacks returned thread stop\n");
814 thrd->llthrd()->setUserState(int_thread::stopped);
815 thrd->llthrd()->setInternalState(int_thread::stopped);
817 case Process::cbProcContinue: {
818 if (proc == Process::const_ptr()) {
819 perr_printf("User returned invalid action %s for event\n",
823 pthrd_printf("Callbacks returned process continue\n");
824 int_threadPool *tp = proc->llproc()->threadPool();
825 for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
826 (*j)->setUserState(int_thread::running);
827 (*j)->setInternalState(int_thread::running);
831 case Process::cbProcStop: {
832 if (proc == Process::const_ptr()) {
833 perr_printf("User returned invalid action %s for event\n",
837 pthrd_printf("Callbacks returned process stop\n");
838 int_threadPool *tp = proc->llproc()->threadPool();
839 for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
840 (*j)->setUserState(int_thread::stopped);
841 (*j)->setInternalState(int_thread::stopped);
845 case Process::cbDefault:
846 pthrd_printf("Callbacks returned default\n");
852 bool HandleCallbacks::deliverCallback(Event::ptr ev, const set<Process::cb_func_t> &cbset)
854 if (ev->suppressCB()) {
855 pthrd_printf("Suppressing callbacks for event %s\n", ev->name().c_str());
856 if (mt()->getThreadMode() == Process::HandlerThreading &&
857 notify()->hasEvents())
859 notify()->clearEvent();
864 //The following code loops over each callback registered for this event type
865 // and triggers the callback for the user. Return results are aggregated.
866 assert(!(isHandlerThread() && mt()->getThreadMode() != Process::CallbackThreading));
868 pthrd_printf("Triggering callback for event '%s'\n", ev->name().c_str());
869 Process::cb_action_t parent_result = Process::cbDefault;
870 Process::cb_action_t child_result = Process::cbDefault;
871 std::set<Process::cb_func_t>::iterator j;
872 for (j = cbset.begin(); j != cbset.end(); j++, k++) {
873 pthrd_printf("Triggering callback #%u for event '%s'\n", k, ev->name().c_str());
874 int_process::setInCB(true);
875 Process::cb_ret_t ret = (*j)(ev);
876 int_process::setInCB(false);
878 if (ret.parent != Process::cbDefault)
879 parent_result = ret.parent;
880 if (ret.child != Process::cbDefault)
881 child_result = ret.child;
883 pthrd_printf("Callback #%u return %s/%s\n", k, action_str(ret.parent),
884 action_str(ret.child));
887 //Given the callback return result, change the user state to the appropriate
889 pthrd_printf("Handling return value for main process\n");
890 handleCBReturn(ev->getProcess(), ev->getThread(), parent_result);
892 pthrd_printf("Handling return value for child process/thread\n");
893 Process::const_ptr child_proc = Process::const_ptr();
894 Thread::const_ptr child_thread = Thread::const_ptr();
895 bool event_has_child = false;
896 switch (ev->getEventType().code()) {
897 case EventType::Fork:
898 event_has_child = true;
899 child_proc = static_cast<EventFork *>(ev.get())->getChildProcess();
901 case EventType::ThreadCreate:
902 event_has_child = true;
903 child_thread = static_cast<EventNewThread *>(ev.get())->getNewThread();
907 handleCBReturn(child_proc, child_thread, child_result);
909 if (mt()->getThreadMode() == Process::HandlerThreading &&
910 notify()->hasEvents())
912 notify()->clearEvent();
918 bool HandleCallbacks::registerCallback_int(EventType ev, Process::cb_func_t func)
920 pthrd_printf("Registering event %s with callback function %p\n", ev.name().c_str(), func);
921 std::set<EventType>::iterator i = alleventtypes.find(ev);
922 if (i == alleventtypes.end()) {
923 pthrd_printf("Event %s does not have any handler\n", ev.name().c_str());
926 cbfuncs[ev].insert(func);
930 bool HandleCallbacks::registerCallback(EventType ev, Process::cb_func_t func)
934 case EventType::Post:
935 case EventType::None: {
936 bool result = registerCallback_int(ev, func);
938 pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
939 setLastError(err_noevents, "EventType does not exist");
944 case EventType::Any: {
945 bool result1 = registerCallback_int(EventType(EventType::Pre, ev.code()), func);
946 bool result2 = registerCallback_int(EventType(EventType::Post, ev.code()), func);
947 bool result3 = registerCallback_int(EventType(EventType::None, ev.code()), func);
948 if (!result1 && !result2 && !result3) {
949 pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
950 setLastError(err_noevents, "EventType does not exist");
959 bool HandleCallbacks::removeCallback_int(EventType et, Process::cb_func_t func)
961 cbfuncs_t::iterator i = cbfuncs.find(et);
962 if (i == cbfuncs.end()) {
965 set<Process::cb_func_t> &func_set = i->second;
966 set<Process::cb_func_t>::iterator j = func_set.find(func);
967 if (j == func_set.end()) {
974 bool HandleCallbacks::removeCallback(EventType et, Process::cb_func_t func)
979 case EventType::Post:
980 case EventType::None: {
981 result = removeCallback_int(et, func);
983 case EventType::Any: {
984 bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()), func);
985 bool result2 = removeCallback_int(EventType(EventType::Post,et.code()), func);
986 bool result3 = removeCallback_int(EventType(EventType::None,et.code()), func);
987 result = (result1 || result2 || result3);
991 perr_printf("Attempted to remove non-existant callback %s\n",
993 setLastError(err_badparam, "Callback does not exist");
999 bool HandleCallbacks::removeCallback_int(EventType et)
1001 cbfuncs_t::iterator i = cbfuncs.find(et);
1002 if (i == cbfuncs.end()) {
1009 bool HandleCallbacks::removeCallback(EventType et)
1011 bool result = false;
1012 switch (et.time()) {
1013 case EventType::Pre:
1014 case EventType::Post:
1015 case EventType::None: {
1016 result = removeCallback_int(et);
1018 case EventType::Any: {
1019 bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()));
1020 bool result2 = removeCallback_int(EventType(EventType::Post,et.code()));
1021 bool result3 = removeCallback_int(EventType(EventType::None,et.code()));
1022 result = (result1 || result2 || result3);
1026 perr_printf("Attempted to remove non-existant callback %s\n",
1028 setLastError(err_badparam, "Callback does not exist");
1034 bool HandleCallbacks::removeCallback(Process::cb_func_t func)
1036 bool rmd_something = false;
1037 for (cbfuncs_t::iterator i = cbfuncs.begin(); i != cbfuncs.end(); i++)
1039 EventType et = i->first;
1040 bool result = removeCallback_int(et, func);
1042 rmd_something = true;
1044 if (!rmd_something) {
1045 perr_printf("Attempted to remove non-existant callback %p\n", func);
1046 setLastError(err_badparam, "Callback does not exist");
1052 HandlerPool *createDefaultHandlerPool()
1054 static bool initialized = false;
1055 static HandleBootstrap *hbootstrap = NULL;
1056 static HandleSignal *hsignal = NULL;
1057 static HandlePostExit *hpostexit = NULL;
1058 static HandlePreExit *hpreexit = NULL;
1059 static HandleThreadCreate *hthreadcreate = NULL;
1060 static HandleThreadDestroy *hthreaddestroy = NULL;
1061 static HandleThreadStop *hthreadstop = NULL;
1062 static HandleSingleStep *hsinglestep = NULL;
1063 static HandleCrash *hcrash = NULL;
1064 static HandleBreakpoint *hbpoint = NULL;
1065 static HandlePostBreakpoint *hpost_bpoint = NULL;
1066 static HandleBreakpointClear *hbpclear = NULL;
1067 static HandleLibrary *hlibrary = NULL;
1068 static HandlePostFork *hpostfork = NULL;
1069 static HandlePostExec *hpostexec = NULL;
1070 static iRPCHandler *hrpc = NULL;
1072 hbootstrap = new HandleBootstrap();
1073 hsignal = new HandleSignal();
1074 hpostexit = new HandlePostExit();
1075 hpreexit = new HandlePreExit();
1076 hthreadcreate = new HandleThreadCreate();
1077 hthreaddestroy = new HandleThreadDestroy();
1078 hthreadstop = new HandleThreadStop();
1079 hsinglestep = new HandleSingleStep();
1080 hcrash = new HandleCrash();
1081 hbpoint = new HandleBreakpoint();
1082 hpost_bpoint = new HandlePostBreakpoint();
1083 hbpclear = new HandleBreakpointClear();
1084 hrpc = new iRPCHandler();
1085 hlibrary = new HandleLibrary();
1086 hpostfork = new HandlePostFork();
1087 hpostexec = new HandlePostExec();
1090 HandlerPool *hpool = new HandlerPool();
1091 hpool->addHandler(hbootstrap);
1092 hpool->addHandler(hsignal);
1093 hpool->addHandler(hpostexit);
1094 hpool->addHandler(hpreexit);
1095 hpool->addHandler(hthreadcreate);
1096 hpool->addHandler(hthreaddestroy);
1097 hpool->addHandler(hthreadstop);
1098 hpool->addHandler(hsinglestep);
1099 hpool->addHandler(hcrash);
1100 hpool->addHandler(hbpoint);
1101 hpool->addHandler(hpost_bpoint);
1102 hpool->addHandler(hbpclear);
1103 hpool->addHandler(hrpc);
1104 hpool->addHandler(hlibrary);
1105 hpool->addHandler(hpostfork);
1106 hpool->addHandler(hpostexec);
1107 plat_createDefaultHandlerPool(hpool);