First pass at thread_db integration for FreeBSD.
[dyninst.git] / proccontrol / src / handler.C
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"
9
10 using namespace Dyninst;
11
12 #include <assert.h>
13
14 Handler::Handler(std::string name_) :
15    name(name_)
16 {
17 }
18
19 Handler::~Handler()
20 {
21 }
22
23 int Handler::getPriority() const
24 {
25    return DefaultPriority;
26 }
27
28 Event::ptr Handler::convertEventForCB(Event::ptr /*orig*/)
29 {
30    return Event::ptr();
31 }
32
33 std::string Handler::getName() const
34 {
35    return name;
36 }
37
38 HandlerPool::HandlerPool()
39 {
40 }
41
42 HandlerPool::~HandlerPool()
43 {
44    for (HandlerMap_t::iterator i = handlers.begin(); i != handlers.end(); i++) {
45       delete (*i).second;
46    }
47    //Do not delete actual Handler* objects.
48    handlers.clear();
49 }
50
51 void HandlerPool::addHandlerInt(EventType etype, Handler *handler)
52 {
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;
61    }
62    else {
63       theset = (*i).second;
64    }   
65    theset->insert(handler);
66
67    HandleCallbacks *cb = HandleCallbacks::getCB();
68    if (cb != handler) {
69       cb->alleventtypes.insert(etype);
70       if (!(etype.code() >= EventType::InternalEvents && etype.code() < EventType::MaxProcCtrlEvent))
71          addHandlerInt(etype, cb);
72    }
73 }
74
75 void HandlerPool::addHandler(Handler *handler)
76 {
77    std::vector<EventType> etypes;
78    handler->getEventTypesHandled(etypes);
79
80    for (std::vector<EventType>::iterator i = etypes.begin(); i != etypes.end(); i++)
81    {
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);
86       }
87       else {
88          addHandlerInt(*i, handler);
89       }
90    }
91 }
92
93 struct eh_cmp_func
94 {
95    bool operator()(const pair<Event::ptr, Handler*> &a,
96                    const pair<Event::ptr, Handler*> &b)
97    {
98       if (a.second->getPriority() != b.second->getPriority())
99          return a.second->getPriority() < b.second->getPriority();
100       if (a.first->subservientTo().lock() == b.first)
101          return false;
102       if (b.first->subservientTo().lock() == a.first)
103          return true;
104       eventtype_cmp cmp;
105       return cmp(a.first->getEventType(), b.first->getEventType());
106    }
107 };
108
109 bool HandlerPool::handleEvent(Event::ptr ev)
110 {
111    EventType etype = ev->getEventType();
112    Event::ptr cb_replacement_ev = Event::ptr();
113    
114    /**
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.
121     *
122     * We'll take the event and all its subservient set and run handlers
123     * for all of them.
124     **/
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++)
129    {
130       all_events.insert(*i);
131    }
132
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++)
136    {
137       Event::ptr ev = *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());
142          continue;
143       }
144       HandlerSet_t *hset = j->second;
145       for (HandlerSet_t::iterator k = hset->begin(); k != hset->end(); k++)
146       {
147          Handler *hnd = *k;
148          events_and_handlers.insert(pair<Event::ptr, Handler*>(ev, hnd));
149       }
150    }
151
152    /**
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.
156     **/
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++)
160    {
161       handled_something = true;
162       Event::ptr event = i->first;
163       Handler *handler = i->second;
164       EventType etype = ev->getEventType();
165
166       pthrd_printf("Handling event '%s' with handler '%s'\n", etype.name().c_str(), 
167                    handler->getName().c_str());
168       
169       bool result = handler->handleEvent(event);
170       if (!result) {
171          pthrd_printf("Error handling event %s with %s\n", etype.name().c_str(), 
172                       handler->getName().c_str());
173          return false;
174       }
175    }
176    return handled_something;
177 }
178
179 HandleBootstrap::HandleBootstrap() :
180    Handler(std::string("Bootstrap"))
181 {
182 }
183
184 HandleBootstrap::~HandleBootstrap()
185 {
186 }
187
188 void HandleBootstrap::getEventTypesHandled(std::vector<EventType> &etypes)
189 {
190    etypes.push_back(EventType(EventType::None, EventType::Bootstrap));
191 }
192
193 bool HandleBootstrap::handleEvent(Event::ptr ev)
194 {
195    int_process *p = ev->getProcess()->llproc();
196    assert(p);
197    pthrd_printf("Handling bootstrap for %d\n", p->getPid());
198
199    if (p->getState() != int_process::neonatal_intermediate)
200       return true;
201    
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;
209          break;
210       }
211    }
212
213    if (all_bootstrapped) {
214       pthrd_printf("All threads are bootstrapped, marking process bootstrapped\n");
215       p->setState(int_process::running);
216    }
217
218    return true;
219 }
220
221 HandleSignal::HandleSignal() :
222    Handler(std::string("Signal"))
223 {
224 }
225
226 HandleSignal::~HandleSignal()
227 {
228 }
229
230 void HandleSignal::getEventTypesHandled(std::vector<EventType> &etypes)
231 {
232    etypes.push_back(EventType(EventType::None, EventType::Signal));
233 }
234
235 bool HandleSignal::handleEvent(Event::ptr ev)
236 {
237    int_thread *thrd = ev->getThread()->llthrd();
238    
239    EventSignal *sigev = static_cast<EventSignal *>(ev.get());
240    thrd->setContSignal(sigev->getSignal());
241
242    return true;
243 }
244
245 HandlePostExit::HandlePostExit() :
246    Handler("Post Exit")
247 {
248 }
249
250 HandlePostExit::~HandlePostExit()
251 {
252 }
253
254 void HandlePostExit::getEventTypesHandled(std::vector<EventType> &etypes)
255 {
256    etypes.push_back(EventType(EventType::Post, EventType::Exit));
257 }
258
259 bool HandlePostExit::handleEvent(Event::ptr ev)
260 {
261    int_process *proc = ev->getProcess()->llproc();
262    int_thread *thrd = ev->getThread()->llthrd();
263    assert(proc);
264    assert(thrd);
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());
269    
270    ProcPool()->condvar()->lock();
271
272    proc->setState(int_process::exited);
273    ProcPool()->rmProcess(proc);
274    ProcPool()->rmThread(thrd);
275
276    ProcPool()->condvar()->signal();
277    ProcPool()->condvar()->unlock();
278
279    if (int_process::in_waitHandleProc == proc) {
280       pthrd_printf("Postponing delete due to being in waitAndHandleForProc\n");
281       delete proc;
282    }
283
284    return true;
285 }
286
287 HandleCrash::HandleCrash() :
288    Handler("Crash")
289 {
290 }
291
292 HandleCrash::~HandleCrash()
293 {
294 }
295
296 void HandleCrash::getEventTypesHandled(std::vector<EventType> &etypes)
297 {
298    etypes.push_back(EventType(EventType::Post, EventType::Crash));
299 }
300
301 bool HandleCrash::handleEvent(Event::ptr ev)
302 {
303    int_process *proc = ev->getProcess()->llproc();
304    int_thread *thrd = ev->getThread()->llthrd();
305    assert(proc);
306    assert(thrd);
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());
311    
312    ProcPool()->condvar()->lock();
313
314    proc->setState(int_process::exited);
315    ProcPool()->rmProcess(proc);
316
317    ProcPool()->condvar()->signal();
318    ProcPool()->condvar()->unlock();
319
320    delete proc;
321
322    return true;
323 }
324
325 HandlePreExit::HandlePreExit() :
326    Handler("Pre Exit")
327 {
328 }
329
330 HandlePreExit::~HandlePreExit()
331 {
332 }
333
334 void HandlePreExit::getEventTypesHandled(std::vector<EventType> &etypes)
335 {
336    etypes.push_back(EventType(EventType::Pre, EventType::Exit));
337 }
338
339 bool HandlePreExit::handleEvent(Event::ptr ev)
340 {
341    pthrd_printf("Handling pre-exit for process %d on thread %d\n",
342                 ev->getProcess()->llproc()->getPid(), 
343                 ev->getThread()->llthrd()->getLWP());
344
345    return true;
346 }
347
348 HandleThreadCreate::HandleThreadCreate() :
349    Handler("Thread Create")
350 {
351 }
352
353 HandleThreadCreate::~HandleThreadCreate()
354 {
355 }
356
357 void HandleThreadCreate::getEventTypesHandled(std::vector<EventType> &etypes)
358 {
359    etypes.push_back(EventType(EventType::None, EventType::ThreadCreate));
360 }
361
362 bool HandleThreadCreate::handleEvent(Event::ptr ev)
363 {
364    int_process *proc = ev->getProcess()->llproc();
365    int_thread *thrd = ev->getThread()->llthrd();
366    EventNewThread *threadev = static_cast<EventNewThread *>(ev.get());
367
368    pthrd_printf("Handle thread create for %d/%d with new thread %d\n",
369                 proc->getPid(), thrd ? thrd->getLWP() : -1, threadev->getLWP());
370
371    ProcPool()->condvar()->lock();
372    
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());
380    
381    ProcPool()->condvar()->signal();
382    ProcPool()->condvar()->unlock();
383
384    return true;
385 }
386
387 HandleThreadDestroy::HandleThreadDestroy() :
388    Handler("Thread Destroy")
389 {
390 }
391
392 HandleThreadDestroy::~HandleThreadDestroy()
393 {
394 }
395
396 void HandleThreadDestroy::getEventTypesHandled(std::vector<EventType> &etypes)
397 {
398    etypes.push_back(EventType(EventType::Any, EventType::ThreadDestroy));
399 }
400
401 bool HandleThreadDestroy::handleEvent(Event::ptr ev)
402 {
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());
407       return true;
408    }
409
410    pthrd_printf("Handling post-thread destroy for %d\n", thrd->getLWP());
411    ProcPool()->condvar()->lock();
412
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);
418
419    delete thrd;
420
421    ProcPool()->condvar()->signal();
422    ProcPool()->condvar()->unlock();
423    return true;
424 }
425
426 HandleThreadStop::HandleThreadStop() :
427    Handler(std::string("Thread Stop"))
428 {
429 }
430
431 HandleThreadStop::~HandleThreadStop()
432 {
433 }
434
435 void HandleThreadStop::getEventTypesHandled(std::vector<EventType> &etypes)
436 {
437    etypes.push_back(EventType(EventType::None, EventType::Stop));
438 }
439
440 bool HandleThreadStop::handleEvent(Event::ptr ev)
441 {
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());
445
446    assert(thrd->hasPendingStop());
447    thrd->setPendingStop(false);
448
449    thrd->setInternalState(int_thread::stopped);
450    if (thrd->hasPendingUserStop()) {
451       thrd->setUserState(int_thread::stopped);
452       thrd->setPendingUserStop(false);
453    }
454
455    return true;
456 }
457
458 HandlePostFork::HandlePostFork() :
459    Handler("Post Fork")
460 {
461 }
462
463 HandlePostFork::~HandlePostFork()
464 {
465 }
466
467 void HandlePostFork::getEventTypesHandled(std::vector<EventType> &etypes)
468 {
469    etypes.push_back(EventType(EventType::Post, EventType::Fork));
470 }
471
472 bool HandlePostFork::handleEvent(Event::ptr ev)
473 {
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);
479
480    int_process *child_proc = int_process::createProcess(child_pid, parent_proc);
481    assert(child_proc);
482    return child_proc->forked();
483 }
484
485 HandlePostExec::HandlePostExec() :
486    Handler("Post Exec")
487 {
488 }
489
490 HandlePostExec::~HandlePostExec()
491 {
492 }
493
494 void HandlePostExec::getEventTypesHandled(std::vector<EventType> &etypes)
495 {
496    etypes.push_back(EventType(EventType::Post, EventType::Exec));
497 }
498
499 bool HandlePostExec::handleEvent(Event::ptr ev)
500 {
501    EventExec *eexec = static_cast<EventExec *>(ev.get());
502    int_process *proc = ev->getProcess()->llproc();
503    pthrd_printf("Handling exec for process %d\n",
504                 proc->getPid());
505
506    bool result = proc->execed();
507    if (!result) 
508       return false;
509    
510    eexec->setExecPath(proc->getExecutable());
511    eexec->setThread(proc->threadPool()->initialThread()->thread());
512    return true;
513 }
514
515 HandleSingleStep::HandleSingleStep() :
516    Handler("Single Step")
517 {
518 }
519
520 HandleSingleStep::~HandleSingleStep()
521 {
522 }
523
524 void HandleSingleStep::getEventTypesHandled(vector<EventType> &etypes)
525 {
526    etypes.push_back(EventType(EventType::None, EventType::SingleStep));
527 }
528
529 bool HandleSingleStep::handleEvent(Event::ptr ev)
530 {
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);
536    return true;
537 }
538
539 HandleBreakpoint::HandleBreakpoint() :
540    Handler("Breakpoint")
541 {
542 }
543
544 HandleBreakpoint::~HandleBreakpoint()
545 {
546 }
547
548 void HandleBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
549 {
550    etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
551 }
552
553 bool HandleBreakpoint::handleEvent(Event::ptr ev)
554 {
555    pthrd_printf("Handling breakpoint\n");
556    int_process *proc = ev->getProcess()->llproc();
557
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();
562
563    if (has_user_breakpoints) 
564    {
565       int_threadPool *pool = proc->threadPool();
566       for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
567          (*i)->setUserState(int_thread::stopped);
568       }
569    }
570
571    return true;
572 }
573
574 HandlePostBreakpoint::HandlePostBreakpoint() :
575    Handler("Post Breakpoint")
576 {
577 }
578
579 HandlePostBreakpoint::~HandlePostBreakpoint()
580 {
581 }
582
583 void HandlePostBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
584 {
585    etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
586 }
587
588 bool HandlePostBreakpoint::handleEvent(Event::ptr ev)
589 {
590    int_process *proc = ev->getProcess()->llproc();
591    int_thread *thrd = ev->getThread()->llthrd();
592
593    /**
594     * TODO: Ctrl transfer breakpoints
595     **/
596
597    /**
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
600     **/
601    pthrd_printf("Marking all threads in %d stopped for internal breakpoint handling\n",
602                 proc->getPid());
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);
607       }
608    }
609
610    EventBreakpoint *evbp = static_cast<EventBreakpoint *>(ev.get());
611    installed_breakpoint *bp = evbp->installedbp();
612
613    pthrd_printf("Setting breakpoint thread to single step mode\n");
614    thrd->setSingleStepMode(true);
615    thrd->markClearingBreakpoint(bp);
616
617    pthrd_printf("Removing breakpoint from memory\n");
618    bool result = bp->suspend(proc);
619    assert(result);
620
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());
624    assert(result);
625
626    thrd->setInternalState(int_thread::running);
627
628    return true;
629 }
630
631 HandleBreakpointClear::HandleBreakpointClear() :
632    Handler("Breakpoint Clear")
633 {
634 }
635
636 HandleBreakpointClear::~HandleBreakpointClear()
637 {
638 }
639
640 void HandleBreakpointClear::getEventTypesHandled(vector<EventType> &etypes)
641 {
642    etypes.push_back(EventType(EventType::None, EventType::BreakpointClear));
643 }
644
645 bool HandleBreakpointClear::handleEvent(Event::ptr ev)
646 {
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();
651
652    pthrd_printf("Resuming breakpoint at %lx\n", bp->getAddr());
653    bp->resume(proc);
654   
655    pthrd_printf("Restoring process state\n");
656    thrd->setSingleStepMode(false);
657    thrd->markClearingBreakpoint(NULL);
658    thrd->setInternalState(int_thread::stopped);
659   
660    proc->threadPool()->restoreInternalState(false);
661
662    return true;
663 }
664
665 int HandlePostBreakpoint::getPriority() const
666 {
667    return Handler::PostCallbackPriority;
668 }
669
670 HandleLibrary::HandleLibrary() :
671    Handler("SysV Library Handler")
672 {
673 }
674
675 HandleLibrary::~HandleLibrary()
676 {
677 }
678
679 bool HandleLibrary::handleEvent(Event::ptr ev)
680 {
681    pthrd_printf("Handling library load/unload\n");
682    EventLibrary *lev = static_cast<EventLibrary *>(ev.get());
683
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);
687    if (!result) {
688       pthrd_printf("Failed to refresh library list\n");
689       return false;
690    }
691    if (ll_added.empty() && ll_rmd.empty()) {
692       pthrd_printf("Could not find actual changes in lib state\n");
693       return true;
694    }
695
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());
699    }
700    for (set<int_library*>::iterator i = ll_rmd.begin(); i != ll_rmd.end(); i++) {
701       rmd.insert((*i)->getUpPtr());
702    }
703    lev->setLibs(added, rmd);
704    return true;
705 }
706
707 void HandleLibrary::getEventTypesHandled(std::vector<EventType> &etypes)
708 {
709    etypes.push_back(EventType(EventType::None, EventType::Library));
710 }
711
712 HandleCallbacks::HandleCallbacks() : 
713    Handler("Callback")
714 {
715 }
716
717 HandleCallbacks::~HandleCallbacks()
718 {
719 }
720
721 HandleCallbacks *HandleCallbacks::getCB()
722 {
723    static HandleCallbacks *cb = NULL;
724    if (!cb) {
725       cb = new HandleCallbacks();
726       assert(cb);
727    }
728    return cb;
729 }
730
731 int HandleCallbacks::getPriority() const
732 {
733    return CallbackPriority;
734 }
735
736 void HandleCallbacks::getEventTypesHandled(std::vector<EventType> & /*etypes*/)
737 {
738    //Callbacks are special cased, they respond to all event types.
739 }
740
741 bool HandleCallbacks::hasCBs(Event::const_ptr ev)
742 {
743    return cbfuncs.find(ev->getEventType()) != cbfuncs.end();
744 }
745
746 bool HandleCallbacks::requiresCB(Event::const_ptr ev)
747 {
748    return hasCBs(ev) && !ev->suppressCB();
749 }
750
751 bool HandleCallbacks::handleEvent(Event::ptr ev)
752 {
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());
757       return true;
758    }
759    int_process *proc = ev->getProcess()->llproc();
760    if (proc &&
761        (proc->getState() == int_process::neonatal ||
762         proc->getState() == int_process::neonatal_intermediate))
763    {
764       pthrd_printf("No callback for neonatal process %d\n", proc->getPid());
765       return true;
766    }
767    const std::set<Process::cb_func_t> &cbs = i->second;
768
769    return deliverCallback(ev, cbs);
770 }
771
772 static const char *action_str(Process::cb_action_t action)
773 {
774    switch (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:
782          return "cbProcStop";
783       case Process::cbDefault:
784          return "cbDefault";
785       default:
786          assert(0);
787    }
788
789    return NULL;
790 }
791
792 bool HandleCallbacks::handleCBReturn(Process::const_ptr proc, Thread::const_ptr thrd, 
793                                      Process::cb_action_t ret)
794 {
795    switch (ret) {
796       case Process::cbThreadContinue:
797          if (thrd == Thread::const_ptr()) {
798             perr_printf("User returned invalid action %s for event\n", 
799                         action_str(ret));
800             return false;
801          }
802          pthrd_printf("Callbacks returned thread continue\n");
803          thrd->llthrd()->setUserState(int_thread::running);
804          thrd->llthrd()->setInternalState(int_thread::running);
805          break;
806       case Process::cbThreadStop:
807          if (thrd == Thread::const_ptr()) {
808             perr_printf("User returned invalid action %s for event\n", 
809                         action_str(ret));
810             return false;
811          }
812          pthrd_printf("Callbacks returned thread stop\n");
813          thrd->llthrd()->setUserState(int_thread::stopped);
814          thrd->llthrd()->setInternalState(int_thread::stopped);
815          break;
816       case Process::cbProcContinue: {
817          if (proc == Process::const_ptr()) {
818             perr_printf("User returned invalid action %s for event\n", 
819                         action_str(ret));
820             return false;
821          }
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);
827          }
828          break;
829       }
830       case Process::cbProcStop: {
831          if (proc == Process::const_ptr()) {
832             perr_printf("User returned invalid action %s for event\n", 
833                         action_str(ret));
834             return false;
835          }
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);
841          }
842          break;
843       }
844       case Process::cbDefault:
845          pthrd_printf("Callbacks returned default\n");
846          break;
847    }
848    return true;
849 }
850
851 bool HandleCallbacks::deliverCallback(Event::ptr ev, const set<Process::cb_func_t> &cbset)
852 {
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()) 
857       {
858          notify()->clearEvent();
859       }
860       return true;
861    }
862
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));
866    unsigned k = 0;
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);
876
877       if (ret.parent != Process::cbDefault)
878          parent_result = ret.parent;
879       if (ret.child != Process::cbDefault)
880          child_result = ret.child;
881
882       pthrd_printf("Callback #%u return %s/%s\n", k, action_str(ret.parent),
883                    action_str(ret.child));
884    }
885
886    //Given the callback return result, change the user state to the appropriate
887    // setting.
888    pthrd_printf("Handling return value for main process\n");
889    handleCBReturn(ev->getProcess(), ev->getThread(), parent_result);
890
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();
899          break;
900       case EventType::ThreadCreate:
901          event_has_child = true;
902          child_thread = static_cast<EventNewThread *>(ev.get())->getNewThread();
903          break;
904    }
905    if (event_has_child)
906       handleCBReturn(child_proc, child_thread, child_result);
907
908    if (mt()->getThreadMode() == Process::HandlerThreading && 
909        notify()->hasEvents())
910    {
911       notify()->clearEvent();
912    }
913
914    return true;
915 }
916
917 bool HandleCallbacks::registerCallback_int(EventType ev, Process::cb_func_t func)
918 {
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());
923       return false;
924    }
925    cbfuncs[ev].insert(func);
926    return true;
927 }
928
929 bool HandleCallbacks::registerCallback(EventType ev, Process::cb_func_t func)
930 {
931    switch (ev.time()) {
932       case EventType::Pre:
933       case EventType::Post:
934       case EventType::None: {
935          bool result = registerCallback_int(ev, func);
936          if (!result) {
937             pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
938             setLastError(err_noevents, "EventType does not exist");
939             return false;
940          }
941          break;
942       }
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");
950             return false;
951          }
952          break;
953       }
954    }
955    return true;
956 }
957
958 bool HandleCallbacks::removeCallback_int(EventType et, Process::cb_func_t func)
959 {
960    cbfuncs_t::iterator i = cbfuncs.find(et);
961    if (i == cbfuncs.end()) {
962       return false;
963    }
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()) {
967       return false;
968    }
969    func_set.erase(j);
970    return true;
971 }
972
973 bool HandleCallbacks::removeCallback(EventType et, Process::cb_func_t func)
974 {
975    bool result = false;
976    switch (et.time()) {
977       case EventType::Pre:
978       case EventType::Post:
979       case EventType::None: {
980          result = removeCallback_int(et, func);
981       }
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);
987       }
988    }
989    if (!result) {
990       perr_printf("Attempted to remove non-existant callback %s\n", 
991                   et.name().c_str());
992       setLastError(err_badparam, "Callback does not exist");
993       return false;
994    }
995    return true;
996 }
997
998 bool HandleCallbacks::removeCallback_int(EventType et)
999 {
1000    cbfuncs_t::iterator i = cbfuncs.find(et);
1001    if (i == cbfuncs.end()) {
1002       return false;
1003    }
1004    cbfuncs.erase(i);
1005    return true;
1006 }
1007
1008 bool HandleCallbacks::removeCallback(EventType et)
1009 {
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);
1016       }
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);
1022       }
1023    }
1024    if (!result) {
1025       perr_printf("Attempted to remove non-existant callback %s\n", 
1026                   et.name().c_str());
1027       setLastError(err_badparam, "Callback does not exist");
1028       return false;
1029    }
1030    return true;
1031 }
1032
1033 bool HandleCallbacks::removeCallback(Process::cb_func_t func)
1034 {
1035    bool rmd_something = false;
1036    for (cbfuncs_t::iterator i = cbfuncs.begin(); i != cbfuncs.end(); i++)
1037    {
1038       EventType et = i->first;
1039       bool result = removeCallback_int(et, func);
1040       if (result) 
1041          rmd_something = true;
1042    }
1043    if (!rmd_something) {
1044       perr_printf("Attempted to remove non-existant callback %p\n", func);
1045       setLastError(err_badparam, "Callback does not exist");
1046       return false;
1047    }
1048    return true;
1049 }
1050
1051 HandlerPool *createDefaultHandlerPool()
1052 {
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;
1070    if (!initialized) {
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();
1087       initialized = true;
1088    }
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);
1107    return hpool;
1108 }
1109