Problem 1:
[dyninst.git] / dyninstAPI / src / signalhandler.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: signalhandler.C,v 
43
44 #include "process.h"
45 #include "dyn_lwp.h"
46 #include "dyn_thread.h"
47 #include "callbacks.h"
48 #include "function.h"
49 #include "stats.h"
50 #include "signalhandler.h"
51 #include "Object.h"
52 #include "mapped_object.h"
53 //  signal_generator_counter is used to generate identifier strings
54 //  for signal generator threads.  eg SYNC1, SYNC2, SYNC3
55
56 unsigned signal_generator_counter = 0;
57 eventLock SignalGeneratorCommon::global_wait_list_lock;
58 pdvector<EventGate *> SignalGeneratorCommon::global_wait_list;
59
60 EventGate::EventGate(eventLock *l, eventType t, process *p, dyn_lwp *lwp,
61                      eventStatusCode_t status) :
62      lock(l), waiting(false)
63 {
64   //cond = new eventCond(lock);
65   EventRecord target_event;
66   target_event.type = t;
67   target_event.proc = p;
68   target_event.lwp = lwp;
69   target_event.status = status;
70   evts.push_back(target_event);
71
72   if (t != evtProcessExit) {
73     EventRecord process_exit_event;
74     process_exit_event.type = evtProcessExit;
75     process_exit_event.proc = p;
76     evts.push_back(process_exit_event);
77   }
78 }
79
80 bool EventGate::addEvent(eventType type, process *p)
81 {
82   EventRecord target_event;
83   target_event.type = type;
84   target_event.proc = p;
85   if (type == evtProcessExit) {
86     for (unsigned int i = 0; i < evts.size(); ++i) {
87       if (evts[i].isTemplateOf(target_event)) {
88         //fprintf(stderr, "%s[%d]:  dropping duplicate request to wait for proces exit\n",
89          //       FILE__, __LINE__);
90         return true;
91       }
92     }
93   }
94   evts.push_back(target_event);
95   return true;
96 }
97
98 EventGate::~EventGate()
99 {
100   //delete cond;
101 }
102
103 EventRecord &EventGate::wait()
104 {
105   trigger.type = evtUndefined;
106   assert(lock->depth());
107  
108   still_waiting:
109   waiting = true;
110   getMailbox()->executeCallbacks(FILE__, __LINE__);
111
112   if (trigger.type != evtUndefined) {
113     return trigger;
114   }
115   extern int dyn_debug_signal;
116   if (dyn_debug_signal) {
117     signal_printf("%s[%d][%s]: waiting for event matching:\n", FILE__, __LINE__,
118             getThreadStr(getExecThreadID()));
119     for (unsigned int i = 0; i < evts.size(); ++i) {
120       char buf[1024];
121       signal_printf("\t%s\n", evts[i].sprint_event(buf));
122     }
123   }
124
125   lock->_WaitForSignal(FILE__, __LINE__);
126   waiting = false;
127   
128
129   bool triggered = false;
130   for (unsigned int i = 0; i < evts.size(); ++i) {
131     if (evts[i].isTemplateOf(trigger)) {
132       triggered = true;
133       break;
134     }
135   }
136   if (!triggered) goto still_waiting;
137
138   return trigger;
139 }
140
141 bool EventGate::signalIfMatch(EventRecord &ev)
142 {
143   lock->_Lock(FILE__, __LINE__);
144   if (!waiting) {
145     lock->_Unlock(FILE__, __LINE__);
146     return false;
147   }
148   bool ret = false;
149   for (unsigned int i = 0; i < evts.size(); ++i) {
150     if (evts[i].isTemplateOf(ev)) {
151       ret = true;
152       trigger = ev;
153       lock->_Broadcast(FILE__, __LINE__);
154       break;
155     }
156   }
157   lock->_Unlock(FILE__, __LINE__);
158   return ret;
159 }
160
161 SignalHandler *SignalGenerator::newSignalHandler(char *name, int id)
162 {
163   SignalHandler *sh;
164   sh  = new SignalHandler(name, id, this);
165   return (SignalHandler *)sh;
166 }
167
168 pdstring SignalGeneratorCommon::createExecPath(pdstring &file, pdstring &dir)
169 {
170   pdstring ret = file;
171 #if defined (os_windows)
172   if (dir.length() > 0) {
173       if ( (file.length() < 2)      // file is too short to be a drive specifier
174          || !isalpha( file[0] )     // first character in file is not a letter
175          || (file[1] != ':') )      // second character in file is not a colon
176             ret = dir + "\\" + file;
177   }
178 #else
179   if (dir.length() > 0) {
180      if (!file.prefixed_by("/") ) {
181          // file does not start  with a '/', so it is a relative pathname
182          // we modify it to prepend the given directory
183          if (dir.suffixed_by("/") ) {
184              // the dir already has a trailing '/', so we can
185              // just concatenate them to get an absolute path
186              ret =  dir + file;
187           }
188           else {
189              // the dir does not have a trailing '/', so we must
190              // add a '/' to get the absolute path
191              ret =  dir + "/" + file;
192           }
193       }
194       else {
195          // file starts with a '/', so it is an absolute pathname
196          // DO NOT prepend the directory, regardless of what the
197          // directory variable holds.
198          // nothing to do in this case
199       }
200
201   }
202 #endif
203   return ret;
204 }
205 SignalGenerator *SignalGeneratorCommon::newSignalGenerator(pdstring file, pdstring dir,
206                                                          pdvector<pdstring> *argv,
207                                                          pdvector<pdstring> *envp,
208                                                          pdstring inputFile,
209                                                          pdstring outputFile,
210                                                          int stdin_fd, int stdout_fd,
211                                                          int stderr_fd)
212 {
213   char idstr[16];
214   sprintf(idstr, "SYNC%d", signal_generator_counter++);
215   return new SignalGenerator(idstr, 
216                              file, dir, 
217                              argv, envp, inputFile, outputFile,
218                              stdin_fd, stdout_fd, stderr_fd);
219 }
220
221 SignalGenerator *SignalGeneratorCommon::newSignalGenerator(pdstring file, int pid)
222 {
223   char idstr[16];
224   sprintf(idstr, "SYNC%d", signal_generator_counter++);
225   return new SignalGenerator(idstr, file, pid);
226 }
227
228 process *SignalGeneratorCommon::newProcess(pdstring file_, pdstring dir, 
229                                                      pdvector<pdstring> *argv,
230                                                      pdvector<pdstring> *envp,
231                                                      int stdin_fd, int stdout_fd, 
232                                                      int stderr_fd)
233 {
234    // Verify existence of exec file
235    pdstring file = createExecPath(file_, dir);
236    struct stat file_stat;
237    int stat_result;
238
239    stat_result = stat(file.c_str(), &file_stat);
240
241    if (stat_result == -1) {
242       startup_printf("%s[%d]:  failed to read file %s\n", __FILE__, __LINE__, file.c_str());
243       pdstring msg = pdstring("Can't read executable file ") + file + (": ") + strerror(errno);
244       showErrorCallback(68, msg.c_str());
245       return NULL;
246    }
247
248    // check for I/O redirection in arg list.
249    pdstring inputFile;
250    pdstring outputFile;
251 #if !defined(BPATCH_LIBRARY) || defined(BPATCH_REDIRECT_IO)
252    // TODO -- this assumes no more than 1 of each "<", ">"
253    for (unsigned i1=0; i1<argv->size(); i1++) {
254      if ((*argv)[i1] == "<") {
255        inputFile = (*argv)[i1+1];
256        for (unsigned j=i1+2, k=i1; j<argv->size(); j++, k++)
257          (*argv)[k] = (*argv)[j];
258        argv->resize(argv->size()-2);
259      }
260    }
261    for (unsigned i2=0; i2<argv->size(); i2++) {
262      if ((*argv)[i2] == ">") {
263        outputFile = (*argv)[i2+1];
264        for (unsigned j=i2+2, k=i2; j<argv->size(); j++, k++)
265          (*argv)[k] = (*argv)[j];
266        argv->resize(argv->size()-2);
267      }
268    }
269 #endif
270
271
272   SignalGenerator *sg = newSignalGenerator(file, dir, argv, envp, inputFile, outputFile,
273                                            stdin_fd, stdout_fd, stderr_fd);
274
275   if (!sg) {
276      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
277              FILE__, __LINE__, getThreadStr(getExecThreadID()));
278      getMailbox()->executeCallbacks(FILE__, __LINE__);
279      return NULL;
280   }
281
282
283   process *theProc = new process(sg);
284   assert(theProc);
285   sg->setProcess(theProc);
286   //  finally, create the signal handler thread -- this creates the process
287   //  from the event handling thread.  We want to do it there because on some platforms
288   //  (windows, linux-with-linuxThreads) the only thread that can properly listen for
289   //  debug events is the thread that spawned the process. 
290
291   if (!sg->createThread()) {
292      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
293              FILE__, __LINE__, getThreadStr(getExecThreadID()));
294      delete sg;
295      fprintf(stderr, "%s[%d]: WARN:  removed delete theProc\n", FILE__, __LINE__);
296      //delete theProc;
297      getMailbox()->executeCallbacks(FILE__, __LINE__);
298      return NULL;
299   }
300
301   assert(-1 != sg->getPid());
302
303   signal_printf("%s[%d]:  started signal listener for new process %d -- %s\n",
304           FILE__, __LINE__, sg->pid, file.c_str());
305
306   return theProc;
307 }
308
309 void SignalGeneratorCommon::stopSignalGenerator(SignalGenerator *sg)
310 {
311    
312   int dur = 0;
313   signal_printf("%s[%d]:  waiting for thread to terminate\n", FILE__, __LINE__);
314
315   sg->stopThreadNextIter();
316   sg->wakeUpThreadForShutDown();
317
318   while (sg->isRunning() && (dur < 5)) {
319     sg->__UNLOCK;
320     //  If we wait more than 5 iters here, something is defnitely wrong and
321     //  this should be reexamined.
322     if (dur++ > 5) {
323         fprintf(stderr, "%s[%d]:  sg still running\n", FILE__, __LINE__);
324     }
325     sleep(1);
326     
327     sg->__LOCK;
328   }
329
330   for (unsigned i = 0; i < sg->handlers.size(); i++) {
331       sg->deleteSignalHandler(sg->handlers[i]);
332   }
333
334   signal_printf("%s[%d]:  sg has stopped\n", FILE__, __LINE__);
335 }
336
337 void SignalGeneratorCommon::deleteSignalGenerator(SignalGenerator *sg)
338 {
339    
340   if (sg->isRunning())
341     stopSignalGenerator(sg);
342
343    delete (sg);
344 }
345
346 bool SignalGeneratorCommon::waitNextEvent(EventRecord &ev) 
347 {
348   __LOCK;
349   //  If we have events left over from the last call of this fn,
350   //  just return one.
351   if (events_to_handle.size()) {
352     //  if per-call ordering is important this should grab events from the front
353     //  of events_to_handle.  Guessing that (if possible) multiple events generated
354     //  "simultaneously" can be handled in any order, however.
355     ev = events_to_handle[events_to_handle.size() - 1];
356     events_to_handle.pop_back();
357     char buf[128];
358     signal_printf("%s[%d][%s]:  waitNextEvent: had existing event %s\n", FILE__, __LINE__,
359                 getThreadStr(getExecThreadID()), ev.sprint_event(buf));
360     __UNLOCK;
361     return true;
362   }
363
364   assert(proc);
365
366   
367   if (proc->status() == deleted || proc->status() == exited) {
368       fprintf(stderr, "%s[%d]:  getting ready to shut down event handling thread\n", FILE__, __LINE__);
369       stopThreadNextIter();
370       ev.type = evtShutDown;
371       ev.proc = proc;
372       __UNLOCK;
373       return true;
374   }
375   //  maybe query_for_running_lwp is sufficient here??
376   while (  proc->status() != running
377            && proc->status() != neonatal
378            && !proc->query_for_running_lwp()) {
379
380       signal_printf("%s[%d]:  waiting for process %d to become active, status: %s\n",
381                     FILE__, __LINE__, pid, proc->getStatusAsString().c_str());
382       waiting_for_active_process = true;
383       __WAIT_FOR_SIGNAL;
384   }
385   
386   if (stop_request) {
387       fprintf(stderr, "%s[%d]:  getting ready to shut down event handling thread 2\n", FILE__, __LINE__);
388       ev.type = evtShutDown;
389       ev.proc = proc;
390       __UNLOCK;
391       return true;
392   }
393   
394   waiting_for_active_process = false;
395   
396   ev.type = evtUndefined;
397   bool ret = waitNextEventLocked(ev);
398   
399   //  shut down events will not make it to the handler thread(s), since this thread will
400   //  terminate execution after leaving this function.
401
402   if (ev.type == evtShutDown)
403     signalEvent(ev);
404
405   __UNLOCK;
406   return ret;
407 }
408
409 process *SignalGeneratorCommon::newProcess(pdstring &progpath, int pid_)
410 {
411   SignalGenerator *sg = newSignalGenerator(progpath, pid_);
412
413   if (!sg) {
414      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
415              FILE__, __LINE__, getThreadStr(getExecThreadID()));
416      getMailbox()->executeCallbacks(FILE__, __LINE__);
417      return NULL;
418   }
419
420
421   process *theProc = new process(sg);
422   assert(theProc);
423   sg->setProcess(theProc);
424   //  finally, create the signal handler thread -- this creates the process
425   //  from the event handling thread.  We want to do it there because on some platforms
426   //  (windows, linux-with-linuxThreads) the only thread that can properly listen for
427   //  debug events is the thread that spawned the process. 
428
429   if (!sg->createThread()) {
430      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
431              FILE__, __LINE__, getThreadStr(getExecThreadID()));
432      delete sg;
433      getMailbox()->executeCallbacks(FILE__, __LINE__);
434      return NULL;
435   }
436
437   assert(-1 != sg->getPid());
438   signal_printf("%s[%d]:  started signal listener for new process %d -- %s\n",
439           FILE__, __LINE__, pid_, progpath.c_str());
440
441   
442
443   return theProc;
444 }
445
446 process * SignalGeneratorCommon::newProcess(process *parent, int pid_, int traceLink)
447 {
448   char *progpath = const_cast<char *>(parent->getAOut()->fullName().c_str());
449   assert(progpath);
450   SignalGenerator *sg = newSignalGenerator(progpath, pid_);
451
452   if (!sg) {
453      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
454              FILE__, __LINE__, getThreadStr(getExecThreadID()));
455      getMailbox()->executeCallbacks(FILE__, __LINE__);
456      return NULL;
457   }
458
459   process *theChild = new process(parent, sg, traceLink);
460   assert(theChild);
461   sg->setProcess(theChild);
462
463   if (!sg->createThread()) {
464      fprintf(stderr, "%s[%d]:  failed to create event handler thread for %s\n", 
465              FILE__, __LINE__, getThreadStr(getExecThreadID()));
466      delete sg;
467      getMailbox()->executeCallbacks(FILE__, __LINE__);
468      return NULL;
469   }
470
471   assert(-1 != sg->getPid());
472
473
474   return theChild;
475 }
476
477 SignalGeneratorCommon::SignalGeneratorCommon(char *idstr,pdstring file_, pdstring dir_,
478                                  pdvector<pdstring> *argv_,
479                                  pdvector<pdstring> *envp_,
480                                  pdstring inputFile_,
481                                  pdstring outputFile_,
482                                  int stdin_fd_, int stdout_fd_,
483                                  int stderr_fd_) :
484                  EventHandler<EventRecord>(BPatch_eventLock::getLock(),
485                                            idstr,/*start thread?*/ false),
486                  file(file_),
487                  dir(dir_),
488                  inputFile(inputFile_),
489                  outputFile(outputFile_),
490                  stdin_fd(stdin_fd_),
491                  stdout_fd(stdout_fd_),
492                  stderr_fd(stderr_fd_),
493                  argv(argv_),
494                  envp(envp_),
495                  pid(-1),
496                  traceLink(-1),
497                  waiting_for_event(false)
498 {
499   signal_printf("%s[%d]:  new SignalGenerator\n", FILE__, __LINE__);
500   assert(eventlock == global_mutex);
501 }
502
503 SignalGeneratorCommon::SignalGeneratorCommon(char *idstr, pdstring file_,
504                                  int pid_) :
505                  EventHandler<EventRecord>(BPatch_eventLock::getLock(),
506                                            idstr,/*start thread?*/ false),
507                  file(file_),
508                  pid(pid_),
509                  traceLink(-1),
510                  waiting_for_event(false)
511 {
512   signal_printf("%s[%d]:  new SignalGenerator\n", FILE__, __LINE__);
513   assert(eventlock == global_mutex);
514 }
515
516 bool SignalGeneratorCommon::wakeUpThreadForShutDown()
517 {
518 #if defined (os_windows)
519   int sig_to_send = 5;
520   fprintf(stderr, "%s[%d]:  FIGURE ME OUT FOR WINDOWS\n", FILE__, __LINE__);
521   if (waiting_for_active_process) {
522     signalEvent(evtShutDown);
523     __BROADCAST;
524     return true;
525   }
526 #else
527   int sig_to_send = SIGTRAP;
528    assert(global_mutex->depth());
529
530   if (waiting_for_event) {
531     fprintf(stderr, "%s[%d]:  sending SIGTRAP to wake up signal handler\n", FILE__, __LINE__);
532     P_kill (pid, sig_to_send);
533     waitForEvent(evtShutDown, proc);
534     fprintf(stderr, "%s[%d][%s]:  got shutdown event\n", FILE__, __LINE__, getThreadStr(getExecThreadID()));
535   }
536   else if (waiting_for_active_process) {
537     signalEvent(evtShutDown);
538     __BROADCAST;
539   }
540 #endif
541   return true;
542 }
543
544 SignalGeneratorCommon::~SignalGeneratorCommon() 
545 {
546   fprintf(stderr, "%s[%d]:  welcome to ~SignalGenerator\n", FILE__, __LINE__);
547   //killThread();
548
549   for (unsigned int i = 0; i < handlers.size(); ++i) {
550     signal_printf("%s[%d]:  destroying handler %s\n", FILE__, __LINE__, 
551                   handlers[i]->getName());
552     delete handlers[i];
553   }
554 }
555
556 void SignalGeneratorCommon::deleteSignalHandler(SignalHandler *sh)
557 {
558     EventRecord ev;
559     ev.type = evtShutDown;
560     sh->stopThreadNextIter();
561     sh->assignEvent(ev);
562     
563     while (sh->isRunning()) {
564         waitForEvent(evtAnyEvent);
565     }
566 }
567
568 bool SignalGeneratorCommon::initialize_event_handler()
569 {
570   assert(proc);
571
572   //  This is the init function for the event handler.  It is called before the main
573   //  event handing loop.  
574
575   //  In the case of the signal handler, here we call either forkNewProcess() or
576   //  attachProcess() if the process already exists.
577
578   if (pid == -1) {
579     if (!forkNewProcess()) {
580        fprintf(stderr, "%s[%d]:  failed to fork a new process for %s\n", FILE__, __LINE__,
581                file.c_str());
582        return false;
583     }
584
585     proc->createRepresentativeLWP();
586
587     if (!proc->setupCreated(traceLink)) {
588         delete proc;
589         proc = NULL;
590         return false;
591     }
592
593     int status;
594     fileDescriptor desc;
595     if (!getExecFileDescriptor(file, getPid(), true, status, desc)) {
596         startup_cerr << "Failed to find exec descriptor" << endl;
597     ///    cleanupBPatchHandle(theProc->sh->getPid());
598       //  processVec.pop_back();
599         delete proc;
600         proc = NULL;
601         return false;
602     }
603     //HACKSTATUS = status;
604
605     if (!proc->setAOut(desc)) {
606         startup_printf("[%s:%u] - Couldn't setAOut\n", __FILE__, __LINE__);
607        // cleanupBPatchHandle(theProc->sh->getPid());
608        // processVec.pop_back();
609         delete proc;
610         proc = NULL;
611         return false;
612     }
613
614     
615   }
616   else if (!proc->getParent()){
617     //  attach case (pid != -1 && proc->parent == NULL)
618     proc->createRepresentativeLWP();
619
620     if (!attachProcess()) {
621        fprintf(stderr, "%s[%d]:  failed to attach to process %d\n", FILE__, __LINE__,
622                pid);
623        delete proc;
624        proc = NULL;
625        return false;
626     }
627
628 #if defined(i386_unknown_nt4_0)
629     int status = (int)INVALID_HANDLE_VALUE;    // indicates we need to obtain a valid handle
630 #else
631     int status = pid;
632 #endif // defined(i386_unknown_nt4_0)
633
634     fileDescriptor desc;
635     if (!getExecFileDescriptor(file,
636 #if defined(os_windows)
637                              (int)INVALID_HANDLE_VALUE,
638 #else
639                              pid,
640 #endif
641                              false,
642                              status,
643                              desc)) {
644         delete proc;
645         proc = NULL;
646         return false;
647     }
648
649     if (!proc->setAOut(desc)) {
650        delete proc;
651        proc = NULL;
652        return false;
653     }
654
655   }
656   else { // proc->getParent() is non-NULL, fork case
657      proc->createRepresentativeLWP();
658      
659      if (!attachProcess()) {
660          fprintf(stderr, "%s[%d]:  failed to attach to process %d\n", FILE__, __LINE__,
661                  pid);
662          delete proc;
663          proc = NULL;
664          return false;
665      }
666      
667      if (!proc->setupFork()) {
668          fprintf(stderr, "%s[%d]:  failed to setupFork\n", FILE__, __LINE__);
669          delete proc;
670          proc = NULL;
671          return false;
672      }
673
674   }
675
676   return true;
677 }
678
679 bool SignalGeneratorCommon::handleEventLocked(EventRecord &ev)
680 {
681   char buf[128];
682   signal_printf("%s[%d]:  dispatching event %s\n", FILE__, __LINE__,
683                 ev.sprint_event(buf));
684
685   if (ev.type == evtUndefined) {
686     fprintf(stderr, "%s[%d]:  CHECK THIS, undefined event\n", FILE__, __LINE__); 
687     return true;
688   }
689
690   SignalHandler *sh = NULL;
691   for (unsigned int i = 0; i < handlers.size(); ++i) {
692     if (handlers[i]->assignEvent(ev)) {
693       sh = handlers[i];
694       break;
695     }
696   }
697
698   if ((sh) && (handlers.size() > HANDLER_TRIM_THRESH)) {
699     for (int i = handlers.size() - 1; i >= 0; i--) {
700       if (!handlers[i]->idle()) break;
701       if (handlers[i] != sh) {
702         signal_printf("%s[%d]:  trimming idle signal handler %s\n", FILE__, __LINE__,
703                       handlers[i]->getName());
704         delete handlers[i];
705         handlers.erase(i,i);
706       }
707     }
708   }
709
710   if (handlers.size() > MAX_HANDLERS) {
711      fprintf(stderr, "%s[%d]:  FATAL:  Something is horribly wrong.\n", FILE__, __LINE__);
712      fprintf(stderr, "\thave %d signal handlers, max is %d\n", 
713              handlers.size(), MAX_HANDLERS);
714      abort();
715   }
716
717   bool ret = true;
718   if (!sh) {
719     int shid = handlers.size();
720     char shname[64];
721     sprintf(shname, "SH-%d-%d", pid, shid);
722     signal_printf("%s[%d]:  about to create event handler %s\n", 
723                    FILE__, __LINE__, shname);
724     sh = newSignalHandler(shname, shid);
725     sh->createThread();
726     handlers.push_back(sh);
727     ret = sh->assignEvent(ev);
728     if (!ret)  {
729        char buf[128];
730        fprintf(stderr, "%s[%d]:  failed to assign event %s to handler\n", 
731                FILE__, __LINE__, ev.sprint_event(buf));
732     }
733   }
734
735   //  special case:  if this event is a process exit event, we want to shut down
736   //  the SignalGenerator (there are not going to be any more events to listen for).
737   //  The exit event has been passed off to a handler presumably, which will take
738   //  care of user notifications, callbacks, etc.
739
740   if (ev.type == evtProcessExit) {
741     signal_printf("%s[%d]:  preparing to shut down signal gen for process %d\n", FILE__, __LINE__, pid);
742     stopThreadNextIter();
743   }
744
745   return ret;
746 }
747
748 bool SignalGeneratorCommon::signalActiveProcess()
749 {         
750   bool ret = true;
751   if (waiting_for_active_process)
752     ret = __BROADCAST;
753   return ret;
754 }   
755
756 bool SignalGeneratorCommon::signalEvent(EventRecord &ev)
757 {
758   if (ev.type != evtError) {
759     char buf[128];
760     signal_printf("%s[%d][%s]:  signalEvent(%s)\n", FILE__, __LINE__, 
761                   getThreadStr(getExecThreadID()), ev.sprint_event(buf));
762   }
763   assert(global_mutex->depth());
764
765   getMailbox()->executeCallbacks(FILE__, __LINE__);
766
767   if (ev.type == evtProcessStop || ev.type == evtProcessExit) {
768      //fprintf(stderr, "%s[%d]:  flagging BPatch status change\n", FILE__, __LINE__);
769      SignalHandler::flagBPatchStatusChange();
770   }
771
772   bool ret = false;
773   for (unsigned int i = 0; i <wait_list.size(); ++i) {
774     if (wait_list[i]->signalIfMatch(ev)) {
775       ret = true;
776     }
777   }
778
779   global_wait_list_lock._Lock(__FILE__, __LINE__);
780   for (unsigned int i = 0; i < global_wait_list.size(); ++i) {
781       if (global_wait_list[i]->signalIfMatch(ev)) {
782           ret = true;
783       }
784   }
785   global_wait_list_lock._Unlock(__FILE__, __LINE__);
786
787
788   
789 #if 0
790   if (!ret) 
791     signal_printf("%s[%d][%s]:  signalEvent(%s): nobody waiting\n", FILE__, __LINE__, 
792                   getThreadStr(getExecThreadID()), eventType2str(ev.type));
793 #endif
794   return ret;
795 }
796
797 bool SignalGeneratorCommon::signalEvent(eventType t)
798 {
799   EventRecord ev;
800   ev.type = t;
801   return signalEvent(ev);
802 }
803
804 eventType SignalGeneratorCommon::waitForOneOf(pdvector<eventType> &evts)
805 {
806   assert(global_mutex->depth());
807
808   if (getExecThreadID() == getThreadID()) {
809     fprintf(stderr, "%s[%d][%s]:   ILLEGAL:  SYNC THREAD waiting on for a signal\n", 
810             FILE__, __LINE__, getThreadStr(getExecThreadID()));
811     abort();
812   }
813
814   //  When to set wait_flag ??
815   //    (1)  If we are running on an event handler thread
816   //    (2)  If we are currently running inside a callback AND an 
817   //         event handler is waiting for the completion of this callback
818   SignalHandler *sh = findSHWithThreadID(getExecThreadID());
819   if (sh)
820     sh->wait_flag = true;
821   else {
822     CallbackBase *cb = NULL;
823     if (NULL != (cb = getMailbox()->runningInsideCallback())) {
824       sh = findSHWaitingForCallback(cb);
825       if (sh)
826         sh->wait_flag = true;
827     }
828   }
829
830   EventGate *eg = new EventGate(global_mutex,evts[0]);
831   for (unsigned int i = 1; i < evts.size(); ++i) {
832     eg->addEvent(evts[i]);
833   }
834   wait_list.push_back(eg);
835   if (global_mutex->depth() > 1)
836     fprintf(stderr, "%s[%d]:  about to EventGate::wait(), lock depth %d\n", FILE__, __LINE__, 
837            global_mutex->depth());
838   EventRecord result = eg->wait();
839   
840   bool found = false;
841   for (int i = wait_list.size() -1; i >= 0; i--) {
842     if (wait_list[i] == eg) {
843        found = true;
844        wait_list.erase(i,i);
845        delete eg;
846        break;
847     } 
848   }
849
850   if (!found) {
851      fprintf(stderr, "%s[%d]:  BAD NEWS, somehow lost a pointer to eg\n", 
852              FILE__, __LINE__);
853   }
854
855   if (sh)
856     sh->wait_flag = false;
857   return result.type;
858 }
859
860
861 // Global version of the one above this: only called by threads external to
862 // the entire signal process (e.g., UI thread) who need to wait cross-process.
863
864 // Static method.
865 eventType SignalGeneratorCommon::globalWaitForOneOf(pdvector<eventType> &evts)
866 {
867   assert(global_mutex->depth());
868
869   EventGate *eg = new EventGate(global_mutex,evts[0]);
870   for (unsigned int i = 1; i < evts.size(); ++i) {
871       eg->addEvent(evts[i]);
872   }
873
874   global_wait_list_lock._Lock(__FILE__, __LINE__);
875   global_wait_list.push_back(eg);
876   global_wait_list_lock._Unlock(__FILE__, __LINE__);
877
878   if (global_mutex->depth() > 1)
879     fprintf(stderr, "%s[%d]:  about to EventGate::wait(), lock depth %d\n", FILE__, __LINE__, 
880            global_mutex->depth());
881   EventRecord result = eg->wait();
882   
883   global_wait_list_lock._Lock(__FILE__, __LINE__);
884   bool found = false;
885   for (int i = global_wait_list.size() -1; i >= 0; i--) {
886     if (global_wait_list[i] == eg) {
887        found = true;
888        global_wait_list.erase(i,i);
889        delete eg;
890        break;
891     } 
892   }
893   global_wait_list_lock._Unlock(__FILE__, __LINE__);
894   
895   if (!found) {
896      fprintf(stderr, "%s[%d]:  BAD NEWS, somehow lost a pointer to eg\n", 
897              FILE__, __LINE__);
898   }
899
900   return result.type;
901 }
902
903 eventType SignalGeneratorCommon::waitForEvent(eventType evt, process *p, dyn_lwp *lwp,
904                                         eventStatusCode_t status)
905 {
906   if (getExecThreadID() == getThreadID()) {
907     fprintf(stderr, "%s[%d][%s]:   ILLEGAL:  SYNC THREAD waiting on for a signal: %s\n", 
908             FILE__, __LINE__, getThreadStr(getExecThreadID()), eventType2str(evt));
909     abort();
910   }
911
912 #if 0
913   fprintf(stderr, "%s[%d]:  welcome to waitForEvent(%s)\n", FILE__, __LINE__, eventType2str(evt));
914 #endif
915
916   //  When to set wait_flag ??
917   //    (1)  If we are running on an event handler thread
918   //    (2)  If we are currently running inside a callback AND a 
919   //         signal handler is waiting for the completion of this callback
920   SignalHandler *sh = findSHWithThreadID(getExecThreadID());
921   if (sh)
922     sh->wait_flag = true;
923   else {
924     CallbackBase *cb = NULL;
925     if (NULL != (cb = getMailbox()->runningInsideCallback())) {
926       sh = findSHWaitingForCallback(cb);
927       if (sh)
928         sh->wait_flag = true;
929     }
930   }
931
932   EventGate *eg = new EventGate(global_mutex,evt,p, lwp, status);
933   wait_list.push_back(eg);
934   
935   if (global_mutex->depth() > 1)
936     fprintf(stderr, "%s[%d]:  about to EventGate::wait(%s), lock depth %d\n", FILE__, __LINE__, 
937            eventType2str(evt), global_mutex->depth());
938   EventRecord result = eg->wait();
939   
940   bool found = false;
941   for (int i = wait_list.size() -1; i >= 0; i--) {
942     if (wait_list[i] == eg) {
943        found = true;
944        wait_list.erase(i,i);
945        delete eg;
946        break;
947     } 
948   }
949
950   if (!found) {
951      fprintf(stderr, "%s[%d]:  BAD NEWS, somehow lost a pointer to eg\n", 
952              FILE__, __LINE__);
953   }
954
955   if (sh)
956     sh->wait_flag = false;
957   return result.type;
958 }
959
960 SignalHandler *SignalGeneratorCommon::findSHWithThreadID(unsigned long tid)
961 {
962   for (unsigned int i = 0; i < handlers.size(); ++i) {
963     if (handlers[i]->getThreadID() == tid)
964       return handlers[i];
965   }
966   return NULL;
967 }
968
969 SignalHandler *SignalGeneratorCommon::findSHWaitingForCallback(CallbackBase *cb)
970 {
971   for (unsigned int i = 0; i < handlers.size(); ++i) {
972     if (handlers[i]->wait_cb == cb)
973       return handlers[i];
974   }
975   return NULL;
976 }
977
978 bool SignalHandler::isActive(process *p) {
979     // Cases:
980     if (idle_flag) return false;
981
982     if (wait_cb) {
983         // Experiment: release "lock" if we're waiting
984         // for a callback to complete.
985         return false;
986     }
987
988     return p == active_proc;
989 }
990
991 bool SignalGeneratorCommon::activeHandlerForProcess(process *p)
992 {
993     // If the handler is active and running on a different thread from
994     // us (as we can get the following:
995     //    Handler calls into BPatch
996     //    BPatch tries continue
997     //    .... continue blocked because of active handler
998
999   for (unsigned int i = 0; i < handlers.size(); ++i) {
1000       if (handlers[i]->isActive(p) &&
1001           !(handlers[i]->getThreadID() == getExecThreadID()))
1002           return true;
1003   }
1004   return false;
1005 }
1006
1007 bool SignalGeneratorCommon::anyActiveHandlers()
1008 {
1009   for (unsigned int i = 0; i < handlers.size(); ++i) {
1010     if (!handlers[i]->idle())
1011       return true;
1012   }
1013   return false;
1014 }
1015
1016 bool SignalGeneratorCommon::decodeIfDueToProcessStartup(EventRecord &ev)
1017 {
1018   bool ret = false;
1019   char buf[128];
1020   process *proc = ev.proc;
1021   bootstrapState_t bootstrapState = proc->getBootstrapState();
1022
1023   //fprintf(stderr, "%s[%d]:  decodeIfDueToProcessStartup: state: %s\n", FILE__, __LINE__, proc->getBootstrapStateAsString().c_str());
1024   switch(bootstrapState) {
1025     case bootstrapped_bs:  
1026         break;
1027     case unstarted_bs:     
1028     case attached_bs:
1029         if (proc->wasCreatedViaAttach())
1030           ev.type = evtProcessAttach; 
1031         else 
1032           ev.type = evtProcessCreate; 
1033         ret = true;
1034         break;
1035     case begun_bs:         
1036 #if defined (os_windows)
1037        if (proc->trapAtEntryPointOfMain(NULL, (Address)ev.info.u.Exception.ExceptionRecord.ExceptionAddress)) {
1038           ev.type = evtProcessInit; 
1039           ret = true;
1040        }
1041 #else
1042        if (proc->trapAtEntryPointOfMain(ev.lwp)) {
1043           ev.type = evtProcessInit; 
1044           ret = true;
1045        }
1046 #endif
1047        else {
1048
1049          fprintf(stderr, "%s[%d]:  begun_bs, but no trap!!!!!\n", FILE__, __LINE__);
1050        }
1051        break;
1052     case loadingRT_bs:
1053         if (proc->trapDueToDyninstLib(ev.lwp)) {
1054           ev.type = evtProcessLoadedRT;
1055           ret = true;
1056         }
1057 #if 0
1058   //  windows has more info available here, not just from getActiveFrame -- we
1059   //  used to use it, but it may not be necessary anymore...
1060
1061      if (proc->dyninstlib_brk_addr &&
1062             (proc->dyninstlib_brk_addr == (Address)ev.info.u.Exception.ExceptionRecord.ExceptionAddress)) {
1063
1064         ev.type = evtProcessLoadedRT;
1065        ret = true;
1066      }
1067
1068 #endif
1069         break;
1070     case initialized_bs:
1071     case loadedRT_bs:
1072     default:
1073       break;
1074   };
1075   
1076   if (ret)
1077      signal_printf("%s[%d]:  decodeIfDueToProcessStartup got %s, status = %s\n",
1078                    FILE__, __LINE__, ev.sprint_event(buf), 
1079                    proc->getBootstrapStateAsString().c_str());
1080
1081   return ret;
1082 }
1083
1084 SignalHandler::~SignalHandler()
1085 {
1086    signal_printf("%s[%d]:  welcome to ~SignalHandler\n", FILE__, __LINE__);
1087    if (idle_flag || wait_flag) {
1088      // maybe a bit heavy handed here....
1089      stopThreadNextIter();
1090      //killThread();
1091    }else {
1092      signal_printf("%s[%d]:  waiting for idle before killing thread %s\n", 
1093              FILE__, __LINE__, getName());
1094      int timeout = 2000 /*ms*/, time_elapsed = 0;
1095      while (!idle_flag && !wait_flag) {
1096        struct timeval slp;
1097        slp.tv_sec = 0;
1098        slp.tv_usec = 10 /*ms*/ *1000;
1099        select(0, NULL, NULL, NULL, &slp);
1100        time_elapsed +=10;
1101        if (time_elapsed >= timeout) {
1102          fprintf(stderr, "%s[%d]:  cannot kill thread %s, did not become idle\n", FILE__, __LINE__, getName());
1103          break;
1104        }
1105      }
1106      if (idle_flag || wait_flag) {
1107        stopThreadNextIter();
1108      //  killThread();
1109      }
1110    }
1111 }
1112
1113
1114 bool SignalHandler::handleSingleStep(EventRecord &ev) 
1115 {
1116    if (!ev.lwp->isSingleStepping()) {
1117      fprintf(stderr, "%s[%d]:  unexpected step event\n", FILE__, __LINE__);
1118    }
1119    ev.lwp->setSingleStepping(false);
1120    sg->signalEvent(evtDebugStep);
1121    return true;
1122 }
1123
1124 bool SignalHandler::handleProcessStop(EventRecord &ev)
1125 {
1126    process *proc = ev.proc;
1127    bool retval = false;
1128
1129 #if defined(os_linux)
1130       // Linux uses SIGSTOPs for process control.  If the SIGSTOP
1131       // came during a process::pause (which we would know because
1132       // suppressEventConts() is set) then we'll handle the signal.
1133       // If it comes at another time we'll assume it came from something
1134       // like a Dyninst Breakpoint and not handle it.      
1135       if (!ev.lwp) {
1136          fprintf(stderr, "%s[%d]:  no lwp for SIGSTOP handling (needed)\n", FILE__, __LINE__);
1137          return false;
1138       }
1139       proc->set_lwp_status(ev.lwp, stopped);
1140       proc->set_status(stopped);
1141 #else
1142       signal_printf("%s[%d]:  unhandled SIGSTOP for pid %d, process will stay paused\n",
1143              FILE__, __LINE__, proc->getPid());
1144 #endif
1145       retval = true;
1146
1147    bool exists = false;
1148    BPatch_process *bproc = BPatch::bpatch->getProcessByPid(proc->getPid(), &exists);
1149    if (bproc) {
1150        setBPatchProcessSignal(bproc, ev.what);
1151        bproc->isVisiblyStopped = true;
1152    }
1153
1154    // Unlike other signals, don't forward this to the process. It's stopped
1155    // already, and forwarding a "stop" does odd things on platforms
1156    // which use ptrace. PT_CONTINUE and SIGSTOP don't mix
1157    return retval;
1158 }
1159
1160 bool SignalHandler::forwardSigToProcess(EventRecord &ev) 
1161 {
1162     process *proc = ev.proc;
1163
1164     // Pass the signal along to the child
1165     bool res;
1166     if(process::IndependentLwpControl()) {
1167        res = ev.lwp->continueLWP(ev.what);
1168     } else {
1169        res = proc->continueProc(ev.what);
1170     }
1171     if (res == false) {
1172         fprintf(stderr, "%s[%d]:  Couldn't forward signal %d to process %d\n",
1173                 FILE__, __LINE__, ev.what, proc->getPid());
1174         logLine("error  in forwarding  signal\n");
1175         showErrorCallback(38, "Error  in forwarding  signal");
1176         return false;
1177     } 
1178
1179     return true;
1180 }
1181
1182 bool SignalHandler::handleProcessExit(EventRecord &ev) 
1183 {
1184   bool ret = false;
1185   process *proc = ev.proc;
1186
1187   if (ev.status == statusNormal) {
1188       sprintf(errorLine, "Process %d has terminated with code 0x%x\n",
1189               proc->getPid(), (int) ev.what);
1190       statusLine(errorLine);
1191 #if defined(os_windows)
1192       //  on the unixes we do this at syscall exit()
1193       proc->triggerNormalExitCallback(ev.what);
1194 #endif
1195       ret = proc->handleProcessExit();
1196    } else if (ev.status == statusSignalled) {
1197       sprintf(errorLine, "process %d has terminated on signal %d\n",
1198               proc->getPid(), (int) ev.what);
1199       logLine(errorLine);
1200       statusLine(errorLine);
1201       printDyninstStats();
1202       proc->triggerSignalExitCallback(ev.what);
1203       ret = proc->handleProcessExit();
1204     } else {
1205       sprintf(errorLine, "process %d has terminated for unknown reason\n",
1206               proc->getPid());
1207       logLine(errorLine);
1208       ret = proc->handleProcessExit();
1209       //ret = true; //  maybe this should be false?  (this case is an error)
1210     }
1211
1212   flagBPatchStatusChange();
1213   return ret;
1214 }
1215
1216 bool SignalHandler::handleCritical(EventRecord &ev) 
1217 {
1218    process *proc = ev.proc;
1219    assert(proc);
1220
1221    signal_printf("Process %d dying on signal %d\n", proc->getPid(), ev.what);
1222
1223     {
1224 #ifndef mips_unknown_ce2_11 //ccw 6 feb 2001 : 29 mar 2001
1225         // Should walk stacks for other threads as well
1226         pdvector<pdvector<Frame> > stackWalks;
1227         proc->walkStacks(stackWalks, true);
1228         for (unsigned walk_iter = 0; walk_iter < stackWalks.size(); walk_iter++) {
1229             fprintf(stderr, "%s[%d]:  Registers for pid %d, lwpid %d\n", FILE__, __LINE__,
1230                     stackWalks[walk_iter][0].getLWP()->proc()->getPid(), 
1231                     stackWalks[walk_iter][0].getLWP()->get_lwp_id());
1232             stackWalks[walk_iter][0].getLWP()->dumpRegisters();
1233             fprintf(stderr, "%s[%d]:  Stack for pid %d, lwpid %d\n", FILE__, __LINE__,
1234                     stackWalks[walk_iter][0].getLWP()->proc()->getPid(), 
1235                     stackWalks[walk_iter][0].getLWP()->get_lwp_id());
1236             for( unsigned i = 0; i < stackWalks[walk_iter].size(); i++ )
1237             {
1238                 //int_function* f = proc->findFuncByAddr( stackWalks[walk_iter][i].getPC() );
1239                 //const char* szFuncName = (f != NULL) ? f->prettyName().c_str() : "<unknown>";
1240                 //fprintf( stderr, "%08x: %s\n", stackWalks[walk_iter][i].getPC(), szFuncName );
1241                 cerr << stackWalks[walk_iter][i] << endl;
1242             }
1243         }
1244         
1245 #endif
1246     }
1247
1248     int sleep_counter = SLEEP_ON_MUTATEE_CRASH;
1249     while (dyn_debug_signal && (sleep_counter > 0)) {
1250        signal_printf("Critical signal received, spinning to allow debugger to attach\n");
1251        sleep(10);
1252        sleep_counter -= 10;
1253     }
1254
1255     if (CAN_DUMP_CORE)
1256       proc->dumpImage("imagefile");
1257     else
1258       proc->dumpMemory((void *)ev.address, 32);
1259
1260     fprintf(stderr, "Forwarding signal to process\n");
1261     return forwardSigToProcess(ev);
1262 }
1263
1264 bool SignalHandler::handleEvent(EventRecord &ev)
1265 {
1266   global_mutex->_Lock(FILE__, __LINE__);
1267   bool ret = handleEventLocked(ev); 
1268   if (!events_to_handle.size())
1269     idle_flag = true;
1270   active_proc = NULL;
1271   global_mutex->_Unlock(FILE__, __LINE__);
1272
1273   return ret;
1274 }
1275
1276 bool SignalHandler::handleForkEntry(EventRecord &ev)
1277 {
1278      signal_printf("Welcome to FORK ENTRY for process %d\n",
1279                    ev.proc->getPid());
1280      return ev.proc->handleForkEntry();
1281 }
1282
1283 bool SignalHandler::handleLwpExit(EventRecord &ev)
1284 {
1285    signal_printf("%s[%d]:  welcome to handleLwpExit\n", FILE__, __LINE__);
1286    process *proc = ev.proc;
1287    dyn_lwp *lwp = ev.lwp;
1288    dyn_thread *thr = NULL;
1289    //Find the exiting thread
1290    for (unsigned i=0; i<proc->threads.size(); i++)
1291       if (proc->threads[i]->get_lwp()->get_lwp_id() == lwp->get_lwp_id())
1292       {
1293          thr = proc->threads[i];
1294          break;
1295       }
1296    if (!thr)
1297    {
1298       return false;
1299    }
1300
1301    ev.type = evtThreadExit;
1302
1303    if (proc->IndependentLwpControl())
1304       proc->set_lwp_status(ev.lwp, exited);
1305
1306    BPatch_process *bproc = BPatch::bpatch->getProcessByPid(proc->getPid());
1307    BPatch_thread *bthrd = bproc->getThread(thr->get_tid());
1308
1309    pdvector<CallbackBase *> cbs;
1310    getCBManager()->dispenseCallbacksMatching(evtThreadExit, cbs);
1311    for (unsigned int i = 0; i < cbs.size(); ++i) {
1312      AsyncThreadEventCallback &cb = * ((AsyncThreadEventCallback *) cbs[i]);
1313      mailbox_printf("%s[%d]:  executing thread exit callback\n", FILE__, __LINE__);
1314      BPatch_thread *bpthread = bproc->getThreadByIndex(bthrd->getBPatchID());
1315      assert(bpthread);
1316      cb(bproc, bpthread);
1317    }
1318
1319    flagBPatchStatusChange();
1320    return true;
1321 }
1322 bool SignalHandler::handleSyscallEntry(EventRecord &ev)
1323 {
1324     signal_printf("%s[%d]:  welcome to handleSyscallEntry\n", FILE__, __LINE__);
1325     process *proc = ev.proc;
1326     bool ret = false;
1327     switch ((procSyscall_t)ev.what) {
1328       case procSysFork:
1329           ret = handleForkEntry(ev);
1330           break;
1331       case procSysExec:
1332          ret = handleExecEntry(ev);
1333          break;
1334       case procSysExit:
1335           signal_printf("%s[%d]:  handleSyscallEntry exit(%d)\n", FILE__, __LINE__, ev.what);
1336           proc->triggerNormalExitCallback(INFO_TO_EXIT_CODE(ev.info));
1337           ret = true;
1338           break;
1339       case procLwpExit:
1340          assert(0);
1341          //  this case should be hijacked during event decoding and mapped onto
1342          //  the evtThreadExit event type.
1343
1344          break;
1345       default:
1346       // Check process for any other syscall
1347       // we may have trapped on entry to?
1348       ret = false;
1349       break;
1350     }
1351     return ret;
1352 }
1353
1354 bool SignalHandler::handleForkExit(EventRecord &ev)
1355 {
1356      signal_printf("Welcome to FORK EXIT for process %d\n",
1357                    ev.proc->getPid());
1358
1359      process *proc = ev.proc;
1360      // Fork handler time
1361      extern pdvector<process*> processVec;
1362      int childPid = INFO_TO_PID(ev.info);
1363
1364      if (childPid == getpid()) {
1365          // this is a special case where the normal createProcess code
1366          // has created this process, but the attach routine runs soon
1367          // enough that the child (of the mutator) gets a fork exit
1368          // event.  We don't care about this event, so we just continue
1369          // the process - jkh 1/31/00
1370          return true;
1371      } else if (childPid > 0) {
1372
1373          unsigned int i;
1374          for (i=0; i < processVec.size(); i++) {
1375              if (processVec[i] &&
1376                  (processVec[i]->getPid() == childPid)) break;
1377          }
1378          if (i== processVec.size()) {
1379              // this is a new child, register it with dyninst
1380              // Note: we need to wait for the child process to be created.
1381
1382              sleep(1);
1383
1384              // For now, we sleep (apparently), but the better solution is to
1385              // loop waiting for the child to be created and then attach to it.
1386              // We have seen the following order:
1387              // Parent exits fork
1388              // We get notification -- but no child yet.
1389              // Child is created
1390              // This seems to be OS dependent on who goes first - parent or child.
1391
1392              // We leave the parent paused until the child is finished,
1393              // so that we can be sure to copy everything correctly.
1394
1395              process *theChild = ev.proc->sh->newProcess(proc, (int) childPid, -1);
1396              if (!theChild)
1397                return false;
1398    
1399              proc->handleForkExit(theChild);
1400         }
1401      }
1402      else {
1403          // Child signalGenerator may execute this guy ; leave it untouched.
1404
1405      }
1406     return true;
1407 }
1408 // the alwaysdosomething argument is to maintain some strange old code
1409 bool SignalHandler::handleExecExit(EventRecord &ev)
1410 {
1411     process *proc = ev.proc;
1412     proc->nextTrapIsExec = false;
1413     if ( (int) INFO_TO_PID(ev.info) == -1) {
1414         // Failed exec, do nothing
1415         return false;
1416     }
1417
1418     proc->execFilePath = proc->tryToFindExecutable(proc->execPathArg, proc->getPid());
1419     // As of Solaris 2.8, we get multiple exec signals per exec.
1420     // My best guess is that the daemon reads the trap into the
1421     // kernel as an exec call, since the process is paused
1422     // and PR_SYSEXIT is set. We want to ignore all traps 
1423     // but the last one.
1424
1425     // We also see an exec as the first signal in a process we create. 
1426     // That's because it... wait for it... execed!
1427     if (!proc->reachedBootstrapState(begun_bs)) {
1428         return handleProcessCreate(ev);
1429     }
1430
1431
1432    int status = 0;
1433    // False: not waitin' for a signal (theoretically, we already got
1434     // it when we attached)
1435     fileDescriptor desc;
1436     if (!proc->sh->getExecFileDescriptor(proc->execFilePath,
1437                                    proc->getPid(),
1438                                    false,
1439                                    status,
1440                                    desc)) {
1441         cerr << "Failed to find exec descriptor" << endl;
1442         return false;
1443     }
1444
1445     // Unlike fork, handleExecExit doesn't do all processing required.
1446     // We finish up when the trap at main() is reached.
1447     proc->handleExecExit(desc);
1448
1449     return true;
1450 }
1451
1452
1453 bool SignalHandler::handleSyscallExit(EventRecord &ev)
1454 {
1455     process *proc = ev.proc;
1456     bool ret = false;
1457
1458     // Check to see if a thread we were waiting for exited a
1459     // syscall
1460     bool wasHandled = proc->handleSyscallExit(ev.status, ev.lwp);
1461
1462     signal_printf( "%s[%d]:  welcome to handleSyscallExit:  wasHandled = %s\n", FILE__, __LINE__, wasHandled ? "true" : "false");
1463
1464     // Fall through no matter what since some syscalls have their
1465     // own handlers.
1466     switch((procSyscall_t) ev.what) {
1467       case procSysFork:
1468          signal_printf("%s[%d]:  Fork Exit\n", FILE__, __LINE__);
1469          ret = handleForkExit(ev);
1470          break;
1471       case procSysExec:
1472          signal_printf("%s[%d]:  Exec Exit\n", FILE__, __LINE__);
1473          ret = handleExecExit(ev);
1474          if (!ret)
1475            ev.proc->continueProc();
1476          break;
1477       case procSysLoad:
1478          signal_printf("%s[%d]:  Load Exit\n", FILE__, __LINE__);
1479          ret = handleLoadLibrary(ev);
1480          ev.proc->continueProc();
1481          break;
1482       default:
1483          fprintf(stderr, "%s[%d]:  unknown syscall\n", __FILE__, __LINE__);
1484          break;
1485     }
1486
1487 #if defined(rs6000_ibm_aix4_1)
1488     // When we handle a fork exit on AIX, we need to keep both parent and
1489     // child stopped until we've seen the fork exit on both.  This is so
1490     // we can copy the instrumentation from the parent to the child (if we
1491     // don't keep the parent stopped, it may, for instance, exit before we
1492     // can do this).  So, don't continue the process here - it will be
1493     // continued at the appropriate time by handleForkExit.
1494     if (((procSyscall_t)ev.what) != procSysFork)
1495 #endif
1496
1497     return ret || wasHandled;
1498 }
1499
1500 bool SignalHandler::handleEventLocked(EventRecord &ev)
1501 {
1502   signal_printf("%s[%d]:  got event: %s\n", FILE__, __LINE__, eventType2str(ev.type));
1503
1504   process *proc = ev.proc;
1505   bool ret = false;
1506   Frame activeFrame;
1507   assert(proc);
1508   
1509   // One big switch statement
1510   switch(ev.type) {
1511      // First the platform-independent stuff
1512      // (/proc and waitpid)
1513      case evtProcessExit:
1514         ret = handleProcessExit(ev);
1515         break;
1516      case evtProcessCreate:
1517         ret = handleProcessCreate(ev);
1518         break;
1519      case evtThreadCreate:
1520         ret = handleThreadCreate(ev);
1521         break;
1522      case evtThreadExit:
1523         ret = handleLwpExit(ev);
1524         break;
1525      case evtProcessAttach:
1526         proc->setBootstrapState(initialized_bs);
1527         ret = true;
1528         break;
1529      case evtProcessInit:
1530         proc->handleTrapAtEntryPointOfMain(ev.lwp);
1531         proc->setBootstrapState(initialized_bs);
1532         // If we were execing, we now know we finished
1533         if (proc->execing()) {
1534            proc->finishExec();
1535         }
1536         ret = true;
1537         break;
1538      case evtProcessLoadedRT:
1539      {
1540         pdstring buffer = pdstring("PID=") + pdstring(proc->getPid());
1541         buffer += pdstring(", loaded dyninst library");
1542         statusLine(buffer.c_str());
1543         startup_cerr << "trapDueToDyninstLib returned true, trying to handle\n";
1544         proc->loadDYNINSTlibCleanup(ev.lwp);
1545         proc->setBootstrapState(loadedRT_bs);
1546         //getSH()->signalEvent(evtProcessLoadedRT);
1547         ret = true;
1548         break;
1549      }
1550      case evtInstPointTrap:
1551          // Linux inst via traps
1552          ev.lwp->changePC(proc->trampTrapMapping[ev.address], NULL);
1553          proc->continueProc();
1554          ret = true;
1555          break;
1556      case evtLoadLibrary:
1557      case evtUnloadLibrary:
1558         ret = handleLoadLibrary(ev);
1559         proc->continueProc();
1560         break;
1561      case evtPreFork:
1562          // If we ever want to callback this guy, put it here.
1563          ret = true;
1564         proc->continueProc();
1565         break;
1566      case evtSignalled:
1567      {
1568         ret = forwardSigToProcess(ev);
1569         break;
1570      }
1571      case evtProcessStop:
1572      {
1573          ret = handleProcessStop(ev);
1574          if (!ret) {
1575              fprintf(stderr, "%s[%d]:  handleProcessStop failed\n", FILE__, __LINE__);
1576          }
1577          break;
1578      }
1579         // Now the /proc only
1580         // AIX clones some of these (because of fork/exec/load notification)
1581      case evtRPCSignal:
1582        ret = proc->getRpcMgr()->handleRPCEvent(ev);
1583        break;
1584      case evtSyscallEntry:
1585         ret = handleSyscallEntry(ev);
1586         if (!ret)
1587             cerr << "handleSyscallEntry failed!" << endl;
1588         break;
1589      case evtSyscallExit:
1590         ret = handleSyscallExit(ev);
1591         if (!ret)
1592             fprintf(stderr, "%s[%d]: handlesyscallExit failed! ", __FILE__, __LINE__); ;
1593         break;
1594      case evtSuspended:
1595        proc->continueProc();   // ignoring this signal
1596        ret = true;
1597        flagBPatchStatusChange();
1598        break;
1599      case evtDebugStep:
1600          handleSingleStep(ev);
1601          ret = 1;
1602          break;
1603      case evtUndefined:
1604         // Do nothing
1605          cerr << "Undefined event!" << endl;
1606         break;
1607      case evtCritical:
1608          ret = handleCritical(ev);
1609          break;
1610      case evtTimeout:
1611      case evtNullEvent:
1612      case evtThreadDetect:
1613         ret = true;
1614         break;
1615      default:
1616         fprintf(stderr, "%s[%d]:  cannot handle signal %s\n", FILE__, __LINE__, eventType2str(ev.type));
1617         assert(0 && "Undefined");
1618    }
1619
1620    sg->signalEvent(ev);
1621
1622    if (ret == false) {
1623       //  if ret is false, complain, but return true anyways, since the handler threads
1624       //  should be shut down by the SignalGenerator.
1625       char buf[128];
1626       fprintf(stderr, "%s[%d]:  failed to handle event %s\n", FILE__, __LINE__,
1627               ev.sprint_event(buf));
1628       ret = true;
1629    }
1630
1631    return ret;
1632 }
1633
1634 bool SignalHandler::idle()
1635 {
1636   bool ret;
1637   _Lock(FILE__, __LINE__);
1638   ret = idle_flag;
1639   _Unlock(FILE__, __LINE__);
1640   return ret;
1641 }
1642
1643 bool SignalHandler::waiting()
1644 {
1645   bool ret;
1646   _Lock(FILE__, __LINE__);
1647   ret = wait_flag;
1648   _Unlock(FILE__, __LINE__);
1649   return ret;
1650 }
1651
1652 bool SignalHandler::assignEvent(EventRecord &ev) 
1653 {
1654   char buf[128];
1655   bool ret = false;
1656   assert(global_mutex->depth());
1657
1658   //  after we get the lock, the handler thread should be either idle, or waiting
1659   //  for some event.  
1660
1661   while (!idle_flag) {
1662     if ((wait_flag) && (ev.type != evtShutDown)) {
1663       signal_printf("%s[%d]:  cannot assign event %s to %s, while it is waiting\n", 
1664                     FILE__, __LINE__, ev.sprint_event(buf), getName());
1665       return false;
1666     }
1667     signal_printf("%s[%d]:  shoving event %s into the queue for %s\n",
1668          FILE__, __LINE__, ev.sprint_event(buf), getName());
1669     events_to_handle.push_back(ev);
1670     if (ev.type == evtProcessExit) 
1671       sg->signalEvent(ev);
1672     else 
1673       _Broadcast(FILE__, __LINE__);
1674     return true;
1675   }
1676
1677   if (idle_flag) {
1678     // handler thread is not doing anything, assign away...
1679     signal_printf("%s[%d]:  assigning event %s to %s\n", FILE__, __LINE__,
1680                   ev.sprint_event(buf), getName());
1681     events_to_handle.push_back(ev);
1682     ret = true;
1683     idle_flag = false;
1684     _Broadcast(FILE__, __LINE__);
1685   } 
1686  // else {
1687  //   char buf[128];
1688  //   fprintf(stderr, "%s[%d]:  WEIRD, tried to assign %s to busy handler\n",
1689  //          FILE__, __LINE__, ev.sprint_event(buf));
1690  // } 
1691
1692   return ret;
1693 }
1694
1695 bool SignalHandler::waitNextEvent(EventRecord &ev)
1696 {
1697   bool ret;
1698   _Lock(FILE__, __LINE__);
1699   while (idle_flag) {
1700     signal_printf("%s[%d]:  handler %s waiting for something to do\n", 
1701                   FILE__, __LINE__, getName());
1702 #if 0
1703     fprintf(stderr, "%s[%d]:  sg->waitingForActiveProcess = %s\n", FILE__, __LINE__, sg->waitingForActiveProcess() ? "true" : "false");
1704     fprintf(stderr, "%s[%d]:  sg->anyActiveHandlers() = %s\n", FILE__, __LINE__, sg->anyActiveHandlers() ? "true" : "false");
1705 #endif
1706     if (!sg->anyActiveHandlers() && sg->waitingForActiveProcess()) {
1707       sg->signalEvent(evtProcessStop);
1708     }
1709     // Waiting for someone to ping our lock (internal thread)
1710     _WaitForSignal(FILE__, __LINE__);
1711
1712     // Someone wants us to go away....
1713     if (stop_request) {
1714         signal_printf("%s[%d]:  sg got stop request... no more handling\n", FILE__, __LINE__);
1715        ev.type = evtShutDown;
1716        
1717        // And bounce it back to the signalGenerator
1718        sg->signalEvent(ev);
1719        _Unlock(FILE__, __LINE__);
1720       return true;
1721     }
1722     signal_printf("%s[%d]:  handler %s has been signalled: got event = %s\n", 
1723                   FILE__, __LINE__, getName(), idle_flag ? "false" : "true");
1724   }
1725
1726   // Take the top thing off our queue and handle it. 
1727   ret = true;
1728   ev = events_to_handle[0];
1729   events_to_handle.erase(0,0);
1730   active_proc = ev.proc;
1731
1732   if (ev.type == evtUndefined) {
1733     fprintf(stderr, "%s[%d]:  got evtUndefined for next event!\n", FILE__, __LINE__);
1734     ret = false;
1735   }
1736
1737   _Unlock(FILE__, __LINE__);
1738   if (!ret) abort();
1739   return ret;
1740 }
1741
1742 signal_handler_location::signal_handler_location(Address addr, unsigned size) :
1743     addr_(addr),
1744     size_(size) {}