Problem 1:
[dyninst.git] / dyninstAPI / src / unix.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: unix.C,v 1.164 2006/02/14 23:50:16 jaw Exp $
43
44 #include "common/h/headers.h"
45 #include "common/h/String.h"
46 #include "common/h/Vector.h"
47 #include "dyninstAPI/src/showerror.h"
48 #include "dyninstAPI/src/os.h"
49 #include "dyninstAPI/src/util.h"
50 #include "dyninstAPI/src/debuggerinterface.h"
51 #include "dyninstAPI/src/mapped_object.h"
52 #include "dyninstAPI/src/callbacks.h"
53 #include "dyninstAPI/src/dynamiclinking.h"
54 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"  // for DYNINST_BREAKPOINT_SIGNUM
55
56
57 #ifndef BPATCH_LIBRARY
58 #include "paradynd/src/main.h"  // for "tp" ?
59 #include "paradynd/src/pd_process.h" // for class pd_process
60 #endif
61
62 // the following are needed for handleSigChild
63 #include "dyninstAPI/src/signalhandler.h"
64 #include "dyninstAPI/src/process.h"
65 #include "dyninstAPI/src/dyn_lwp.h"
66 #include "dyninstAPI/src/dyn_thread.h"
67 #include "dyninstAPI/src/instP.h"
68 #include "dyninstAPI/src/stats.h"
69
70 // BREAK_POINT_INSN
71 #if defined(AIX_PROC)
72 #include "dyninstAPI/src/arch-power.h"
73 #endif
74 #include "dyninstAPI/src/sol_proc.h"
75
76 #include <sys/poll.h>
77
78
79 /////////////////////////////////////////////////////////////////////////////
80 /// Massive amounts of signal handling code
81 /////////////////////////////////////////////////////////////////////////////
82
83
84 // Turn the return result of waitpid into something we can use
85 bool decodeWaitPidStatus(procWaitpidStatus_t status,
86                         EventRecord &ev) {
87     // Big if-then-else tree
88     if (WIFEXITED(status)) {
89         ev.type = evtProcessExit;
90         ev.status = statusNormal;
91         ev.what = (eventWhat_t) (unsigned int) WEXITSTATUS(status);
92         return true;
93     } 
94     else if (WIFSIGNALED(status)) {
95         ev.type = evtProcessExit;
96         ev.status = statusSignalled;
97         ev.what = (eventWhat_t) (unsigned int) WTERMSIG(status);
98         return true;
99     }
100     else if (WIFSTOPPED(status)) {
101         ev.type = evtSignalled;
102         ev.status = statusSignalled;
103         ev.what = (eventWhat_t) (unsigned int) WSTOPSIG(status);
104         return true;
105     }
106     else {
107         fprintf(stderr, "%s[%d]:  unable to decode waitpid results\n", FILE__, __LINE__);
108         ev.type = evtUndefined;
109         ev.what = 0;
110         return false;
111     }
112     return false;
113 }
114
115 bool SignalGenerator::decodeRTSignal(EventRecord &ev)
116 {
117    // We've received a signal we believe was sent
118    // from the runtime library. Check the RT lib's
119    // status variable and return it.
120    // These should be made constants
121    process *proc = ev.proc;
122    if (!proc) return false;
123
124    pdstring status_str = pdstring("DYNINST_synch_event_id");
125    pdstring arg_str = pdstring("DYNINST_synch_event_arg1");
126
127    int status;
128    Address arg;
129
130    pdvector<int_variable *> vars;
131    if (!proc->findVarsByAll(status_str, vars)) {
132      return false;
133    }
134
135    if (vars.size() != 1) {
136      fprintf(stderr, "%s[%d]:  ERROR:  %d vars matching %s, not 1\n", 
137              FILE__, __LINE__, vars.size(), status_str.c_str());
138      return false;
139    }
140
141    Address status_addr = vars[0]->getAddress();
142
143    if (!proc->readDataSpace((void *)status_addr, sizeof(int),
144                             &status, true)) {
145       fprintf(stderr, "%s[%d]:  readDataSpace failed\n", FILE__, __LINE__);
146       return false;
147    }
148
149    if (status == DSE_undefined) {
150       return false; // Nothing to see here
151    }
152
153    vars.clear();
154    if (!proc->findVarsByAll(arg_str, vars)) {
155      return false;
156    }
157
158    if (vars.size() != 1) {
159      fprintf(stderr, "%s[%d]:  ERROR:  %d vars matching %s, not 1\n", 
160              FILE__, __LINE__, vars.size(), arg_str.c_str());
161      return false;
162    }
163
164    Address arg_addr = vars[0]->getAddress();
165
166    if (!proc->readDataSpace((void *)arg_addr, sizeof(Address),
167                             &arg, true)) {
168       fprintf(stderr, "%s[%d]:  readDataSpace failed\n", FILE__, __LINE__);
169       return false;
170    }
171
172    ev.info = (eventInfo_t)arg;
173    switch(status) {
174      case DSE_forkEntry:
175         /* Entry to fork */
176         ev.type = evtSyscallEntry;
177         ev.what = SYS_fork;
178         break;
179      case DSE_forkExit:
180         ev.type = evtSyscallExit;
181         ev.what = SYSSET_MAP(SYS_fork, proc->getPid());
182         break;
183      case DSE_execEntry:
184         /* Entry to exec */
185         ev.type = evtSyscallEntry;
186         ev.what = SYS_exec;
187         break;
188      case DSE_execExit:
189         ev.type = evtSyscallExit;
190         ev.what = SYS_exec;
191         /* Exit of exec, unused */
192         break;
193      case DSE_exitEntry:
194         /* Entry of exit, used for the callback. We need to trap before
195            the process has actually exited as the callback may want to
196            read from the process */
197         ev.type = evtSyscallEntry;
198         ev.what = SYS_exit;
199         break;
200    case DSE_loadLibrary:
201      /* We need to hook this into the shared library handling code... */
202         ev.type = evtSyscallExit;
203         ev.what = SYS_load;
204      break;
205
206      default:
207         assert(0);
208         break;
209    }
210   return decodeSyscall(ev);
211 }
212
213 bool SignalGenerator::decodeSigIll(EventRecord &ev) 
214 {
215 #if defined (arch_ia64) 
216   if ( ev.proc->getRpcMgr()->decodeEventIfDueToIRPC(ev))
217     return true;
218 #endif
219   ev.type = evtCritical;
220   return true;
221 }
222
223
224  //////////////////////////////////////////////////////////////////
225  // Syscall handling
226  //////////////////////////////////////////////////////////////////
227  // On AIX I've seen a long string of calls to exec, basically
228  // doing a (for i in $path; do exec $i/<progname>
229  // This means that the entry will be called multiple times
230  // until the exec call gets the path right.
231 bool SignalHandler::handleExecEntry(EventRecord &ev) 
232 {
233      return ev.proc->handleExecEntry((char *)ev.info);
234 }
235
236 bool SignalHandler::handleLoadLibrary(EventRecord &ev)
237 {
238    process *proc = ev.proc;
239    if (!proc->handleChangeInSharedObjectMapping(ev)) {
240       fprintf(stderr, "%s[%d]:  setting event to NULL because handleChangeIn.. failed\n",
241               FILE__, __LINE__);
242      ev.type = evtNullEvent;
243      return false;
244    }
245    return true;
246 }
247
248 #if !defined (os_linux)
249 bool SignalGenerator::decodeProcStatus(procProcStatus_t status, EventRecord &ev)
250 {
251
252    ev.info = GETREG_INFO(status.pr_reg);
253
254    switch (status.pr_why) {
255      case PR_SIGNALLED:
256         ev.type = evtSignalled;
257         ev.what = status.pr_what;
258         if (!decodeSignal(ev)) {
259           char buf[128];
260           fprintf(stderr, "%s[%d]:  decodeSignal failed\n", FILE__, __LINE__, ev.sprint_event(buf));
261           return false;
262         }
263         break;
264      case PR_SYSENTRY:
265         ev.type = evtSyscallEntry;
266         ev.what = status.pr_what;
267 #if defined(AIX_PROC)
268         // We actually pull from the syscall argument vector
269         if (status.pr_nsysarg > 0)
270            ev.info = status.pr_sysarg[0];
271         else
272            ev.info = 0;
273 #endif
274 #if defined (os_osf)
275        ev.info = status.pr_reg.regs[A0_REGNUM];
276 #endif
277         decodeSyscall(ev);
278         break;
279      case PR_SYSEXIT:
280         ev.type = evtSyscallExit;
281         ev.what = status.pr_what;
282
283 #if defined(AIX_PROC)
284         // This from the proc header file: system returns are
285         // left in pr_sysarg[0]. NOT IN MAN PAGE.
286         ev.info = status.pr_sysarg[0];
287 #endif
288 #if defined (os_osf)
289        ev.info = status.pr_reg.regs[V0_REGNUM];
290 #endif
291         decodeSyscall(ev);
292         break;
293      case PR_REQUESTED:
294         // We don't expect PR_REQUESTED in the signal handler
295         assert(0 && "PR_REQUESTED not handled");
296 #if defined(PR_SUSPENDED)
297      case PR_SUSPENDED:
298         // I'm seeing this state at times with a forking multi-threaded
299         // child process, currently handling by just continuing the process
300         ev.type = evtSuspended;
301         break;
302 #endif
303      case PR_JOBCONTROL:
304      case PR_FAULTED:
305      default:
306         assert(0);
307         break;
308    }
309
310    return true;
311 }
312 #endif
313
314 bool SignalGenerator::decodeSyscall(EventRecord &ev)
315 {
316 #if defined (os_aix)
317    process *p = ev.proc;
318    assert(p);
319    int pid = p->getPid();
320 #endif
321    int syscall = (int) ev.what;
322
323     if (syscall == SYSSET_MAP(SYS_fork, pid) ||
324         syscall == SYSSET_MAP(SYS_fork1, pid) ||
325         syscall == SYSSET_MAP(SYS_vfork, pid)) {
326         ev.what = (int) procSysFork;
327         return true;
328     }
329     if (syscall == SYSSET_MAP(SYS_exec, pid) ||
330         syscall == SYSSET_MAP(SYS_execv, pid) ||
331         syscall == SYSSET_MAP(SYS_execve, pid)) {
332         ev.what = (int) procSysExec;
333         return true;
334     }
335     if (syscall == SYSSET_MAP(SYS_exit, pid)) {
336         ev.what = (int) procSysExit; 
337         return true;
338     }
339     if (syscall == SYSSET_MAP(SYS_lwp_exit, pid)) {
340        ev.type = evtThreadExit;
341        ev.what = (int) procLwpExit;
342        return true;
343     }
344     // Don't map -- we make this up
345     if (syscall == SYS_load) {
346       ev.what = procSysLoad;
347       return true;
348     }
349
350     ev.what = procSysOther;
351     return false;
352 }
353
354 bool SignalHandler::handleProcessCreate(EventRecord &ev)
355 {
356   process * proc = ev.proc;
357   proc->setBootstrapState(begun_bs);
358   if (proc->insertTrapAtEntryPointOfMain()) {
359       pdstring buffer = pdstring("PID=") + pdstring(proc->getPid());
360       buffer += pdstring(", attached to process, stepping to main");
361       statusLine(buffer.c_str());
362       proc->continueProc();
363       return true;
364    } else {
365       // We couldn't insert the trap... so detach from the process
366       // and let it run. 
367       fprintf(stderr, "%s[%d][%s]:  ERROR:  couldn't insert at entry of main,\n",
368               FILE__, __LINE__, getThreadStr(getExecThreadID()));
369       fprintf(stderr, "\tinstrumenting process impossible\n");
370       // We should actually delete any mention of this
371       // process... including (for Paradyn) removing it from the
372       // frontend.
373       proc->triggerNormalExitCallback(0);
374       proc->handleProcessExit();
375       proc->continueProc();
376     }
377    return false;
378 }
379
380 bool SignalHandler::handleThreadCreate(EventRecord &)
381 {
382   assert(0);
383 }
384
385 //  checkForExit returns true when an exit has been detected
386 bool SignalGenerator::checkForExit(EventRecord &ev, bool block)
387 {
388   int waitpid_flags = block ? 0 : WNOHANG|WNOWAIT;
389   int status;
390
391   int retWait = waitpid(pid, &status, waitpid_flags);
392   if (retWait == -1) {
393        fprintf(stderr, "%s[%d]:  waitpid failed\n", __FILE__, __LINE__);
394        return false;
395    }
396    else if (retWait > 1) {
397       //fprintf(stderr, "%s[%d]:  checkForExit is returning true: pid %d exited, status was %s\n", FILE__, __LINE__, ev.proc->getPid(), ev.proc->getStatusAsString().c_str());
398       decodeWaitPidStatus(status, ev);
399       ev.proc = proc;
400       ev.lwp = proc->getRepresentativeLWP();
401       ev.info = 0;
402       return true;
403    }
404
405   return false;
406 }
407
408 #if !defined (os_linux)
409
410 bool SignalGenerator::waitNextEventLocked(EventRecord &ev)
411 {
412   bool ret = true;
413   int timeout = POLL_TIMEOUT;
414   signal_printf("%s[%d][%s]:  waitNextEvent\n", FILE__, __LINE__, 
415                 getThreadStr(getExecThreadID()));
416
417   assert(getExecThreadID() == getThreadID());
418   assert(getExecThreadID() != primary_thread_id);
419
420   assert(proc);
421   assert(proc->getRepresentativeLWP());
422
423   struct pollfd pfds[1]; 
424
425   pfds[0].fd = proc->getRepresentativeLWP()->POLL_FD;
426   pfds[0].events = POLLPRI;
427   pfds[0].revents = 0;
428
429   waiting_for_event = true;
430   __UNLOCK;
431   int num_selected_fds = poll(pfds, 1, timeout);
432   __LOCK;
433   waiting_for_event = false;
434   int handled_fds = 0;
435
436   if (num_selected_fds < 0) {
437     ret = false;
438 #if defined(os_osf)
439   //  alpha-osf apparently does not detect process exits from poll events,
440   //  so we have to check for exits before calling poll().
441   if (checkForExit(ev)) {
442     char buf[128];
443     signal_printf("%s[%d][%s]:  process exited %s\n", FILE__, __LINE__, 
444                 getThreadStr(getExecThreadID()), ev.sprint_event(buf));
445     ret = true;
446     decodeSignal(ev);
447     //decodeKludge(ev);
448   }
449 #else
450     stopThreadNextIter();
451     fprintf(stderr, "%s[%d]:  checkForProcessEvents: poll failed: %s\n", FILE__, __LINE__, strerror(errno));
452 #endif
453      return ret;
454   } else if (num_selected_fds == 0) {
455     //  poll timed out with nothing to report
456     signal_printf("%s[%d]:  poll timed out\n", FILE__, __LINE__);
457     ev.type = evtTimeout;
458     ev.proc = proc;
459     return true;
460   }
461
462   if (!pfds[0].revents) {
463      fprintf(stderr, "%s[%d]:  weird, no event for signalled process\n", FILE__, __LINE__);
464      return false;
465   }
466
467   ev.type = evtUndefined;
468   ev.proc = proc;
469   ev.lwp = proc->getRepresentativeLWP();
470   ev.info  = pfds[0].revents;
471
472   if (ev.proc->status() == running) {
473       ev.proc->set_status(stopped);
474   }
475   if (!decodeEvent(ev)) {
476        fprintf(stderr, "%s[%d]:  Internal Error: decodeEvent returned false\n", 
477                FILE__, __LINE__);
478    }
479    else {
480      if (ev.type == evtUndefined)
481        fprintf(stderr, "%s[%d]:  CHECK THIS evtUndefined\n", FILE__, __LINE__);
482    }
483
484   return ret;
485 }
486
487 #endif
488
489 #if !defined (os_aix)
490 //  This function is only needed on aix (right now)
491 bool SignalGenerator::decodeSignal_NP(EventRecord &)
492 {
493   return false;
494 }
495 #endif
496
497 bool SignalGenerator::decodeSignal(EventRecord &ev)
498 {
499
500   //  allow for platform specific decoding of signals, currently only used on
501   //  AIX.  If decodeSignal_NP() returns true, the event is fully decoded
502   //  so we're done here.
503
504   if (decodeSignal_NP(ev)) {
505     return true;
506   }
507
508   errno = 0;
509
510   if (ev.type != evtSignalled) {
511     char buf[128];
512     fprintf(stderr, "%s[%d]:  decodeSignal:  event %s is not a signal event??\n", FILE__, __LINE__,
513             ev.sprint_event(buf));
514     return false;
515   }
516
517   //  signal number is assumed to be in ev.what
518   switch(ev.what)  {
519   case SIGSTOP:
520   case SIGINT:
521       if (!decodeRTSignal(ev) && !decodeSigStopNInt(ev)) {
522           fprintf(stderr, "%s[%d]:  weird, decodeSigStop failed for SIGSTOP\n", FILE__, __LINE__);
523       }
524
525       // We have to use SIGSTOP for RTsignals, since we may not be attached
526       // at that point...
527       break;
528   case DYNINST_BREAKPOINT_SIGNUM: /*SIGUSR2*/
529     signal_printf("%s[%d]:  DYNINST BREAKPOINT\n", FILE__, __LINE__);
530     if (!decodeRTSignal(ev)) {
531         ev.type = evtProcessStop; // happens when we get a DYNINSTbreakPoint
532       }
533      break;
534   case SIGIOT:
535   {
536      ev.type = evtProcessExit;
537      ev.status = statusSignalled;
538   }
539   case SIGTRAP:
540   {
541     signal_printf("%s[%d]:  SIGTRAP\n", FILE__, __LINE__);
542     decodeSigTrap(ev);
543     break;
544   }
545   case SIGILL:
546   case SIGSEGV:
547   {
548      signal_printf("%s[%d]:  SIGILL\n", FILE__, __LINE__);
549 #if defined (arch_ia64)
550      Address pc = getPC(ev.proc->getPid());
551
552      if (pc == ev.proc->dyninstlib_brk_addr ||
553          pc == ev.proc->main_brk_addr ||
554          ev.proc->getDyn()->reachedLibHook(pc)) {
555         ev.what = SIGTRAP;
556         decodeSigTrap(ev);
557       }
558       else
559         decodeSigIll(ev);
560
561       signal_printf("%s[%d]:  SIGILL:  main brk = %p, dyn brk = %p, pc = %p/%p\n",
562            FILE__, __LINE__, ev.proc->main_brk_addr, ev.proc->dyninstlib_brk_addr,
563            pc, getPC(ev.proc->getPid()));
564 #else
565
566       decodeSigIll(ev);
567 #endif
568       break;
569   }
570   case SIGCHLD:
571 #if defined (os_linux)
572      // Linux fork() sends a SIGCHLD once the fork has been created
573      ev.type = evtPreFork;
574 #endif
575      break;
576   default:
577      signal_printf("%s[%d]:  got signal %d\n", FILE__, __LINE__, ev.what);
578      fprintf(stderr, "%s[%d]:  Signal %d\n", FILE__, __LINE__, ev.what);
579      break;
580   }
581
582   return true;
583 }
584
585 bool SignalGenerator::decodeSigTrap(EventRecord &ev)
586 {
587   char buf[128];
588   process *proc = ev.proc;
589
590   if (decodeIfDueToProcessStartup(ev)) {
591      signal_printf("%s[%d]:  decodeSigTrap for %s, state: %s\n",
592                 FILE__, __LINE__, ev.sprint_event(buf), 
593                 proc->getBootstrapStateAsString().c_str());
594      return true;
595   }
596
597   Frame af = ev.lwp->getActiveFrame();
598
599   // (1)  Is this trap due to an instPoint ??
600   if (proc->trampTrapMapping.defines(af.getPC())) {
601      ev.type = evtInstPointTrap;
602      ev.address = af.getPC();
603      goto finish;
604   }
605
606   // (2) Is this trap due to a RPC ??
607   if (proc->getRpcMgr()->decodeEventIfDueToIRPC(ev)) {
608       signal_printf("%s[%d]:  SIGTRAP due to RPC\n", FILE__, __LINE__);
609       goto finish;
610   }
611
612   // (3) Is this trap due to a library being loaded/unloaded ??
613   if (proc->isDynamicallyLinked()) {
614      if (proc->decodeIfDueToSharedObjectMapping(ev)){
615          signal_printf("%s[%d]:  SIGTRAP due to dlopen/dlclose\n", FILE__, __LINE__);
616          goto finish;
617       }
618    }
619
620   // (4) Is this trap due to a single step debugger operation ??
621   if (ev.lwp->isSingleStepping()) {
622      ev.type = evtDebugStep;
623      ev.address = af.getPC();
624      signal_printf("Single step trap at %lx\n", ev.address);
625      goto finish;
626    }
627
628 #if defined (os_linux)
629     // (5)  Is this trap due to an exec ??
630     // On Linux we see a trap when the process execs. However,
631     // there is no way to distinguish this trap from any other,
632     // and so it is special-cased here.
633     if (proc->nextTrapIsExec) {
634         signal_printf("%s[%d]: decoding trap as exec exit\n", FILE__, __LINE__);
635         ev.type = evtSyscallExit;
636         ev.what = SYS_exec;
637         decodeSyscall(ev);
638         goto finish;
639     }
640 #endif
641
642   finish:
643   signal_printf("%s[%d]:  decodeSigTrap for %s, state: %s\n",
644                 FILE__, __LINE__, ev.sprint_event(buf), 
645                 proc->getBootstrapStateAsString().c_str());
646   return true;
647 }
648
649
650 bool SignalGenerator::decodeSigStopNInt(EventRecord &ev)
651 {
652   process *proc = ev.proc;
653
654   signal_printf("%s[%d]:  welcome to decodeSigStopNInt for %d, state is %s\n",
655                 FILE__, __LINE__, ev.proc->getPid(), 
656                 proc->getBootstrapStateAsString().c_str());
657
658
659   if (! proc->getRpcMgr()->decodeEventIfDueToIRPC(ev)) {
660       signal_printf("%s[%d]:  unhandled sigstop/sigint\n", FILE__, __LINE__);
661      ev.type = evtProcessStop;
662   }
663   return true;
664 }
665
666 ///////////////////////////////////////////
667 /////      DebuggerInterface
668 ///////////////////////////////////////////
669
670 unsigned long dbi_thread_id = -1UL;
671 DebuggerInterface *global_dbi = NULL;
672 DebuggerInterface *getDBI()
673 {
674   if (global_dbi) return global_dbi;
675   global_dbi = new DebuggerInterface();
676   return global_dbi; 
677 }
678
679 void DBICallbackBase::dbi_signalCompletion(CallbackBase *cbb) 
680 {
681   DBICallbackBase *cb = (DBICallbackBase *) cbb;
682   cb->lock->_Lock(FILE__, __LINE__); 
683   cb->completion_signalled = true;
684   dbi_printf("%s[%d]:  DBICallback, signalling completion\n", FILE__, __LINE__);
685   cb->lock->_Broadcast(FILE__, __LINE__); 
686   cb->lock->_Unlock(FILE__, __LINE__); 
687 }
688
689 bool DBICallbackBase::waitForCompletion()
690 {
691   assert(lock->depth() == 1);
692
693   getDBI()->evt = type;
694
695   while (!completion_signalled) {
696     dbi_printf("%s[%d]:  waiting for completion of callback\n", FILE__, __LINE__);
697     if (0 != lock->_Broadcast(FILE__, __LINE__)) assert(0);
698     if (0 != lock->_WaitForSignal(FILE__, __LINE__)) assert(0);
699   }
700   dbi_printf("%s[%d]:  callback completion signalled\n", FILE__, __LINE__);
701   return true;
702 }
703
704 bool DebuggerInterface::waitNextEvent(DBIEvent &ev)
705 {
706   isReady = true;
707   dbi_printf("%s[%d]:  welcome to waitNextEvent for DebugInterface\n", FILE__, __LINE__);
708   dbilock._Lock(FILE__, __LINE__);
709   if (evt == dbiUndefined) {
710     dbi_printf("%s[%d]:  DebugInterface waiting for something to do\n", FILE__, __LINE__);
711     dbilock._WaitForSignal(FILE__, __LINE__);
712   }
713   //  got something
714   ev.type = evt;
715   dbi_printf("%s[%d]:  DebuggerInterface got event %s\n", FILE__, __LINE__, 
716              dbiEventType2str(evt));
717    //       eventType2str(ev.type));
718   dbilock._Unlock(FILE__, __LINE__);
719   return true;
720 }
721
722 bool DebuggerInterface::handleEventLocked(DBIEvent &ev)
723 {
724   assert(dbilock.depth());
725
726   evt = ev.type;
727
728   getMailbox()->executeCallbacks(FILE__, __LINE__);
729
730   //  event is handled, so set evt back to undefined. (our waiting criterion)
731   evt = dbiUndefined;
732   dbilock._Broadcast(FILE__, __LINE__);
733   return true;
734 }
735
736 bool PtraceCallback::operator()(int req, pid_t pid, Address addr,
737                                 Address data, int word_len)
738 {
739   //  No need to copy buffers since dbi callbacks will only be used in
740   //  the immediate context of the call;
741   lock->_Lock(FILE__, __LINE__);
742   req_ = req;
743   pid_ = pid;
744   addr_ = addr;
745   data_ = data;
746   word_len_  = word_len;
747   ret = (PTRACE_RETURN)0;
748   getMailbox()->executeOrRegisterCallback(this);
749   if (synchronous) {
750     dbi_printf("%s[%d]:  waiting for completion of callback\n", FILE__, __LINE__);
751     waitForCompletion();
752   }
753   lock->_Unlock(FILE__, __LINE__);
754   return true;
755 }
756
757 bool PtraceCallback::execute_real()
758 {
759   errno = 0;
760
761   ret = P_ptrace(req_, pid_, addr_, data_, word_len_);
762   if (errno) {
763     fprintf(stderr, "%s[%d][%s]:  ptrace(%d, pid = %d, %lx, %lx, %d) failed\n", 
764             FILE__, __LINE__, 
765            getThreadStr(getExecThreadID()), req_, pid_, addr_, data_, word_len_);
766     perror("ptrace error");
767   }
768   ptrace_errno = errno;
769   return true;
770 }
771
772 PTRACE_RETURN DebuggerInterface::ptrace(int req, pid_t pid, Address addr, 
773                               Address data, int word_len, int *ptrace_errno)
774 {
775   dbi_printf("%s[%d][%s]:  welcome to DebuggerInterface::ptrace()\n",
776           FILE__, __LINE__, getThreadStr(getExecThreadID()));
777   getBusy();
778
779   PTRACE_RETURN ret;
780   PtraceCallback *ptp = new PtraceCallback(&dbilock);
781   PtraceCallback &pt = *ptp;
782
783   pt.enableDelete(false);
784   pt(req, pid, addr, data, word_len);
785   ret = pt.getReturnValue();
786   if (ptrace_errno) 
787     *ptrace_errno = pt.getErrno();
788   pt.enableDelete();
789
790   releaseBusy();
791   return ret;
792 }
793
794
795
796 PTRACE_RETURN DBI_ptrace(int req, pid_t pid, Address addr, Address data, int *ptrace_errno, int word_len,  const char * /* file */, unsigned int /* line */) 
797 {
798   PTRACE_RETURN ret;
799   ret = getDBI()->ptrace(req, pid, addr, data, word_len, ptrace_errno);
800   return ret;
801 }
802
803 bool WaitPidNoBlockCallback::operator()(int *status)
804 {
805   lock->_Lock(FILE__, __LINE__);
806   status_ = status;
807   getMailbox()->executeOrRegisterCallback(this);
808   //DBIEvent ev(dbiWaitPid);
809   if (synchronous) {
810     dbi_printf("%s[%d]:  waiting for completion of callback\n", FILE__, __LINE__);
811     waitForCompletion();
812   }
813   lock->_Unlock(FILE__, __LINE__);
814   return true;
815 }
816
817 bool WaitPidNoBlockCallback::execute_real() 
818 {
819 #if defined (os_linux)
820   int wait_options = __WALL | WNOHANG;
821   ret = waitpid(-1, status_, wait_options);
822 #else
823   assert(0);
824 #endif
825   return true;
826 }
827
828 int DebuggerInterface::waitpidNoBlock(int *status)
829 {
830   dbi_printf("%s[%d][%s]:  welcome to DebuggerInterface::waitPidNoBlock()\n",
831           FILE__, __LINE__, getThreadStr(getExecThreadID()));
832   getBusy();
833
834   bool ret;
835   WaitPidNoBlockCallback *cbp = new WaitPidNoBlockCallback(&dbilock);
836   WaitPidNoBlockCallback &cb = *cbp;
837
838   cb.enableDelete(false);
839   cb(status);
840   ret = cb.getReturnValue();
841   cb.enableDelete();
842
843   releaseBusy();
844   return ret;
845 }
846
847 /*****************************************************************************
848  * forkNewProcess: starts a new process, setting up trace and io links between
849  *                the new process and the daemon
850  * Returns true if succesfull.
851  * 
852  * Arguments:
853  *   file: file to execute
854  *   dir: working directory for the new process
855  *   argv: arguments to new process
856  *   argp: environment variables for new process
857  *   inputFile: where to redirect standard input
858  *   outputFile: where to redirect standard output
859  *   traceLink: handle or file descriptor of trace link (read only)
860 //removed all ioLink related code for output redirection
861  *   ioLink: handle or file descriptor of io link (read only)
862  *   pid: process id of new process
863  *   tid: thread id for main thread (needed by WindowsNT)
864  *   procHandle: handle for new process (needed by WindowsNT)
865  *   thrHandle: handle for main thread (needed by WindowsNT)
866  ****************************************************************************/
867
868 bool SignalGenerator::forkNewProcess()
869 {
870   forkexec_printf("%s[%d][%s]:  welcome to forkNewProcess(%s)\n",
871           __FILE__, __LINE__, getThreadStr(getExecThreadID()), file.c_str());
872 #ifndef BPATCH_LIBRARY
873    int tracePipe[2];
874    int r = P_pipe(tracePipe);
875    if (r) {
876       // P_perror("socketpair");
877       pdstring msg = pdstring("Unable to create trace pipe for program '") + file +
878          pdstring("': ") + pdstring(strerror(errno));
879       showErrorCallback(68, msg);
880       return false;
881    }
882 #endif
883    errno = 0;
884
885    pid = fork();
886
887    if (pid != 0) {
888       // *** parent
889       startup_printf("%s[%d][%s]:  ForkNewProcessCallback::execute(%s): FORK PARENT\n",
890                __FILE__, __LINE__, getThreadStr(getExecThreadID()), file.c_str());
891
892
893 #if defined(os_linux)
894       if (!attachToChild(pid)) 
895         assert (0 && "failed to ptrace attach to child process");
896 #endif
897
898 #if (defined(BPATCH_LIBRARY) && !defined(alpha_dec_osf4_0))
899       /*
900        * On Irix, errno sometimes seems to have a non-zero value after
901        * the fork even though it succeeded.  For now, if we're using fork
902        * and not vfork, we will check the return code of fork to determine
903        * if there was error, instead of relying on errno (so make sure the
904        * condition for this section of code is the same as the condition for
905        * using fork instead of vfork above). - brb
906        */
907       if (pid == -1)
908 #else
909          if (errno)
910 #endif
911          {
912       fprintf(stderr, "%s[%d][%s]:  ForkNewProcessCallback::execute(%s): FORK ERROR\n",
913                __FILE__, __LINE__, getThreadStr(getExecThreadID()), file.c_str());
914             sprintf(errorLine, "Unable to start %s: %s\n", file.c_str(), 
915                     strerror(errno));
916             logLine(errorLine);
917             showErrorCallback(68, (const char *) errorLine);
918             return false; 
919          }
920
921 #ifndef BPATCH_LIBRARY
922       // parent never writes trace records; it only receives them.
923       P_close(tracePipe[1]);
924       traceLink = tracePipe[0];
925 #endif
926       return true;
927
928    } else if (pid == 0) {
929       // *** child
930
931 #ifndef BPATCH_LIBRARY
932       //setup output redirection to termWin
933       dup2(stdout_fd,1);
934       dup2(stdout_fd,2);
935
936       // Now that stdout is going to a pipe, it'll (unfortunately) be block
937       // buffered instead of the usual line buffered (when it goes to a tty).
938       // In effect the stdio library is being a little too clever for our
939       // purposes.  We don't want the "bufferedness" to change.  So we set it
940       // back to line-buffered.  The command to do this is setlinebuf(stdout)
941       // [stdio.h call] But we don't do it here, since the upcoming execve()
942       // would undo our work [execve keeps fd's but resets higher-level stdio
943       // information, which is recreated before execution of main()] So when
944       // do we do it?  In rtinst's DYNINSTinit (RTposix.c et al.)
945
946       // setup stderr for rest of exec try.
947       FILE *childError = P_fdopen(2, "w");
948
949       P_close(tracePipe[0]);
950
951       if (P_dup2(tracePipe[1], 3) != 3) {
952          fprintf(childError, "dup2 failed\n");
953          fflush(childError);
954          P__exit(-1);
955       }
956
957       /* close if higher */
958       if (tracePipe[1] > 3) P_close(tracePipe[1]);
959
960
961       if ((dir.length() > 0) && (P_chdir(dir.c_str()) < 0)) {
962          bpfatal("cannot chdir to '%s': %s\n", dir.c_str(), 
963                  strerror(errno));
964          P__exit(-1);
965       }
966 #endif
967 #if !defined(BPATCH_LIBRARY)
968       /* see if I/O needs to be redirected */
969       if (inputFile.length()) {
970          int fd = P_open(inputFile.c_str(), O_RDONLY, 0);
971          if (fd < 0) {
972             fprintf(childError, "stdin open of %s failed\n", inputFile.c_str());
973             fflush(childError);
974             P__exit(-1);
975          } else {
976             dup2(fd, 0);
977             P_close(fd);
978          }
979       }
980
981       if (outputFile.length()) {
982          int fd = P_open(outputFile.c_str(), O_WRONLY|O_CREAT, 0444);
983          if (fd < 0) {
984             fprintf(childError, "stdout open of %s failed\n", outputFile.c_str());
985             fflush(childError);
986             P__exit(-1);
987          } else {
988             dup2(fd, 1); // redirect fd 1 (stdout) to a copy of descriptor "fd"
989             P_close(fd); // not using descriptor fd any more; close it.
990          }
991       }
992 #endif
993
994 #if defined (BPATCH_LIBRARY)
995       // Should unify with (fancier) Paradyn handling
996       /* see if we should use alternate file decriptors */
997       if (stdin_fd != 0) dup2(stdin_fd, 0);
998       if (stdout_fd != 1) dup2(stdout_fd, 1);
999       if (stderr_fd != 2) dup2(stderr_fd, 2);
1000 #endif
1001
1002       // define our own session id so we don't get the mutators signals
1003 #ifndef rs6000_ibm_aix4_1
1004       setsid();
1005 #endif
1006       /* indicate our desire to be traced */
1007       errno = 0;
1008       OS::osTraceMe();
1009       if (errno != 0) {
1010          fprintf(stderr, 
1011                  "Could perform set PTRACE_TRACEME on forked process\n");
1012          fprintf(stderr, 
1013                  " Perhaps your executable doesn't have the exec bit set?\n");
1014          P__exit(-1);   // double underscores are correct
1015       }
1016
1017       char **envs = NULL;
1018       if (envp) {
1019           envs = new char*[envp->size() + 2]; // Also room for PARADYN_MASTER_INFO
1020           for(unsigned ei = 0; ei < envp->size(); ++ei)
1021               envs[ei] = P_strdup((*envp)[ei].c_str());
1022           envs[envp->size()] = NULL;
1023       }
1024       
1025 #ifndef BPATCH_LIBRARY
1026       // hand off info about how to start a paradynd to the application.
1027       //   used to catch rexec calls, and poe events.
1028       //
1029       char* paradynInfo = new char[1024];
1030       sprintf(paradynInfo, "PARADYN_MASTER_INFO= ");
1031       for (unsigned i=0; i < pd_process::arg_list.size(); i++) {
1032          const char *str;
1033
1034          str = P_strdup(pd_process::arg_list[i].c_str());
1035          if (!strcmp(str, "-l1")) {
1036             strcat(paradynInfo, "-l0");
1037          } else {
1038             strcat(paradynInfo, str);
1039          }
1040          strcat(paradynInfo, " ");
1041       }
1042
1043       if (envp) {
1044           envs[envp->size()] = P_strdup(paradynInfo);
1045           envs[envp->size() + 1] = NULL;
1046       } else {
1047           P_putenv(paradynInfo);
1048       }
1049 #endif
1050
1051       char **args;
1052       args = new char*[argv->size()+1];
1053       for (unsigned ai=0; ai<argv->size(); ai++)
1054          args[ai] = P_strdup((*argv)[ai].c_str());
1055       args[argv->size()] = NULL;
1056
1057      startup_printf("%s[%d]:  before exec\n", __FILE__, __LINE__);
1058      char argstr[2048];
1059      argstr[0] = '\0';
1060      for (unsigned int ji=0; ji < argv->size(); ji++) {
1061        pdstring &s = (*argv)[ji];
1062        sprintf(argstr, "%s %s", argstr, s.c_str());
1063      }
1064      startup_printf("%s[%d]:  EXEC: %s %s\n", __FILE__, __LINE__, file.c_str(), argstr);
1065       if (envp) {
1066           P_execve(file.c_str(), args, envs);
1067       }else
1068           P_execvp(file.c_str(), args);
1069
1070       sprintf(errorLine, "paradynd: execv failed, errno=%d\n", errno);
1071       logLine(errorLine);
1072     
1073       logLine(strerror(errno));
1074       {
1075          int i=0;
1076          while (args[i]) {
1077             sprintf(errorLine, "argv %d = %s\n", i, args[i]);
1078             logLine(errorLine);
1079             i++;
1080          }
1081       }
1082       {
1083           for(unsigned i = 0; envs[i] != NULL; ++i) {
1084               sprintf(errorLine, "envp %d = %s\n", i, envs[i]);
1085               logLine(errorLine);
1086           }
1087       }       
1088       P__exit(-1);
1089       // not reached
1090     
1091       return false;
1092    } 
1093    return false;
1094 }
1095
1096 #if !defined (os_linux)
1097 //  linux version of this function needs to use waitpid();
1098 bool SignalGenerator::waitForStopInline()
1099 {
1100    int timeout = 10 /*ms*/;
1101    assert(proc);
1102    assert(proc->getRepresentativeLWP());
1103
1104    while (proc->isRunning_()) {
1105        struct pollfd pfds[1]; 
1106
1107        pfds[0].fd = proc->getRepresentativeLWP()->status_fd();
1108        pfds[0].events = POLLPRI;
1109        pfds[0].revents = 0;
1110
1111        int num_selected_fds = poll(pfds, 1, timeout);
1112    }
1113
1114    return true;
1115
1116 }
1117 #endif
1118
1119 bool SignalGenerator::attachProcess()
1120 {
1121   assert(proc);
1122
1123     proc->creationMechanism_ = process::attached_cm;
1124     // We're post-main... run the bootstrapState forward
1125
1126 #if !defined(os_windows)
1127     proc->bootstrapState = initialized_bs;
1128 #else
1129     // We need to wait for the CREATE_PROCESS debug event.
1130     // Set to "begun" here, and fix up in the signal loop
1131     proc->bootstrapState = begun_bs;
1132 #endif
1133
1134   if (!proc->attach()) {
1135      proc->set_status( detached);
1136
1137      fprintf(stderr, "%s[%d] attach failing here: thread %s\n", FILE__, __LINE__,
1138              getThreadStr(getExecThreadID()));
1139      pdstring msg = pdstring("Warning: unable to attach to specified process: ")
1140                   + pdstring(getPid());
1141      showErrorCallback(26, msg.c_str());
1142      return false;
1143   }
1144
1145   startup_printf("%s[%d]: attached, getting current process state\n", FILE__, __LINE__);
1146
1147    // Record what the process was doing when we attached, for possible
1148    // use later.
1149    if (proc->isRunning_()) {
1150        startup_printf("[%d]: process running when attached, pausing...\n", getPid());
1151        proc->stateWhenAttached_ = running;
1152        proc->set_status(running);
1153
1154
1155        //  Now pause the process -- since we are running on the signal handling thread
1156        //  we cannot use the "normal" pause, which sends a signal and then waits
1157        //  for the signal handler to receive the trap.
1158        //  Need to do it all inline.
1159        if (!proc->stop_(false)) {
1160           fprintf(stderr, "%s[%d]:  failed to stop process\n", FILE__, __LINE__);
1161           return false;
1162        }
1163
1164        if (!waitForStopInline()) {
1165          fprintf(stderr, "%s[%d]:  failed to do initial stop of process\n", FILE__, __LINE__);
1166          return false;
1167        }
1168        proc->set_status(stopped);
1169    }
1170    else {
1171        startup_printf("%s[%d]: attached to previously paused process: %d\n", FILE__, __LINE__, getPid());
1172        proc->stateWhenAttached_ = stopped;
1173        //proc->set_status(stopped);
1174    }
1175
1176   return true;
1177 }
1178
1179 bool DebuggerInterface::writeDataSpace(pid_t pid, Address addr, int nbytes, Address data, int word_len, const char * /*file*/, unsigned int /*line*/) 
1180 {
1181   dbi_printf("%s[%d][%s]:  welcome to DebuggerInterface::writeDataSpace()\n",
1182           FILE__, __LINE__, getThreadStr(getExecThreadID()));
1183   getBusy();
1184
1185   bool ret;
1186   WriteDataSpaceCallback *cbp = new WriteDataSpaceCallback(&dbilock);
1187   WriteDataSpaceCallback &cb = *cbp;
1188
1189   cb.enableDelete(false);
1190   cb(pid, addr, nbytes, data, word_len);
1191   ret = cb.getReturnValue();
1192   cb.enableDelete();
1193
1194   releaseBusy();
1195   return ret;
1196 }
1197
1198 bool WriteDataSpaceCallback::operator()(pid_t pid, Address addr, int nelem, Address data, int word_len)
1199 {
1200   lock->_Lock(FILE__, __LINE__);
1201   pid_ = pid;
1202   addr_ = addr;
1203   nelem_ = nelem;
1204   data_ = data;
1205   word_len_ = word_len;
1206   getMailbox()->executeOrRegisterCallback(this);
1207   //DBIEvent ev(dbiWriteDataSpace);
1208   if (synchronous) {
1209     dbi_printf("%s[%d]:  waiting for completion of callback\n", FILE__, __LINE__);
1210     waitForCompletion();
1211   }
1212   lock->_Unlock(FILE__, __LINE__);
1213   return true;
1214 }
1215
1216 bool WriteDataSpaceCallback::execute_real()
1217 {
1218 #if defined (os_linux)
1219   ret =  getDBI()->bulkPtraceWrite((void *)addr_, nelem_, (void *)data_, pid_, word_len_);
1220 #else
1221   assert(0);
1222 #endif
1223   return true;
1224 }
1225
1226 bool DBI_writeDataSpace(pid_t pid, Address addr, int nelem, Address data, int word_len, const char *file, unsigned int line)
1227 {
1228   dbi_printf("%s[%d]: DBI_writeDataSpace(%d, %p, %d, %p, %d) called from %s[%d]\n", 
1229             FILE__, __LINE__, pid, (void *) addr, nelem, (void *) data, word_len,file,line);
1230   return getDBI()->writeDataSpace(pid, addr, nelem, data, word_len, file, line);
1231 }
1232
1233 bool ReadDataSpaceCallback::operator()(pid_t pid, Address addr, int nelem, Address data, int word_len)
1234 {
1235   lock->_Lock(FILE__, __LINE__);
1236   pid_ = pid;
1237   addr_ = addr;
1238   nelem_ = nelem;
1239   data_ = data;
1240   word_len_ = word_len;
1241   getMailbox()->executeOrRegisterCallback(this);
1242   if (synchronous) {
1243     dbi_printf("%s[%d]:  waiting for completion of callback\n", FILE__, __LINE__);
1244     waitForCompletion();
1245   }
1246   //DBIEvent ev(dbiReadDataSpace);
1247   lock->_Unlock(FILE__, __LINE__);
1248   return true;
1249 }
1250
1251 bool ReadDataSpaceCallback::execute_real()
1252 {
1253 #if defined (os_linux)
1254   ret =  getDBI()->bulkPtraceRead((void *)addr_, nelem_, (void *)data_, pid_, word_len_);
1255 #else
1256   assert(0);
1257 #endif
1258   return true;
1259 }
1260
1261 bool DebuggerInterface::readDataSpace(pid_t pid, Address addr, int nbytes, Address data, int word_len, const char * /*file*/, unsigned int /*line*/) 
1262 {
1263   dbi_printf("%s[%d][%s]:  welcome to DebuggerInterface::readDataSpace()\n",
1264           FILE__, __LINE__, getThreadStr(getExecThreadID()));
1265   getBusy();
1266   dbi_printf("%s[%d]:  got busy\n", FILE__, __LINE__);
1267
1268   bool ret;
1269   ReadDataSpaceCallback *cbp = new ReadDataSpaceCallback(&dbilock);
1270   ReadDataSpaceCallback &cb = *cbp;
1271
1272   cb.enableDelete(false);
1273   cb(pid, addr, nbytes, data, word_len);
1274   ret = cb.getReturnValue();
1275   cb.enableDelete();
1276
1277   releaseBusy();
1278   return ret;
1279 }
1280
1281 bool DBI_readDataSpace(pid_t pid, Address addr, int nelem, Address data, int word_len, const char *file, unsigned int line)
1282 {
1283   bool ret =  getDBI()->readDataSpace(pid, addr, nelem, data, word_len, file, line);
1284   if (!ret)
1285     fprintf(stderr, "%s[%d]:  readDataSpace at %s[%d] failing\n", FILE__, __LINE__, file, line);
1286   return ret;
1287 }
1288
1289 bool  OS::osKill(int pid) 
1290 {
1291   return (P_kill(pid,9)==0);
1292 }
1293
1294 void OS::unlink(char *file) 
1295 {
1296    unlink(file);
1297 }
1298 void OS::make_tempfile(char *s)
1299 {
1300    int result;
1301    result = mkstemp(s);
1302    if (result != -1)
1303       close(result);
1304 }
1305
1306 bool OS::execute_file(char *path) {
1307    int result;
1308    result = system(path);
1309    if (result == -1) {
1310       fprintf(stderr, "%s ",path);
1311       perror("couldn't be executed");
1312    }
1313    return (result != -1);
1314 }
1315
1316 #ifndef CASE_RETURN_STR
1317 #define CASE_RETURN_STR(x) case x: return #x
1318 #endif
1319 const char *dbiEventType2str(DBIEventType t)
1320 {
1321   switch(t) {
1322   CASE_RETURN_STR(dbiUndefined);
1323   CASE_RETURN_STR(dbiForkNewProcess);
1324   CASE_RETURN_STR(dbiPtrace);
1325   CASE_RETURN_STR(dbiWriteDataSpace);
1326   CASE_RETURN_STR(dbiReadDataSpace);
1327   CASE_RETURN_STR(dbiWaitPid);
1328   CASE_RETURN_STR(dbiGetFrameRegister);
1329   CASE_RETURN_STR(dbiSetFrameRegister);
1330   CASE_RETURN_STR(dbiCreateUnwindAddressSpace);
1331   CASE_RETURN_STR(dbiDestroyUnwindAddressSpace);
1332   CASE_RETURN_STR(dbiUPTCreate);
1333   CASE_RETURN_STR(dbiUPTDestroy);
1334   CASE_RETURN_STR(dbiInitFrame);
1335   CASE_RETURN_STR(dbiStepFrame);
1336   CASE_RETURN_STR(dbiIsSignalFrame);
1337   CASE_RETURN_STR(dbiWaitpid);
1338   CASE_RETURN_STR(dbiLastEvent);/* placeholder for the end of the list */
1339   };
1340   return "invalid";
1341 }
1342
1343 #include <sys/types.h>
1344 #include <dirent.h>
1345
1346
1347 /// Experiment: wait for the process we're attaching to to be created
1348 // before we return. 
1349
1350 SignalGenerator::SignalGenerator(char *idstr, pdstring file, int pid)
1351     : SignalGeneratorCommon(idstr, file, pid),
1352       waiting_for_stop(false) {
1353     char buffer[128];
1354     sprintf(buffer, "/proc/%d", pid);
1355
1356     // We wait until the entry has shown up in /proc. I believe this
1357     // is sufficient; unsure though.
1358
1359     // Not there after three seconds, give up.
1360     int timeout = 3;
1361     int counter = 0;
1362
1363     DIR *dirName = NULL;
1364     while ((dirName == NULL) && (counter < timeout)) {
1365         dirName = opendir(buffer);
1366         if (!dirName) {
1367             fprintf(stderr, "%s[%d]: waiting for dir %s creation\n", FILE__, __LINE__, buffer);
1368             sleep(1);
1369         }
1370         counter++;
1371     }
1372
1373     if (!dirName) {
1374       fprintf(stderr, "%s[%d]:  WARNING:  could not open dir %s\n", FILE__, __LINE__, buffer);
1375     }
1376     if (dirName)
1377       closedir(dirName);
1378