More changes to support multithreaded debuggees on 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    }else{
282       delete proc;
283    }
284
285    return true;
286 }
287
288 HandleCrash::HandleCrash() :
289    Handler("Crash")
290 {
291 }
292
293 HandleCrash::~HandleCrash()
294 {
295 }
296
297 void HandleCrash::getEventTypesHandled(std::vector<EventType> &etypes)
298 {
299    etypes.push_back(EventType(EventType::Post, EventType::Crash));
300 }
301
302 bool HandleCrash::handleEvent(Event::ptr ev)
303 {
304    int_process *proc = ev->getProcess()->llproc();
305    int_thread *thrd = ev->getThread()->llthrd();
306    assert(proc);
307    assert(thrd);
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());
312    
313    ProcPool()->condvar()->lock();
314
315    proc->setState(int_process::exited);
316    ProcPool()->rmProcess(proc);
317
318    ProcPool()->condvar()->signal();
319    ProcPool()->condvar()->unlock();
320
321    delete proc;
322
323    return true;
324 }
325
326 HandlePreExit::HandlePreExit() :
327    Handler("Pre Exit")
328 {
329 }
330
331 HandlePreExit::~HandlePreExit()
332 {
333 }
334
335 void HandlePreExit::getEventTypesHandled(std::vector<EventType> &etypes)
336 {
337    etypes.push_back(EventType(EventType::Pre, EventType::Exit));
338 }
339
340 bool HandlePreExit::handleEvent(Event::ptr ev)
341 {
342    pthrd_printf("Handling pre-exit for process %d on thread %d\n",
343                 ev->getProcess()->llproc()->getPid(), 
344                 ev->getThread()->llthrd()->getLWP());
345
346    return true;
347 }
348
349 HandleThreadCreate::HandleThreadCreate() :
350    Handler("Thread Create")
351 {
352 }
353
354 HandleThreadCreate::~HandleThreadCreate()
355 {
356 }
357
358 void HandleThreadCreate::getEventTypesHandled(std::vector<EventType> &etypes)
359 {
360    etypes.push_back(EventType(EventType::None, EventType::ThreadCreate));
361 }
362
363 bool HandleThreadCreate::handleEvent(Event::ptr ev)
364 {
365    int_process *proc = ev->getProcess()->llproc();
366    int_thread *thrd = ev->getThread()->llthrd();
367    EventNewThread *threadev = static_cast<EventNewThread *>(ev.get());
368
369    pthrd_printf("Handle thread create for %d/%d with new thread %d\n",
370                 proc->getPid(), thrd ? thrd->getLWP() : -1, threadev->getLWP());
371
372    ProcPool()->condvar()->lock();
373    
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());
381    
382    ProcPool()->condvar()->signal();
383    ProcPool()->condvar()->unlock();
384
385    return true;
386 }
387
388 HandleThreadDestroy::HandleThreadDestroy() :
389    Handler("Thread Destroy")
390 {
391 }
392
393 HandleThreadDestroy::~HandleThreadDestroy()
394 {
395 }
396
397 void HandleThreadDestroy::getEventTypesHandled(std::vector<EventType> &etypes)
398 {
399    etypes.push_back(EventType(EventType::Any, EventType::ThreadDestroy));
400 }
401
402 bool HandleThreadDestroy::handleEvent(Event::ptr ev)
403 {
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());
408       return true;
409    }
410
411    pthrd_printf("Handling post-thread destroy for %d\n", thrd->getLWP());
412    ProcPool()->condvar()->lock();
413
414    if( int_process::getThreadControlMode() == int_process::HybridLWPControl ) {
415       // Need to make sure that the thread actually finishes at this point
416       thrd->plat_resume();
417    }
418
419    thrd->setHandlerState(int_thread::exited);
420    thrd->setInternalState(int_thread::exited);
421    thrd->setUserState(int_thread::exited);
422    ProcPool()->rmThread(thrd);
423    proc->threadPool()->rmThread(thrd);
424
425    delete thrd;
426
427    ProcPool()->condvar()->signal();
428    ProcPool()->condvar()->unlock();
429    return true;
430 }
431
432 HandleThreadStop::HandleThreadStop() :
433    Handler(std::string("Thread Stop"))
434 {
435 }
436
437 HandleThreadStop::~HandleThreadStop()
438 {
439 }
440
441 void HandleThreadStop::getEventTypesHandled(std::vector<EventType> &etypes)
442 {
443    etypes.push_back(EventType(EventType::None, EventType::Stop));
444 }
445
446 bool HandleThreadStop::handleEvent(Event::ptr ev)
447 {
448    int_thread *thrd = ev->getThread()->llthrd();
449    int_process *proc = ev->getProcess()->llproc();
450    pthrd_printf("Handling thread stop for %d/%d\n", proc->getPid(), thrd->getLWP());
451
452    assert(thrd->hasPendingStop());
453    thrd->setPendingStop(false);
454
455    thrd->setInternalState(int_thread::stopped);
456    if (thrd->hasPendingUserStop()) {
457       thrd->setUserState(int_thread::stopped);
458       thrd->setPendingUserStop(false);
459    }
460
461    return true;
462 }
463
464 HandlePostFork::HandlePostFork() :
465    Handler("Post Fork")
466 {
467 }
468
469 HandlePostFork::~HandlePostFork()
470 {
471 }
472
473 void HandlePostFork::getEventTypesHandled(std::vector<EventType> &etypes)
474 {
475    etypes.push_back(EventType(EventType::Post, EventType::Fork));
476 }
477
478 bool HandlePostFork::handleEvent(Event::ptr ev)
479 {
480    EventFork *efork = static_cast<EventFork *>(ev.get());
481    Dyninst::PID child_pid = efork->getPID();
482    int_process *parent_proc = ev->getProcess()->llproc();
483    pthrd_printf("Handling fork for parent %d to child %d\n",
484                 parent_proc->getPid(), child_pid);
485
486    int_process *child_proc = int_process::createProcess(child_pid, parent_proc);
487    assert(child_proc);
488    return child_proc->forked();
489 }
490
491 HandlePostExec::HandlePostExec() :
492    Handler("Post Exec")
493 {
494 }
495
496 HandlePostExec::~HandlePostExec()
497 {
498 }
499
500 void HandlePostExec::getEventTypesHandled(std::vector<EventType> &etypes)
501 {
502    etypes.push_back(EventType(EventType::Post, EventType::Exec));
503 }
504
505 bool HandlePostExec::handleEvent(Event::ptr ev)
506 {
507    EventExec *eexec = static_cast<EventExec *>(ev.get());
508    int_process *proc = ev->getProcess()->llproc();
509    pthrd_printf("Handling exec for process %d\n",
510                 proc->getPid());
511
512    bool result = proc->execed();
513    if (!result) 
514       return false;
515    
516    eexec->setExecPath(proc->getExecutable());
517    eexec->setThread(proc->threadPool()->initialThread()->thread());
518    return true;
519 }
520
521 HandleSingleStep::HandleSingleStep() :
522    Handler("Single Step")
523 {
524 }
525
526 HandleSingleStep::~HandleSingleStep()
527 {
528 }
529
530 void HandleSingleStep::getEventTypesHandled(vector<EventType> &etypes)
531 {
532    etypes.push_back(EventType(EventType::None, EventType::SingleStep));
533 }
534
535 bool HandleSingleStep::handleEvent(Event::ptr ev)
536 {
537    pthrd_printf("Handling event single step on %d/%d\n", 
538                 ev->getProcess()->llproc()->getPid(),
539                 ev->getThread()->llthrd()->getLWP());
540    ev->getThread()->llthrd()->setUserState(int_thread::stopped);
541    ev->getThread()->llthrd()->setInternalState(int_thread::stopped);
542    return true;
543 }
544
545 HandleBreakpoint::HandleBreakpoint() :
546    Handler("Breakpoint")
547 {
548 }
549
550 HandleBreakpoint::~HandleBreakpoint()
551 {
552 }
553
554 void HandleBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
555 {
556    etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
557 }
558
559 bool HandleBreakpoint::handleEvent(Event::ptr ev)
560 {
561    pthrd_printf("Handling breakpoint\n");
562    int_process *proc = ev->getProcess()->llproc();
563
564    EventBreakpoint *ebp = static_cast<EventBreakpoint *>(ev.get());
565    std::vector<Breakpoint::ptr> hl_bps;
566    ebp->getBreakpoints(hl_bps);
567    bool has_user_breakpoints = !hl_bps.empty();
568
569    if (has_user_breakpoints) 
570    {
571       int_threadPool *pool = proc->threadPool();
572       for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
573          (*i)->setUserState(int_thread::stopped);
574       }
575    }
576
577    return true;
578 }
579
580 HandlePostBreakpoint::HandlePostBreakpoint() :
581    Handler("Post Breakpoint")
582 {
583 }
584
585 HandlePostBreakpoint::~HandlePostBreakpoint()
586 {
587 }
588
589 void HandlePostBreakpoint::getEventTypesHandled(vector<EventType> &etypes)
590 {
591    etypes.push_back(EventType(EventType::None, EventType::Breakpoint));
592 }
593
594 bool HandlePostBreakpoint::handleEvent(Event::ptr ev)
595 {
596    int_process *proc = ev->getProcess()->llproc();
597    int_thread *thrd = ev->getThread()->llthrd();
598
599    /**
600     * TODO: Ctrl transfer breakpoints
601     **/
602
603    /**
604     * Stop all other threads in the job while we remove the breakpoint, single step 
605     * through the instruction and then resume the other threads
606     **/
607    pthrd_printf("Marking all threads in %d stopped for internal breakpoint handling\n",
608                 proc->getPid());
609    int_threadPool *pool = proc->threadPool();
610    for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
611       if ((*i)->getInternalState() == int_thread::running) {
612          (*i)->setInternalState(int_thread::stopped);
613       }
614    }
615
616    EventBreakpoint *evbp = static_cast<EventBreakpoint *>(ev.get());
617    installed_breakpoint *bp = evbp->installedbp();
618
619    pthrd_printf("Setting breakpoint thread to single step mode\n");
620    thrd->setSingleStepMode(true);
621    thrd->markClearingBreakpoint(bp);
622
623    pthrd_printf("Removing breakpoint from memory\n");
624    bool result = bp->suspend(proc);
625    assert(result);
626
627    pthrd_printf("Restoring PC to original location location at %lx\n", bp->getAddr());
628    MachRegister pcreg = MachRegister::getPC(proc->getTargetArch());
629    result = thrd->setRegister(pcreg, (MachRegisterVal) bp->getAddr());
630    assert(result);
631
632    thrd->setInternalState(int_thread::running);
633
634    return true;
635 }
636
637 HandleBreakpointClear::HandleBreakpointClear() :
638    Handler("Breakpoint Clear")
639 {
640 }
641
642 HandleBreakpointClear::~HandleBreakpointClear()
643 {
644 }
645
646 void HandleBreakpointClear::getEventTypesHandled(vector<EventType> &etypes)
647 {
648    etypes.push_back(EventType(EventType::None, EventType::BreakpointClear));
649 }
650
651 bool HandleBreakpointClear::handleEvent(Event::ptr ev)
652 {
653    int_process *proc = ev->getProcess()->llproc();
654    int_thread *thrd = ev->getThread()->llthrd();
655    EventBreakpointClear *bpc = static_cast<EventBreakpointClear *>(ev.get());
656    installed_breakpoint *bp = bpc->bp();
657
658    pthrd_printf("Resuming breakpoint at %lx\n", bp->getAddr());
659    bp->resume(proc);
660   
661    pthrd_printf("Restoring process state\n");
662    thrd->setSingleStepMode(false);
663    thrd->markClearingBreakpoint(NULL);
664    thrd->setInternalState(int_thread::stopped);
665
666    // Make sure the thread that caused the event remains stopped
667    if(    int_process::getThreadControlMode() == int_process::HybridLWPControl 
668        && proc->threadPool()->size() > 1 ) 
669    {
670        thrd->plat_suspend();
671    }
672   
673    proc->threadPool()->restoreInternalState(false);
674
675    return true;
676 }
677
678 int HandlePostBreakpoint::getPriority() const
679 {
680    return Handler::PostCallbackPriority;
681 }
682
683 HandleLibrary::HandleLibrary() :
684    Handler("SysV Library Handler")
685 {
686 }
687
688 HandleLibrary::~HandleLibrary()
689 {
690 }
691
692 bool HandleLibrary::handleEvent(Event::ptr ev)
693 {
694    pthrd_printf("Handling library load/unload\n");
695    EventLibrary *lev = static_cast<EventLibrary *>(ev.get());
696
697    int_process *proc = ev->getProcess()->llproc();
698    set<int_library *> ll_added, ll_rmd;
699    bool result = proc->refresh_libraries(ll_added, ll_rmd);
700    if (!result) {
701       pthrd_printf("Failed to refresh library list\n");
702       return false;
703    }
704    if (ll_added.empty() && ll_rmd.empty()) {
705       pthrd_printf("Could not find actual changes in lib state\n");
706       return true;
707    }
708
709    set<Library::ptr> added, rmd;
710    for (set<int_library*>::iterator i = ll_added.begin(); i != ll_added.end(); i++) {
711       added.insert((*i)->getUpPtr());
712    }
713    for (set<int_library*>::iterator i = ll_rmd.begin(); i != ll_rmd.end(); i++) {
714       rmd.insert((*i)->getUpPtr());
715    }
716    lev->setLibs(added, rmd);
717    return true;
718 }
719
720 void HandleLibrary::getEventTypesHandled(std::vector<EventType> &etypes)
721 {
722    etypes.push_back(EventType(EventType::None, EventType::Library));
723 }
724
725 HandleCallbacks::HandleCallbacks() : 
726    Handler("Callback")
727 {
728 }
729
730 HandleCallbacks::~HandleCallbacks()
731 {
732 }
733
734 HandleCallbacks *HandleCallbacks::getCB()
735 {
736    static HandleCallbacks *cb = NULL;
737    if (!cb) {
738       cb = new HandleCallbacks();
739       assert(cb);
740    }
741    return cb;
742 }
743
744 int HandleCallbacks::getPriority() const
745 {
746    return CallbackPriority;
747 }
748
749 void HandleCallbacks::getEventTypesHandled(std::vector<EventType> & /*etypes*/)
750 {
751    //Callbacks are special cased, they respond to all event types.
752 }
753
754 bool HandleCallbacks::hasCBs(Event::const_ptr ev)
755 {
756    return cbfuncs.find(ev->getEventType()) != cbfuncs.end();
757 }
758
759 bool HandleCallbacks::requiresCB(Event::const_ptr ev)
760 {
761    return hasCBs(ev) && !ev->suppressCB();
762 }
763
764 bool HandleCallbacks::handleEvent(Event::ptr ev)
765 {
766    EventType evtype = ev->getEventType();
767    std::map<EventType, std::set<Process::cb_func_t>, eventtype_cmp>::iterator i = cbfuncs.find(evtype);
768    if (i == cbfuncs.end()) {
769       pthrd_printf("No callback registered for event type '%s'\n", ev->name().c_str());
770       return true;
771    }
772    int_process *proc = ev->getProcess()->llproc();
773    if (proc &&
774        (proc->getState() == int_process::neonatal ||
775         proc->getState() == int_process::neonatal_intermediate))
776    {
777       pthrd_printf("No callback for neonatal process %d\n", proc->getPid());
778       return true;
779    }
780    const std::set<Process::cb_func_t> &cbs = i->second;
781
782    return deliverCallback(ev, cbs);
783 }
784
785 static const char *action_str(Process::cb_action_t action)
786 {
787    switch (action) {
788       case Process::cbThreadContinue:
789          return "cbThreadContinue";
790       case Process::cbThreadStop:
791          return "cbThreadStop";
792       case Process::cbProcContinue:
793          return "cbProcContinue";
794       case Process::cbProcStop:
795          return "cbProcStop";
796       case Process::cbDefault:
797          return "cbDefault";
798       default:
799          assert(0);
800    }
801
802    return NULL;
803 }
804
805 bool HandleCallbacks::handleCBReturn(Process::const_ptr proc, Thread::const_ptr thrd, 
806                                      Process::cb_action_t ret)
807 {
808    switch (ret) {
809       case Process::cbThreadContinue:
810          if (thrd == Thread::const_ptr()) {
811             perr_printf("User returned invalid action %s for event\n", 
812                         action_str(ret));
813             return false;
814          }
815          pthrd_printf("Callbacks returned thread continue\n");
816          thrd->llthrd()->setUserState(int_thread::running);
817          thrd->llthrd()->setInternalState(int_thread::running);
818          break;
819       case Process::cbThreadStop:
820          if (thrd == Thread::const_ptr()) {
821             perr_printf("User returned invalid action %s for event\n", 
822                         action_str(ret));
823             return false;
824          }
825          pthrd_printf("Callbacks returned thread stop\n");
826          thrd->llthrd()->setUserState(int_thread::stopped);
827          thrd->llthrd()->setInternalState(int_thread::stopped);
828          break;
829       case Process::cbProcContinue: {
830          if (proc == Process::const_ptr()) {
831             perr_printf("User returned invalid action %s for event\n", 
832                         action_str(ret));
833             return false;
834          }
835          pthrd_printf("Callbacks returned process continue\n");
836          int_threadPool *tp = proc->llproc()->threadPool();
837          for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
838             (*j)->setUserState(int_thread::running);
839             (*j)->setInternalState(int_thread::running);
840          }
841          break;
842       }
843       case Process::cbProcStop: {
844          if (proc == Process::const_ptr()) {
845             perr_printf("User returned invalid action %s for event\n", 
846                         action_str(ret));
847             return false;
848          }
849          pthrd_printf("Callbacks returned process stop\n");
850          int_threadPool *tp = proc->llproc()->threadPool();
851          for (int_threadPool::iterator j = tp->begin(); j != tp->end(); j++) {
852             (*j)->setUserState(int_thread::stopped);
853             (*j)->setInternalState(int_thread::stopped);
854          }
855          break;
856       }
857       case Process::cbDefault:
858          pthrd_printf("Callbacks returned default\n");
859          break;
860    }
861    return true;
862 }
863
864 bool HandleCallbacks::deliverCallback(Event::ptr ev, const set<Process::cb_func_t> &cbset)
865 {
866    if (ev->suppressCB()) {
867       pthrd_printf("Suppressing callbacks for event %s\n", ev->name().c_str());
868       if (mt()->getThreadMode() == Process::HandlerThreading && 
869           notify()->hasEvents()) 
870       {
871          notify()->clearEvent();
872       }
873       return true;
874    }
875
876    //The following code loops over each callback registered for this event type
877    // and triggers the callback for the user.  Return results are aggregated.
878    assert(!(isHandlerThread() && mt()->getThreadMode() != Process::CallbackThreading));
879    unsigned k = 0;
880    pthrd_printf("Triggering callback for event '%s'\n", ev->name().c_str());
881    Process::cb_action_t parent_result = Process::cbDefault;
882    Process::cb_action_t child_result = Process::cbDefault;
883    std::set<Process::cb_func_t>::iterator j;
884    for (j = cbset.begin(); j != cbset.end(); j++, k++) {
885       pthrd_printf("Triggering callback #%u for event '%s'\n", k, ev->name().c_str());
886       int_process::setInCB(true);
887       Process::cb_ret_t ret = (*j)(ev);
888       int_process::setInCB(false);
889
890       if (ret.parent != Process::cbDefault)
891          parent_result = ret.parent;
892       if (ret.child != Process::cbDefault)
893          child_result = ret.child;
894
895       pthrd_printf("Callback #%u return %s/%s\n", k, action_str(ret.parent),
896                    action_str(ret.child));
897    }
898
899    //Given the callback return result, change the user state to the appropriate
900    // setting.
901    pthrd_printf("Handling return value for main process\n");
902    handleCBReturn(ev->getProcess(), ev->getThread(), parent_result);
903
904    pthrd_printf("Handling return value for child process/thread\n");
905    Process::const_ptr child_proc = Process::const_ptr();
906    Thread::const_ptr child_thread = Thread::const_ptr();
907    bool event_has_child = false;
908    switch (ev->getEventType().code()) {
909       case EventType::Fork:
910          event_has_child = true;
911          child_proc = static_cast<EventFork *>(ev.get())->getChildProcess();
912          break;
913       case EventType::ThreadCreate:
914          event_has_child = true;
915          child_thread = static_cast<EventNewThread *>(ev.get())->getNewThread();
916          break;
917    }
918    if (event_has_child)
919       handleCBReturn(child_proc, child_thread, child_result);
920
921    if (mt()->getThreadMode() == Process::HandlerThreading && 
922        notify()->hasEvents())
923    {
924       notify()->clearEvent();
925    }
926
927    return true;
928 }
929
930 bool HandleCallbacks::registerCallback_int(EventType ev, Process::cb_func_t func)
931 {
932    pthrd_printf("Registering event %s with callback function %p\n", ev.name().c_str(), func);
933    std::set<EventType>::iterator i = alleventtypes.find(ev);
934    if (i == alleventtypes.end()) {
935       pthrd_printf("Event %s does not have any handler\n", ev.name().c_str());
936       return false;
937    }
938    cbfuncs[ev].insert(func);
939    return true;
940 }
941
942 bool HandleCallbacks::registerCallback(EventType ev, Process::cb_func_t func)
943 {
944    switch (ev.time()) {
945       case EventType::Pre:
946       case EventType::Post:
947       case EventType::None: {
948          bool result = registerCallback_int(ev, func);
949          if (!result) {
950             pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
951             setLastError(err_noevents, "EventType does not exist");
952             return false;
953          }
954          break;
955       }
956       case EventType::Any: {
957          bool result1 = registerCallback_int(EventType(EventType::Pre, ev.code()), func);
958          bool result2 = registerCallback_int(EventType(EventType::Post, ev.code()), func);
959          bool result3 = registerCallback_int(EventType(EventType::None, ev.code()), func);
960          if (!result1 && !result2 && !result3) {
961             pthrd_printf("Did not register any callbacks for %s\n", ev.name().c_str());
962             setLastError(err_noevents, "EventType does not exist");
963             return false;
964          }
965          break;
966       }
967    }
968    return true;
969 }
970
971 bool HandleCallbacks::removeCallback_int(EventType et, Process::cb_func_t func)
972 {
973    cbfuncs_t::iterator i = cbfuncs.find(et);
974    if (i == cbfuncs.end()) {
975       return false;
976    }
977    set<Process::cb_func_t> &func_set = i->second;
978    set<Process::cb_func_t>::iterator j = func_set.find(func);
979    if (j == func_set.end()) {
980       return false;
981    }
982    func_set.erase(j);
983    return true;
984 }
985
986 bool HandleCallbacks::removeCallback(EventType et, Process::cb_func_t func)
987 {
988    bool result = false;
989    switch (et.time()) {
990       case EventType::Pre:
991       case EventType::Post:
992       case EventType::None: {
993          result = removeCallback_int(et, func);
994       }
995       case EventType::Any: {
996          bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()), func);
997          bool result2 = removeCallback_int(EventType(EventType::Post,et.code()), func);
998          bool result3 = removeCallback_int(EventType(EventType::None,et.code()), func);
999          result = (result1 || result2 || result3);
1000       }
1001    }
1002    if (!result) {
1003       perr_printf("Attempted to remove non-existant callback %s\n", 
1004                   et.name().c_str());
1005       setLastError(err_badparam, "Callback does not exist");
1006       return false;
1007    }
1008    return true;
1009 }
1010
1011 bool HandleCallbacks::removeCallback_int(EventType et)
1012 {
1013    cbfuncs_t::iterator i = cbfuncs.find(et);
1014    if (i == cbfuncs.end()) {
1015       return false;
1016    }
1017    cbfuncs.erase(i);
1018    return true;
1019 }
1020
1021 bool HandleCallbacks::removeCallback(EventType et)
1022 {
1023    bool result = false;
1024    switch (et.time()) {
1025       case EventType::Pre:
1026       case EventType::Post:
1027       case EventType::None: {
1028          result = removeCallback_int(et);
1029       }
1030       case EventType::Any: {
1031          bool result1 = removeCallback_int(EventType(EventType::Pre, et.code()));
1032          bool result2 = removeCallback_int(EventType(EventType::Post,et.code()));
1033          bool result3 = removeCallback_int(EventType(EventType::None,et.code()));
1034          result = (result1 || result2 || result3);
1035       }
1036    }
1037    if (!result) {
1038       perr_printf("Attempted to remove non-existant callback %s\n", 
1039                   et.name().c_str());
1040       setLastError(err_badparam, "Callback does not exist");
1041       return false;
1042    }
1043    return true;
1044 }
1045
1046 bool HandleCallbacks::removeCallback(Process::cb_func_t func)
1047 {
1048    bool rmd_something = false;
1049    for (cbfuncs_t::iterator i = cbfuncs.begin(); i != cbfuncs.end(); i++)
1050    {
1051       EventType et = i->first;
1052       bool result = removeCallback_int(et, func);
1053       if (result) 
1054          rmd_something = true;
1055    }
1056    if (!rmd_something) {
1057       perr_printf("Attempted to remove non-existant callback %p\n", func);
1058       setLastError(err_badparam, "Callback does not exist");
1059       return false;
1060    }
1061    return true;
1062 }
1063
1064 HandlerPool *createDefaultHandlerPool()
1065 {
1066    static bool initialized = false;
1067    static HandleBootstrap *hbootstrap = NULL;
1068    static HandleSignal *hsignal = NULL;
1069    static HandlePostExit *hpostexit = NULL;
1070    static HandlePreExit *hpreexit = NULL;
1071    static HandleThreadCreate *hthreadcreate = NULL;
1072    static HandleThreadDestroy *hthreaddestroy = NULL;
1073    static HandleThreadStop *hthreadstop = NULL;
1074    static HandleSingleStep *hsinglestep = NULL;
1075    static HandleCrash *hcrash = NULL;
1076    static HandleBreakpoint *hbpoint = NULL;
1077    static HandlePostBreakpoint *hpost_bpoint = NULL;
1078    static HandleBreakpointClear *hbpclear = NULL;
1079    static HandleLibrary *hlibrary = NULL;
1080    static HandlePostFork *hpostfork = NULL;
1081    static HandlePostExec *hpostexec = NULL;
1082    static iRPCHandler *hrpc = NULL;
1083    if (!initialized) {
1084       hbootstrap = new HandleBootstrap();
1085       hsignal = new HandleSignal();
1086       hpostexit = new HandlePostExit();
1087       hpreexit = new HandlePreExit();
1088       hthreadcreate = new HandleThreadCreate();
1089       hthreaddestroy = new HandleThreadDestroy();
1090       hthreadstop = new HandleThreadStop();
1091       hsinglestep = new HandleSingleStep();
1092       hcrash = new HandleCrash();
1093       hbpoint = new HandleBreakpoint();
1094       hpost_bpoint = new HandlePostBreakpoint();
1095       hbpclear = new HandleBreakpointClear();
1096       hrpc = new iRPCHandler();
1097       hlibrary = new HandleLibrary();
1098       hpostfork = new HandlePostFork();
1099       hpostexec = new HandlePostExec();
1100       initialized = true;
1101    }
1102    HandlerPool *hpool = new HandlerPool();
1103    hpool->addHandler(hbootstrap);
1104    hpool->addHandler(hsignal);
1105    hpool->addHandler(hpostexit);
1106    hpool->addHandler(hpreexit);
1107    hpool->addHandler(hthreadcreate);
1108    hpool->addHandler(hthreaddestroy);
1109    hpool->addHandler(hthreadstop);
1110    hpool->addHandler(hsinglestep);
1111    hpool->addHandler(hcrash);
1112    hpool->addHandler(hbpoint);
1113    hpool->addHandler(hpost_bpoint);
1114    hpool->addHandler(hbpclear);
1115    hpool->addHandler(hrpc);
1116    hpool->addHandler(hlibrary);
1117    hpool->addHandler(hpostfork);
1118    hpool->addHandler(hpostexec);
1119    plat_createDefaultHandlerPool(hpool);
1120    return hpool;
1121 }
1122