Problem 1:
[dyninst.git] / dyninstAPI / src / sol_proc.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 // Solaris-style /proc support
43
44 // $Id: sol_proc.C,v 1.80 2006/02/14 23:50:16 jaw Exp $
45
46 #ifdef AIX_PROC
47 #include <sys/procfs.h>
48 #else
49 #include <procfs.h>
50 #endif
51 #include <limits.h>
52 #include <poll.h>
53 #include <sys/types.h>  // for reading lwps out of proc
54 #include <dirent.h>     // for reading lwps out of proc
55 #include "common/h/headers.h"
56 #include "dyninstAPI/src/signalhandler.h"
57 #include "dyninstAPI/src/process.h"
58 #include "dyninstAPI/src/dyn_lwp.h"
59 #include "dyninstAPI/src/dyn_thread.h"
60 #include "dyninstAPI/src/stats.h"
61 #include "common/h/pathName.h" // for path name manipulation routines
62 #include "dyninstAPI/src/sol_proc.h"
63 #include "dyninstAPI_RT/h/dyninstAPI_RT.h" // for DYNINST_BREAKPOINT_SIGNUM
64
65 #include "function.h"
66 #include "mapped_object.h"
67 #include "mapped_module.h"
68 #include "dynamiclinking.h" //getlowestSO...
69
70 /*
71    osTraceMe is called after we fork a child process to set
72    a breakpoint on the exit of the exec system call.
73    When /proc is used, this breakpoint **will not** cause a SIGTRAP to 
74    be sent to the process. The parent should use PIOCWSTOP to wait for 
75    the child.
76 */
77 // Interesting problem: I've seen a race condition occur when
78 // we set the proc trace flags from the mutator before the
79 // mutatee. In this case, DON'T reset the flags if there
80 // is a stop on exec in effect.
81
82 void OS::osTraceMe(void) 
83 {
84     sysset_t *exitSet = SYSSET_ALLOC(getpid());
85     int bufsize = SYSSET_SIZE(exitSet) + sizeof(long);
86
87     char *buf = new char[bufsize];
88     long *bufptr = (long *)buf;
89     char procName[128];
90     
91     // Get the current set of syscalls
92     pstatus_t status;
93     sprintf(procName,"/proc/%d/status", (int) getpid());
94     int stat_fd = P_open(procName, O_RDONLY, 0);
95     if (pread(stat_fd, (void *)&status, sizeof(pstatus_t), 0) !=
96         sizeof(pstatus_t)) {
97         perror("osTraceMe::pread");
98         SYSSET_FREE(exitSet);
99         delete [] buf;
100         return;
101     }
102 #if defined(AIX_PROC) 
103     if (status.pr_sysexit_offset)
104         pread(stat_fd, exitSet, SYSSET_SIZE(exitSet), status.pr_sysexit_offset);
105     else // No syscalls are being traced 
106         premptysysset(exitSet);
107 #else
108     memcpy(exitSet, &(status.pr_sysexit), SYSSET_SIZE(exitSet));
109 #endif
110     P_close(stat_fd);
111
112     sprintf(procName,"/proc/%d/ctl", (int) getpid());
113     int fd = P_open(procName, O_WRONLY, 0);
114     if (fd < 0) {
115         perror("open");
116         SYSSET_FREE(exitSet);
117         delete [] buf;
118         return;
119     }
120     
121     /* set a breakpoint at the exit of exec/execve */
122     if (SYSSET_MAP(SYS_exec, getpid()) != -1) {
123         praddsysset(exitSet, SYSSET_MAP(SYS_exec, getpid()));
124     }
125     if (SYSSET_MAP(SYS_execve, getpid()) != -1) {
126         praddsysset(exitSet, SYSSET_MAP(SYS_execve, getpid()));
127     }
128     // Write out the command
129     *bufptr = PCSEXIT; bufptr++;
130     memcpy(bufptr, exitSet, SYSSET_SIZE(exitSet));
131     if (write(fd, buf, bufsize) != bufsize) {
132         perror("osTraceMe: PCSEXIT");
133         P__exit(-1); // must use _exit here.
134     }
135     
136
137     // AIX: do not close file descriptor or all changes are undone (?)
138     // My guess is we need to fiddle with the run on close/kill on 
139     // close bits. For now, leaving the FD open works.
140     //close(fd);    
141
142     SYSSET_FREE(exitSet);
143     delete [] buf;
144 }
145 /*
146  * DYN_LWP class
147  * Operations on LWP file descriptors, or the representative LWP
148  */
149
150 // determine if a process is running by doing low-level system checks, as
151 // opposed to checking the 'status_' member vrble.  May assume that attach()
152 // has run, but can't assume anything else.
153
154 bool dyn_lwp::isRunning() const {
155    procProcStatus_t theStatus;
156    
157    if (!get_status(&theStatus)) return false;
158
159    // Don't consider PR_ASLEEP to be stopped
160    long stopped_flags = PR_STOPPED | PR_ISTOP;
161
162    if (theStatus.pr_flags & stopped_flags)
163       return false;
164    else
165        return true;
166
167    
168 }
169
170 bool dyn_lwp::clearSignal() {
171     long command[2];
172     command[0] = PCRUN; command[1] = PRSTOP | PRCSIG;
173     if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
174         perror("clearSignal: PCRUN");
175         return false;
176     }
177     command[0] = PCWSTOP;
178     
179     if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
180         perror("clearSignal: PCWSTOP");
181         return false;
182     }
183     return true;
184 }
185
186 // Get the process running again. May do one or more of the following:
187 // 1) Continue twice to clear a signal
188 // 2) Restart an aborted system call
189 bool dyn_lwp::continueLWP_(int signalToContinueWith) {
190   procProcStatus_t status;
191   long command[2];
192   Address pc;  // PC at which we are trying to continue
193   // Check the current status
194   if (!get_status(&status)) {
195       bperr( "Failed to get LWP status\n");
196       return false;
197   }
198
199   if ((0==status.pr_flags & PR_STOPPED) && (0==status.pr_flags & PR_ISTOP)) {
200       bperr( "LWP not stopped\n");
201       return false;
202   }
203
204
205   // If the lwp is stopped on a signal we blip it (technical term).
206   // The process will re-stop (since we re-run with PRSTOP). At
207   // this point we continue it.
208   if ((status.pr_flags & PR_STOPPED)
209       && (status.pr_why == PR_SIGNALLED)) {
210       if (status.pr_what == SIGSTOP || 
211           status.pr_what == SIGINT ||
212           status.pr_what == SIGTRAP) {
213           clearSignal();
214       }
215   }
216
217   ptraceOps++; 
218   ptraceOtherOps++;
219
220
221   pc = (Address)(GETREG_PC(status.pr_reg));
222   if (stoppedInSyscall_ && pc == postsyscallpc_) {
223       if (!restartSyscall()) return false;
224   }
225   
226   command[0] = PCRUN;
227   if (signalToContinueWith == dyn_lwp::NoSignal)
228       command[1] = PRCSIG;  // clear the signal
229   else {
230       command[1] = 0;
231   }
232
233   // Continue the process the easy way
234  busy_retry:
235   errno = 0;
236   if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
237       if (errno == EBUSY) {
238         struct timeval slp;
239         slp.tv_sec = 0;
240         slp.tv_usec = 1 /*ms*/ *1000;
241         select(0, NULL, NULL, NULL, &slp);
242         fprintf(stderr, "%s[%d]: continueLWP_, ctl_fd is busy, trying again\n", FILE__, __LINE__);
243         goto busy_retry;
244       }
245       perror("continueLWP: PCRUN2");
246       return false;
247   }
248   
249   return true;
250   
251 }
252
253 // Abort a system call. Place a trap at the exit of the syscall in
254 // question, and run with the ABORT flag set. Wait for the trap
255 // to be hit and then return.
256
257 bool dyn_lwp::abortSyscall()
258 {
259     lwpstatus_t status;
260
261     // MT: aborting syscalls does not work. Maybe someone with better knowledge
262     // of Solaris can get it working. 
263     if(proc_->multithread_capable(true))
264        return false;
265
266     // We do not expect to recursively interrupt system calls.  We could
267     // probably handle it by keeping a stack of system call state.  But
268     // we haven't yet seen any reason to have this functionality.
269     assert(!stoppedInSyscall_);
270     stoppedInSyscall_ = true;
271     
272     if (!get_status(&status)) return false;
273
274     if (status.pr_syscall == 0 ||
275         status.pr_why == PR_SYSEXIT) {
276         // No work to be done
277         stoppedInSyscall_ = false;
278         return true;
279     }
280
281     if (((status.pr_flags & PR_STOPPED) == 0) &&
282         ((status.pr_flags & PR_ISTOP) == 0))
283         stop_();
284     
285
286     sysset_t* scexit = SYSSET_ALLOC(proc_->getPid());
287     sysset_t* scsavedexit = SYSSET_ALLOC(proc_->getPid());
288     sysset_t* scentry = SYSSET_ALLOC(proc_->getPid());
289     sysset_t* scsavedentry = SYSSET_ALLOC(proc_->getPid());
290     
291     // 1. Save the syscall number, registers, and blocked signals
292     stoppedSyscall_ = status.pr_syscall;
293 /*
294     memcpy(&(syscallreg_->theIntRegs), &(status.pr_reg), sizeof(prgregset_t));
295     memcpy(&(syscallreg_->theFpRegs), &(status.pr_fpreg), sizeof(prfpregset_t));
296 */   
297  
298     memcpy(&sighold_, &status.pr_lwphold, sizeof(proc_sigset_t));
299     
300 #ifdef i386_unknown_solaris2_5
301     // From Roger A. Faulkner at Sun (email unknown), 6/29/1997:
302     //
303     // On Intel and PowerPC machines, the system call trap instruction
304     // leaves the PC (program counter, instruction pointer) referring to
305     // the instruction that follows the system call trap instruction.
306     // On Sparc machines, the system call trap instruction leaves %pc
307     // referring to the system call trap instruction itself (the
308     // operating system increments %pc on exit from the system call).
309     //
310     // We have to reset the PC back to the system call trap instruction
311     // on Intel and PowerPC machines.
312     //
313     // This is 7 on Intel, 4 on PowerPC.
314     
315     // Note: On x86/Linux this should probably be 2 bytes, because Linux
316     // uses "int" to trap, not lcall.
317     
318     syscallreg_.theIntRegs[PC_REG] -= 7;
319 #endif
320     
321     // 2. Abort the system call
322     
323     // Save current syscall exit traps
324     proc_->get_entry_syscalls(scsavedentry);
325     proc_->get_exit_syscalls(scsavedexit);
326     
327     // Set process to trap on exit from this system call
328     premptyset(scentry);
329     premptyset(scexit);
330     praddset(scexit, stoppedSyscall_);
331     
332     proc_->set_entry_syscalls(scentry);
333     proc_->set_exit_syscalls(scexit);
334     
335     // Continue, aborting this system call and blocking all sigs except
336     // those needed by DynInst.
337     proc_sigset_t sigs;
338     prfillset(&sigs);
339     prdelset(&sigs, SIGTRAP);
340     prdelset(&sigs, SIGILL);
341     
342     // Set the signals to "ignore" and run, aborting the syscall
343 #if 0
344     int bufsize = sizeof(long) + sizeof(proc_sigset_t);
345     char buf[bufsize]; long *bufptr = (long *)buf;
346     *bufptr = PCSHOLD; bufptr++;
347     memcpy(bufptr, &sigs, sizeof(proc_sigset_t));
348
349     if (write(ctl_fd(), buf, bufsize) != bufsize) {
350         perror("abortSyscall: PCSHOLD"); return false;
351     }
352 #endif
353     long command[2];
354     
355     command[0] = PCRUN;
356     command[1] = PRSABORT;
357
358     if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
359         perror("abortSyscall: PCRUN"); return false;
360     }
361     
362     command[0] = PCWSTOP;
363     if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
364         perror("abortSyscall: PCWSTOP"); return false;
365     }
366     
367     // Note: We assume that is always safe to restart the call after
368     // aborting it.  We are wrong if it turns out that some
369     // interruptible system call can make partial progress before we
370     // abort it.
371     // We think this is impossible because the proc manpage says EINTR
372     // would be returned to the process if we didn't trap the syscall
373     // exit, and the manpages for interruptible system calls say an
374     // EINTR return value means no progress was made.
375     // If we are wrong, this is probably the place to decide whether
376     // and/or how the syscall should be restarted later.
377     
378     if (!get_status(&status)) return false;
379     
380     // Verify that we're stopped in the right place
381     if (((status.pr_flags & (PR_STOPPED|PR_ISTOP))
382          != (PR_STOPPED|PR_ISTOP))
383         || status.pr_why != PR_SYSEXIT
384         || status.pr_syscall != stoppedSyscall_) {
385         sprintf(errorLine,
386                 "warn: Can't step paused process out of syscall (Verify)\n");
387         logLine(errorLine);
388         return 0;
389     }
390
391
392     // Get a copy of the registers and save for when we restart the syscall
393     syscallreg_ = new dyn_saved_regs;
394     getRegisters(syscallreg_);
395
396     // Remember the current PC.  When we continue the process at this PC
397     // we will restart the system call.
398     postsyscallpc_ = (Address) GETREG_PC(syscallreg_->theIntRegs);
399     proc_->set_entry_syscalls(scsavedentry);
400     proc_->set_exit_syscalls(scsavedexit);
401     return true;
402 }
403
404 bool dyn_lwp::restartSyscall() {
405     if (!stoppedInSyscall_)
406         return true;
407     
408     // We interrupted a sleeping system call at some previous pause
409     // (i.e. stoppedInSyscall is true), we have not restarted that
410     // system call yet, and the current PC is the insn following
411     // the interrupted call.  It is time to restart the system
412     // call.
413     
414     // Note that when we make the process runnable, we ignore
415     // `flags', set if `hasNewPC' was true in the previous block,
416     // because we don't want its PC; we want the PC of the system
417     // call trap, which was saved in `syscallreg'.
418     if (!restoreRegisters(*syscallreg_)) return false;
419     delete syscallreg_;
420     syscallreg_ = NULL;
421     
422     // We are done -- the process is in the kernel for the system
423     // call, with the right registers values.  Make the process
424     // runnable, restoring its previously blocked signals.
425     // The signals were blocked as part of the abort mechanism.
426     stoppedInSyscall_ = false;
427 #if 0
428     int bufsize = sizeof(long) + sizeof(proc_sigset_t);
429     char buf[bufsize]; long *bufptr = (long *)buf;
430     *bufptr = PCSHOLD; bufptr++;
431     memcpy(bufptr, &sighold_, sizeof(proc_sigset_t));
432     
433     if (write(ctl_fd(), buf, bufsize) != bufsize) {
434         perror("continueLWP: PCSHOLD"); return false;
435     }
436 #endif
437     return true;
438 }
439
440
441
442 dyn_lwp *process::createRepresentativeLWP() {
443    // don't register the representativeLWP in the lwps since it's not a true
444    // lwp
445    representativeLWP = createFictionalLWP(0);
446    return representativeLWP;
447 }
448
449 // Stop the LWP in question
450 bool dyn_lwp::stop_() {
451   long command[2];
452   command[0] = PCSTOP;
453
454   if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
455       fprintf(stderr, "%s[%d][%s]: ", FILE__, __LINE__, getThreadStr(getExecThreadID()));
456       perror("pauseLWP: PCSTOP");
457       return false;
458   }
459
460   return true;
461 }
462
463 // Get the active frame (PC, FP/SP)
464 Frame dyn_lwp::getActiveFrame()
465 {
466    struct dyn_saved_regs regs;
467    bool status = getRegisters(&regs);
468    if(status == false)
469       return Frame();  
470
471    return Frame(GETREG_PC(regs.theIntRegs),
472                 GETREG_FP(regs.theIntRegs), 
473                 0, // SP unused
474                 proc_->getPid(), proc_, NULL, this, true);
475 }
476
477 // Get the registers of the stopped thread and return them.
478 bool dyn_lwp::getRegisters_(struct dyn_saved_regs *regs)
479 {
480     lwpstatus_t status;
481     if (!get_status(&status)) return false;
482
483     // Process must be stopped for register data to be correct.
484
485     assert((status.pr_flags & PR_STOPPED) || (status.pr_flags & PR_ISTOP)
486            || (status.pr_flags & PR_PCINVAL)  // eg. a trap at syscall exit
487            );
488
489     memcpy(&(regs->theIntRegs), &(status.pr_reg), sizeof(prgregset_t));
490     memcpy(&(regs->theFpRegs), &(status.pr_fpreg), sizeof(prfpregset_t));
491
492     return true;
493 }
494
495 void dyn_lwp::dumpRegisters()
496 {
497    dyn_saved_regs regs;
498    if (!getRegisters(&regs)) {
499      fprintf(stderr, "%s[%d]:  registers unavailable\n", FILE__, __LINE__);
500      return;
501    }
502  
503    fprintf(stderr, "PC:   %llx\n", GETREG_PC(regs.theIntRegs));
504    fprintf(stderr, "FP:   %llx\n", GETREG_FP(regs.theIntRegs));
505    fprintf(stderr, "INFO: %llx\n", GETREG_INFO(regs.theIntRegs));
506    //  plenty more register if we want to print em....
507 }
508
509 bool process::determineLWPs(pdvector<unsigned > &lwp_ids) {
510    char procdir[128];
511    snprintf(procdir, 128, "/proc/%d/lwp", getPid());
512    DIR *dirhandle = opendir(procdir);
513    if (dirhandle)
514    {
515       struct dirent *direntry;
516       while((direntry = readdir(dirhandle)) != NULL) {
517          unsigned lwp_id = atoi(direntry->d_name);
518          if (!lwp_id) continue;
519          lwp_ids.push_back(lwp_id);
520       }
521       closedir(dirhandle);
522    }
523    return true;
524 }
525
526 // Restore registers saved as above.
527 bool dyn_lwp::restoreRegisters_(const struct dyn_saved_regs &regs)
528 {
529     lwpstatus_t status;
530     get_status(&status);
531
532     // The fact that this routine can be shared between solaris/sparc and
533     // solaris/x86 is just really, really cool.  /proc rules!
534     const int regbufsize = sizeof(long) + sizeof(prgregset_t);
535     char regbuf[regbufsize]; long *regbufptr = (long *)regbuf;
536     *regbufptr = PCSREG; regbufptr++;
537     memcpy(regbufptr, &(regs.theIntRegs), sizeof(prgregset_t));
538     int writesize;
539 try_again:
540     errno = 0;
541     writesize = write(ctl_fd(), regbuf, regbufsize);
542     
543     if (writesize != regbufsize) {
544         if (errno == EBUSY) {
545           fprintf(stderr, "%s[%d]:  busy fd\n", FILE__, __LINE__);
546           struct timeval slp;
547           slp.tv_sec = 0;
548           slp.tv_usec = 1 /*ms*/ *1000;
549           select(0, NULL, NULL, NULL, &slp);
550           goto try_again;
551         }
552         perror("restoreRegisters: GPR write");
553         return false;
554     }
555     const int fpbufsize = sizeof(long) + sizeof(prfpregset_t);
556     char fpbuf[fpbufsize]; long *fpbufptr = (long *)fpbuf;
557     *fpbufptr = PCSFPREG; fpbufptr++;
558     memcpy(fpbufptr, &(regs.theFpRegs), sizeof(prfpregset_t));
559     
560     if (write(ctl_fd(), fpbuf, fpbufsize) != fpbufsize) {
561         perror("restoreRegisters FPR write");
562         return false;
563     }
564     return true;
565
566 }
567
568 // Determine if the LWP in question is in a system call.
569 bool dyn_lwp::executingSystemCall()
570 {
571   lwpstatus_t status;
572   if (!get_status(&status)) return false;
573   // Old-style
574
575   if (status.pr_syscall > 0 && // If we're in a system call
576       status.pr_why != PR_SYSEXIT) {
577       stoppedSyscall_ = status.pr_syscall;
578       if (abortSyscall()) {
579           // Not in a syscall any more :)
580           return false;
581       }
582       else {
583           return true;
584       }
585   }
586   
587 #if defined(AIX_PROC)
588   if (status.pr_why == PR_SIGNALLED &&
589       status.pr_what == SIGSTOP) {
590       // We can't operate on a process in SIGSTOP, so clear it
591       proc()->getRepresentativeLWP()->clearSignal();
592   }
593   
594   // I've seen cases where we're apparently not in a system
595   // call, but can't write registers... we'll label this case
596   // a syscall for now
597   const int regbufsize = sizeof(long) + sizeof(prgregset_t);
598   char regbuf[regbufsize]; long *regbufptr = (long *)regbuf;
599   *regbufptr = PCSREG; regbufptr++;
600   memcpy(regbufptr, &(status.pr_reg), sizeof(prgregset_t));
601   int writesize = write(ctl_fd(), regbuf, regbufsize);
602   if (writesize == -1) {
603       return true;
604   }
605 #endif
606   return false;
607 }
608
609
610 bool dyn_lwp::changePC(Address addr, struct dyn_saved_regs *regs)
611 {
612     // Don't change the contents of regs if given
613     dyn_saved_regs local;
614     if (!regs) {
615         getRegisters(&local);
616     } else {
617         memcpy(&local, regs, sizeof(struct dyn_saved_regs));
618     }
619
620     // Compatibility: we don't use PCSVADDR on Solaris because AIX doesn't 
621     // support it
622     // nPC MUST be set before PC! On platforms that don't have it,
623     // nPC will be overwritten by the PC write
624     GETREG_nPC(local.theIntRegs) = addr + instruction::size();
625     GETREG_PC(local.theIntRegs) = addr;
626
627     if (!restoreRegisters(local))
628         return false;
629     
630     dyn_saved_regs check;
631     getRegisters(&check);
632     assert(GETREG_PC(local.theIntRegs) == GETREG_PC(check.theIntRegs));
633
634     return true;
635 }
636
637 #if defined(i386_unknown_solaris2_5)
638 bool process::changeIntReg(int reg, Address val) {
639    assert(status_ == stopped); // /proc will require this
640
641    prgregset_t theIntRegs;
642    dyn_lwp *replwp = getRepresentativeLWP();
643    if (ioctl(replwp->get_fd(), PIOCGREG, &theIntRegs) == -1) {
644       perror("dyn_lwp::changeIntReg");
645       if (errno == EBUSY) {
646          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
647          assert(false);
648       }
649       return false;
650    }
651
652    theIntRegs[reg] = val;
653
654    if (ioctl(replwp->get_fd(), PIOCSREG, &theIntRegs) == -1) {
655       perror("process::changeIntReg PIOCSREG");
656       if (errno == EBUSY) {
657          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
658          assert(false);
659       }
660       return false;
661    }
662
663    return true;
664 }
665 #endif
666
667 // Utility function: get the appropriate lwpstatus_t struct
668 bool dyn_lwp::get_status(lwpstatus_t *status) const
669 {
670     if(!is_attached()) {
671         return false;
672     }
673     
674    if (lwp_id_) {
675       // We're using an lwp file descriptor, so get directly
676       if (pread(status_fd_, 
677                 (void *)status, 
678                 sizeof(lwpstatus_t), 0) != sizeof(lwpstatus_t)) {
679           // When we fork a LWP file might disappear.
680           if (errno != ENOENT) {
681               perror("dyn_lwp::get_status");            
682           }
683          return false;
684       }
685    }
686    else {
687       // No lwp, so we get the whole thing and pick it out
688       pstatus_t procstatus;
689       if (!proc_->get_status(&procstatus)) {
690          return false;
691       }
692       memcpy(status, &(procstatus.pr_lwp), sizeof(lwpstatus_t));
693    }
694    return true;
695 }
696
697 // Read the value of a particular register
698 Address dyn_lwp::readRegister(Register reg)
699 {
700     Address result;
701     dyn_saved_regs regs;
702     getRegisters(&regs);
703     result = GETREG_GPR(regs.theIntRegs, reg);
704     return result;
705 }
706
707 bool dyn_lwp::realLWP_attach_() {
708    char temp[128];
709    sprintf(temp, "/proc/%d/lwp/%d/lwpctl", (int)proc_->getPid(), lwp_id_);
710    ctl_fd_ = P_open(temp, O_WRONLY, 0);
711    if (ctl_fd_ < 0) perror("Opening lwpctl");
712    sprintf(temp, "/proc/%d/lwp/%d/lwpstatus", (int)proc_->getPid(),lwp_id_);
713    status_fd_ = P_open(temp, O_RDONLY, 0);    
714    if (status_fd_ < 0) perror("Opening lwpstatus");
715
716    return true;
717 }
718
719 bool dyn_lwp::representativeLWP_attach_() 
720 {
721 #if defined(os_aix)
722     // Wait a sec; we often outrun process creation.
723     sleep(2);
724 #endif
725    /*
726      Open the /proc file corresponding to process pid
727    */
728
729    char temp[128];
730    // Open the process-wise handles
731    sprintf(temp, "/proc/%d/ctl", getPid());
732
733    if (!waitForFileToExist(temp, 5 /*seconds */)) {
734      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
735      return false;
736    }
737    ctl_fd_ = openFileWhenNotBusy(temp, O_WRONLY | O_EXCL, 0, 5/*seconds*/);
738    //ctl_fd_ = P_open(temp, O_WRONLY | O_EXCL, 0);    
739    if (ctl_fd_ < 0) perror("Opening (LWP) ctl");
740    
741    sprintf(temp, "/proc/%d/status", getPid());
742    if (!waitForFileToExist(temp, 5 /*seconds */)) {
743      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
744      return false;
745    }
746    status_fd_ = openFileWhenNotBusy(temp, O_RDONLY, 0, 5/*seconds*/);
747    //status_fd_ = P_open(temp, O_RDONLY, 0);    
748    if (status_fd_ < 0) perror("Opening (LWP) status");
749
750    as_fd_ = INVALID_HANDLE_VALUE;
751    sprintf(temp, "/proc/%d/as", getPid());
752    if (!waitForFileToExist(temp, 5 /*seconds */)) {
753      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
754      return false;
755    }
756    as_fd_ = openFileWhenNotBusy(temp, O_RDWR, 0, 5/*seconds*/);
757    //as_fd_ = P_open(temp, O_RDWR, 0);
758    if (as_fd_ < 0) perror("Opening as fd");
759
760 #if !defined(AIX_PROC)
761    sprintf(temp, "/proc/%d/auxv", getPid());
762    if (!waitForFileToExist(temp, 5 /*seconds */)) {
763      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
764      return false;
765    }
766    auxv_fd_ = openFileWhenNotBusy(temp, O_RDONLY, 0, 5/*seconds*/);
767    //auxv_fd_ = P_open(temp, O_RDONLY, 0);
768    if (auxv_fd_ < 0) perror("Opening auxv fd");
769 #else
770    // AIX doesn't have the auxv file
771    auxv_fd_ = INVALID_HANDLE_VALUE;
772 #endif
773
774    sprintf(temp, "/proc/%d/map", getPid());
775    if (!waitForFileToExist(temp, 5 /*seconds */)) {
776      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
777      return false;
778    }
779    map_fd_ = openFileWhenNotBusy(temp, O_RDONLY, 0, 5/*seconds*/);
780    //map_fd_ = P_open(temp, O_RDONLY, 0);
781    if (map_fd_ < 0) perror("map fd");
782
783    sprintf(temp, "/proc/%d/psinfo", getPid());
784    if (!waitForFileToExist(temp, 5 /*seconds */)) {
785      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
786      return false;
787    }
788    ps_fd_ = openFileWhenNotBusy(temp, O_RDONLY, 0, 5/*seconds*/);
789    //ps_fd_ = P_open(temp, O_RDONLY, 0);
790    if (ps_fd_ < 0) perror("Opening ps fd");
791
792   //  didn't we already open this file??
793    sprintf(temp, "/proc/%d/status", getPid());
794    if (!waitForFileToExist(temp, 5 /*seconds */)) {
795      fprintf(stderr, "%s[%d]:  cannot attach because %s does not exist\n", FILE__, __LINE__, temp);
796      return false;
797    }
798    status_fd_ = openFileWhenNotBusy(temp, O_RDONLY, 0, 5/*seconds*/);
799    //status_fd_ = P_open(temp, O_RDONLY, 0);
800    if (status_fd_ < 0) perror("Opening status fd");
801
802    lwpstatus_t status;
803
804    // special for aix: we grab the status and clear the STOP
805    // signal (if any)
806    is_attached_ = true;
807    get_status(&status);
808
809
810    if (status.pr_why == PR_SIGNALLED &&
811        status.pr_what == SIGSTOP) {
812        clearSignal();
813    }
814
815   // Abort a system call if we're in it
816   abortSyscall();
817
818    return true;
819 }
820
821 // Close FDs opened above
822 void dyn_lwp::realLWP_detach_()
823 {
824    assert(is_attached());  // dyn_lwp::detach() shouldn't call us otherwise
825       
826    // First we want to clear any signal which might be pending
827    // for the process. Otherwise, when we detach the process has
828    // a signal sent that it may have no clue about
829    // But we can't do that here -- all FDs associated with the process
830    // are closed. 
831    if (ctl_fd_ != INVALID_HANDLE_VALUE)
832       P_close(ctl_fd_);
833    if (status_fd_ != INVALID_HANDLE_VALUE)
834       P_close(status_fd_);
835    is_attached_ = false;
836 }
837
838 // Close FDs opened above
839 void dyn_lwp::representativeLWP_detach_()
840 {
841    assert(is_attached());  // dyn_lwp::detach() shouldn't call us otherwise
842       
843    // First we want to clear any signal which might be pending
844    // for the process. Otherwise, when we detach the process has
845    // a signal sent that it may have no clue about
846    // But we can't do that here -- all FDs associated with the process
847    // are closed.
848    if (ctl_fd_ != INVALID_HANDLE_VALUE)
849       P_close(ctl_fd_);
850    if (status_fd_ != INVALID_HANDLE_VALUE)
851       P_close(status_fd_);
852    if (as_fd_ != INVALID_HANDLE_VALUE)
853       P_close(as_fd_);
854    if (ps_fd_ != INVALID_HANDLE_VALUE)
855       P_close(ps_fd_);
856    is_attached_ = false;
857 }
858
859 /*
860  * Process-wide /proc operations
861  */
862
863 bool process::setProcessFlags()
864 {
865     long command[2];
866
867     // Unset all flags
868     command[0] = PCUNSET;
869     command[1] = PR_BPTADJ | PR_MSACCT | PR_RLC | PR_KLC | PR_FORK;
870
871     dyn_lwp *replwp = getRepresentativeLWP();
872     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
873         perror("installProcessFlags: PRUNSET");
874         return false;
875     }
876     command[0] = PCSET;
877
878     long flags = PR_BPTADJ | PR_MSACCT | PR_FORK;
879
880     command[1] = flags;
881
882     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
883         perror("installProcessFlags: PCSET");
884         return false;
885     }
886
887    // step 2) /proc PIOCSTRACE: define which signals should be
888    // forwarded to daemon These are (1) SIGSTOP and (2) either
889    // SIGTRAP (sparc) or SIGILL (x86), to implement inferiorRPC
890    // completion detection.
891    // Also detect SIGCONT so that we know if a user has restarted
892    // an application.
893   
894    proc_sigset_t sigs;
895     
896    premptyset(&sigs);
897    praddset(&sigs, SIGSTOP);
898    praddset(&sigs, DYNINST_BREAKPOINT_SIGNUM);
899     
900    praddset(&sigs, SIGTRAP);
901     
902    praddset(&sigs, SIGCONT);
903    praddset(&sigs, SIGBUS);
904    praddset(&sigs, SIGSEGV);
905    praddset(&sigs, SIGILL);
906     
907    const int bufsize = sizeof(long) + sizeof(proc_sigset_t);
908    char buf[bufsize]; 
909    long *bufptr = (long *) buf;
910    *bufptr = PCSTRACE;
911    bufptr++;
912    memcpy(bufptr, &sigs, sizeof(proc_sigset_t));
913
914    if(write(replwp->ctl_fd(), buf, bufsize) != bufsize) {
915       perror("attach: PCSTRACE");
916       return false;
917    }
918
919
920     return true;
921 }
922
923 bool process::unsetProcessFlags()
924 {
925     long command[2];
926
927     if (!isAttached()) return false;
928     // Unset all flags
929     command[0] = PCUNSET;
930     command[1] = PR_BPTADJ | PR_MSACCT | PR_RLC | PR_KLC | PR_FORK;
931
932     dyn_lwp *replwp = getRepresentativeLWP();
933     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
934         perror("unsetProcessFlags: PRUNSET");
935         return false;
936     }
937
938     proc_sigset_t sigs;
939     premptyset(&sigs);
940     const int sigbufsize = sizeof(long) + sizeof(proc_sigset_t);
941     char sigbuf[sigbufsize]; long *sigbufptr = (long *)sigbuf;
942
943     sigbufptr = (long *)sigbuf;
944     *sigbufptr = PCSTRACE;
945     if (write(replwp->ctl_fd(), sigbuf, sigbufsize) != sigbufsize) {
946         perror("unsetProcessFlags: PCSTRACE");
947         return false;
948     }
949     
950     return true;
951 }
952
953 // AIX requires us to re-open the process-wide handles after
954 // an exec call
955
956 #if defined(AIX_PROC)
957 void dyn_lwp::reopen_fds() {
958         // Reopen the process-wide handles
959     char temp[128];
960
961     P_close(as_fd_);
962     sprintf(temp, "/proc/%d/as", getPid());
963     as_fd_ = P_open(temp, O_RDWR, 0);
964     if (as_fd_ <= 0) perror("Opening as fd");
965 #if !defined(AIX_PROC)
966     P_close(auxv_fd_);
967     sprintf(temp, "/proc/%d/auxv", getPid());
968     auxv_fd_ = P_open(temp, O_RDONLY, 0);
969     if (auxv_fd_ <= 0) perror("Opening auxv fd");
970 #else
971     // AIX doesn't have the auxv file
972     auxv_fd_ = INVALID_HANDLE_VALUE;
973 #endif
974
975     P_close(map_fd_);
976     sprintf(temp, "/proc/%d/map", getPid());
977     map_fd_ = P_open(temp, O_RDONLY, 0);
978     if (map_fd_ <= 0) perror("map fd");
979
980     P_close(ps_fd_);
981     sprintf(temp, "/proc/%d/psinfo", getPid());
982     ps_fd_ = P_open(temp, O_RDONLY, 0);
983     if (ps_fd_ <= 0) perror("Opening ps fd");
984
985     P_close(status_fd_);
986     sprintf(temp, "/proc/%d/status", getPid());
987     status_fd_ = P_open(temp, O_RDONLY, 0);
988     if (status_fd_ <= 0) perror("Opening status fd");
989 }
990 #endif
991
992 bool process::isRunning_() const {
993     // We can key off the representative LWP
994     return getRepresentativeLWP()->isRunning();
995 }
996
997 /*
998    terminate execution of a process
999  */
1000 terminateProcStatus_t process::terminateProc_()
1001 {
1002   // Two kill methods: polite and unpolite. Not sure why we use
1003   // polite, but hey...
1004
1005   // Polite: we're attached, and use a /proc command.
1006   // Unpolite: we're not attached, and kill -9
1007
1008   if (isAttached()) {
1009     // these next two lines are a hack used to get the poll call initiated
1010     // by checkForAndHandleProcessEvents() in process::terminateProc to
1011     // still check process for events if it was previously stopped
1012     if(status() == stopped)
1013       status_ = running;
1014
1015     long command[2];
1016     command[0] = PCKILL;
1017     command[1] = SIGKILL;
1018     dyn_lwp *cntl_lwp = getRepresentativeLWP();
1019     if (cntl_lwp) {
1020       if (write(cntl_lwp->ctl_fd(), 
1021                 command, 2*sizeof(long)) != 2*sizeof(long)) {
1022         perror("terminateProc: PCKILL");
1023         // TODO: what gets returned if the process is already dead?
1024         // proc man page doesn't say.
1025         return terminateFailed;
1026       }
1027       return terminateSucceeded;
1028     }
1029     else {
1030       // Uh...
1031       return terminateFailed;
1032     }
1033   }
1034   else {
1035     // We may be detached. Go for it the old-fashioned way.
1036     if (kill( getPid(), SIGKILL )) {
1037         return terminateFailed;
1038     }
1039     else {
1040       // alreadyTerminated... since we don't want to wait
1041       // for a "I'm dead" message.
1042       return alreadyTerminated;
1043     }
1044   }
1045   assert(0 && "Unreachable");
1046   return terminateFailed;
1047 }
1048
1049 bool dyn_lwp::waitUntilStopped() {
1050    return true;
1051 }
1052
1053 bool process::waitUntilStopped() {
1054    return true;
1055 }
1056
1057 bool dyn_lwp::writeTextWord(caddr_t inTraced, int data) {
1058    //  cerr << "writeTextWord @ " << (void *)inTraced << endl; cerr.flush();
1059    bool ret =  writeDataSpace(inTraced, sizeof(int), (caddr_t) &data);
1060    if (!ret) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n",
1061                      __FILE__, __LINE__, getThreadStr(getExecThreadID()));
1062         assert(ret);
1063    return ret;
1064 }
1065
1066 bool dyn_lwp::writeTextSpace(void *inTraced, u_int amount, const void *inSelf)
1067 {
1068    //  cerr << "writeTextSpace pid=" << getPid() << ", @ " << (void *)inTraced
1069    //       << " len=" << amount << endl; cerr.flush();
1070    bool ret =  writeDataSpace(inTraced, amount, inSelf);
1071    if (!ret) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n",
1072                      __FILE__, __LINE__, getThreadStr(getExecThreadID()));
1073         assert(ret);
1074    return ret;
1075 }
1076
1077 bool dyn_lwp::readTextSpace(void *inTraced, u_int amount, const void *inSelf) {
1078    return readDataSpace(inTraced, amount, const_cast<void *>(inSelf));
1079 }
1080
1081 bool dyn_lwp::writeDataSpace(void *inTraced, u_int amount, const void *inSelf)
1082 {
1083    //fprintf(stderr, "%s[%d][%s]:  writeDataSpace: %p\n", __FILE__, __LINE__, getThreadStr(getExecThreadID()), inTraced);
1084    ptraceOps++; ptraceBytes += amount;
1085
1086    //  cerr << "process::writeDataSpace_ pid " << getPid() << " writing "
1087    //       << amount << " bytes at loc " << inTraced << endl;
1088 #if defined(BPATCH_LIBRARY)
1089 #if defined (sparc_sun_solaris2_4)
1090    if(proc_->collectSaveWorldData &&  ((Address) inTraced) >
1091       proc_->getDyn()->getlowestSObaseaddr() ) {
1092        mapped_object *sh_obj = NULL;
1093        bool result = false;
1094        const pdvector<mapped_object *> &objs = proc_->mappedObjects();
1095        for (unsigned i = 0; i < objs.size(); i++) {
1096            sh_obj = objs[i];
1097            result = sh_obj->isinText((Address) inTraced);
1098            if( result  ){
1099                /*       bperr(" write at %lx in %s amount %x insn: %x \n", 
1100                         (off_t)inTraced, sh_obj->getName().c_str(), amount,
1101                         *(unsigned int*) inSelf);
1102                         */      
1103                sh_obj->setDirty();      
1104                break;
1105            }
1106        }
1107    }
1108 #endif
1109 #endif
1110    off64_t loc;
1111    // Problem: we may be getting a address with the high bit
1112    // set. So how to convince the system that it's not negative?
1113    loc = (off64_t) ((unsigned) inTraced);
1114
1115    errno = 0;
1116
1117    int written = pwrite64(as_fd(), inSelf, amount, loc);
1118    if(written != (int)amount) {
1119       fprintf(stderr, "%s[%d][%s]:  writeDataSpace: %s\n", __FILE__, __LINE__, getThreadStr(getExecThreadID()), strerror(errno));
1120       perror("writeDataSpace");
1121       assert(0);
1122       return false;
1123    }
1124     
1125    return true;
1126 }
1127
1128 bool dyn_lwp::readDataSpace(const void *inTraced, u_int amount, void *inSelf) {
1129     ptraceOps++; ptraceBytes += amount;
1130
1131     off64_t loc;
1132     loc = (off64_t) ((unsigned) inTraced);
1133
1134     int res = pread64(as_fd(), inSelf, amount, loc);
1135     //fprintf(stderr, "%s[%d][%s]:  %d = readDataSpace(%p, amt=%d, %p)\n",
1136     //       FILE__, __LINE__, getThreadStr(getExecThreadID()), res,
1137     //       inTraced, amount, inSelf);
1138     if (res != (int) amount) {
1139         perror("readDataSpace");
1140         bperr( "From 0x%x (mutator) to 0x%x (mutatee), %d bytes, got %d\n",
1141                 (int)inSelf, (int)inTraced, amount, res);
1142         return false;
1143     }
1144     return true;
1145 }
1146
1147
1148 bool process::get_status(pstatus_t *status) const
1149 {
1150     if (!isAttached()) return false;
1151     if (!getRepresentativeLWP()->is_attached()) return false;
1152    
1153     int readfd = getRepresentativeLWP()->status_fd();
1154     size_t sz_read = pread(readfd, (void *)status, sizeof(pstatus_t), 0);
1155     if (sz_read != sizeof(pstatus_t)) {
1156         fprintf(stderr, "[%s][%d]: process::get_status: %s\n", FILE__, __LINE__, strerror(errno));
1157         fprintf(stderr, "[%s][%d]: pread returned %d instead of %d, fd = %d\n", FILE__, __LINE__, sz_read, sizeof(pstatus_t), readfd);
1158         perror("pread");
1159         return false;
1160     }
1161     
1162     return true;
1163 }
1164
1165 bool process::set_entry_syscalls(sysset_t *entry)
1166 {
1167     if (!isAttached()) return false;
1168     
1169     int bufentrysize = sizeof(long) + SYSSET_SIZE(entry);
1170     char *bufentry = new char[bufentrysize]; long *bufptr = (long *)bufentry;
1171     
1172     // Write entry syscalls
1173     *bufptr = PCSENTRY; bufptr++;
1174     memcpy(bufptr, entry, SYSSET_SIZE(entry));
1175
1176     dyn_lwp *replwp = getRepresentativeLWP();
1177
1178     if (write(replwp->ctl_fd(), bufentry, bufentrysize) != bufentrysize){
1179        delete [] bufentry;
1180        return false;
1181     }
1182
1183     delete [] bufentry;
1184     return true;    
1185 }
1186
1187 bool process::set_exit_syscalls(sysset_t *exit)
1188 {
1189     if (!isAttached()) return false;
1190     
1191     int bufexitsize = sizeof(long) + SYSSET_SIZE(exit);
1192     char *bufexit = new char[bufexitsize]; long *bufptr = (long *)bufexit;
1193     *bufptr = PCSEXIT; bufptr++;
1194     memcpy(bufptr, exit, SYSSET_SIZE(exit));
1195
1196     dyn_lwp *replwp = getRepresentativeLWP();        
1197     if (write(replwp->ctl_fd(), bufexit, bufexitsize) != bufexitsize){
1198        delete [] bufexit;
1199        return false;
1200     }
1201     delete [] bufexit;
1202     return true;    
1203 }
1204
1205 syscallTrap *process::trapSyscallExitInternal(Address syscall)
1206 {
1207     syscallTrap *trappedSyscall = NULL;
1208
1209     // First, the cross-platform bit. If we're already trapping
1210     // on this syscall, then increment the reference counter
1211     // and return
1212
1213     for (unsigned iter = 0; iter < syscallTraps_.size(); iter++) {
1214         if (syscallTraps_[iter]->syscall_id == syscall) {
1215             trappedSyscall = syscallTraps_[iter];
1216             break;
1217         }
1218     }
1219
1220     if (trappedSyscall) {
1221         // That was easy...
1222         trappedSyscall->refcount++;
1223         //bperr( "Bumping refcount for syscall %d to %d\n",
1224         //        (int)trappedSyscall->syscall_id, trappedSyscall->refcount);
1225         return trappedSyscall;
1226     }
1227     else {
1228         // Okay, we haven't trapped this system call yet.
1229         // Things to do:
1230         // 1) Get the original value
1231         // 2) Place a trap
1232         // 3) Create a new syscallTrap object and return it
1233         trappedSyscall = new syscallTrap;
1234         trappedSyscall->refcount = 1;
1235         trappedSyscall->syscall_id = (int) syscall;
1236
1237         //bperr( "  trapping syscall %d for 1st time (%d)\n",
1238         //       (int)trappedSyscall->syscall_id, trappedSyscall->refcount);
1239         
1240 #if defined(AIX_PROC) 
1241         // AIX does some weird things, as we can't modify a thread
1242         // at a system call exit -- this means that using /proc
1243         // doesn't get us anywhere.
1244         // The "address" of the system call is actually the LWP
1245         // in the call
1246         dyn_lwp *syslwp = getLWP((unsigned) syscall);
1247         Frame frame = syslwp->getActiveFrame();
1248         Frame callerFrame = frame.getCallerFrame();
1249         
1250         Address origLR;
1251         readDataSpace((void *)(callerFrame.getFP() + 8),
1252                       sizeof(Address),
1253                       (void *)&origLR, false);
1254         trappedSyscall->origLR = origLR;
1255         
1256         Address trapAddr = inferiorMalloc(instruction::size());
1257         trappedSyscall->trapAddr = trapAddr;
1258
1259         codeGen gen(1);
1260         instruction::generateTrap(gen);
1261
1262         bool ret = writeDataSpace((void *)trapAddr, 
1263                        gen.used(),
1264                        gen.start_ptr());
1265         if (!ret) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n",
1266                           __FILE__, __LINE__, getThreadStr(getExecThreadID()));
1267         writeDataSpace((void *)(callerFrame.getFP() + 8), 
1268                        sizeof(Address),
1269                        (void *)&trapAddr);
1270         if (!ret) fprintf(stderr, "%s[%d][%s]:  writeDataSpace failed\n",
1271                           __FILE__, __LINE__, getThreadStr(getExecThreadID()));
1272         assert(ret);
1273 #else
1274         sysset_t *cur_syscalls = SYSSET_ALLOC(getPid());
1275
1276         if (!get_exit_syscalls(cur_syscalls)) return NULL;
1277         if (prissyssetmember(cur_syscalls, trappedSyscall->syscall_id))
1278             // Surprising case... but it's possible as we trap fork and exec
1279             trappedSyscall->orig_setting = 1;
1280         else
1281             trappedSyscall->orig_setting = 0;
1282
1283         // 2) Place a trap
1284         praddsysset(cur_syscalls, trappedSyscall->syscall_id);
1285         if (!set_exit_syscalls(cur_syscalls)) return false;
1286         
1287         //bperr("PCSexit for %d, orig %d\n", 
1288         //trappedSyscall->syscall_id, trappedSyscall->orig_setting);
1289 #endif
1290         // Insert into the list of trapped syscalls
1291         syscallTraps_ += (trappedSyscall);
1292
1293         return trappedSyscall;
1294     }
1295     // Should never reach here.
1296     return NULL;
1297 }
1298
1299 bool process::clearSyscallTrapInternal(syscallTrap *trappedSyscall) {
1300     // Decrement the reference count, and if it's 0 remove the trapped
1301     // system call
1302     assert(trappedSyscall->refcount > 0);
1303
1304     trappedSyscall->refcount--;
1305     if (trappedSyscall->refcount > 0) {
1306         //bperr( "Refcount on syscall %d reduced to %d\n",
1307         //        (int)trappedSyscall->syscall_id,
1308         //        trappedSyscall->refcount);
1309         return true;
1310     }
1311     // Erk... it hit 0. Remove the trap at the system call
1312 #if defined(AIX_PROC) 
1313     dyn_lwp *lwp = getLWP(trappedSyscall->syscall_id);
1314     inferiorFree(trappedSyscall->trapAddr);
1315     lwp->changePC(trappedSyscall->origLR, NULL);
1316 #else
1317     sysset_t *cur_syscalls = SYSSET_ALLOC(getPid());
1318
1319     if (!get_exit_syscalls(cur_syscalls)) return false;
1320     if (!trappedSyscall->orig_setting) {
1321         prdelsysset(cur_syscalls, trappedSyscall->syscall_id);
1322     }
1323     
1324     if (!set_exit_syscalls(cur_syscalls)) return false;
1325     
1326
1327 #endif
1328     // Now that we've reset the original behavior, remove this
1329     // entry from the vector
1330     pdvector<syscallTrap *> newSyscallTraps;
1331     for (unsigned iter = 0; iter < syscallTraps_.size(); iter++) {
1332         if (trappedSyscall != syscallTraps_[iter])
1333             newSyscallTraps.push_back(syscallTraps_[iter]);
1334     }
1335     syscallTraps_ = newSyscallTraps;
1336     delete trappedSyscall;
1337     
1338     return true;
1339 }
1340
1341 Address dyn_lwp::getCurrentSyscall() {
1342     
1343     // Return the system call we're currently in
1344     lwpstatus_t status;
1345     if (!get_status(&status)) {
1346         bperr( "Failed to get status\n");
1347         return 0;
1348     }
1349 #if defined(AIX_PROC)
1350     return get_lwp_id();
1351 #else
1352     return status.pr_syscall;
1353 #endif
1354 }
1355
1356
1357
1358 bool dyn_lwp::stepPastSyscallTrap()
1359 {
1360 #if defined(AIX_PROC)
1361     // What is something else doing hitting our trap?
1362     assert(0);
1363 #endif
1364     // Nice... on /proc systems we don't need to do anything here
1365     return true;
1366 }
1367
1368 // Check if a LWP has hit a trap we inserted to catch the exit of a
1369 // system call trap.
1370 // Return values:
1371 // 0: did not trap at the exit of a syscall
1372 // 1: Trapped, but did not have a syscall trap placed for this LWP
1373 // 2: Trapped with a syscall trap desired.
1374 int dyn_lwp::hasReachedSyscallTrap() {
1375 #if defined(AIX_PROC) 
1376     if (!trappedSyscall_) return 0;
1377     
1378     Frame frame = getActiveFrame();
1379     
1380     if (frame.getPC() == trappedSyscall_->trapAddr)
1381         return 2;
1382 #else
1383     Address syscall;
1384     // Get the status of the LWP
1385     lwpstatus_t status;
1386     if (!get_status(&status)) {
1387         bperr( "Failed to get thread status\n");
1388         return 0;
1389     }
1390     
1391     if (status.pr_why != PR_SYSEXIT) {
1392         return 0;
1393     }
1394     syscall = status.pr_what;
1395     
1396     if (trappedSyscall_ && syscall == trappedSyscall_->syscall_id) {
1397         return 2;
1398     }
1399     // Unfortunately we can't check a recorded system call trap,
1400     // since we don't have one saved. So do a scan through all traps the
1401     // process placed
1402     if (proc()->checkTrappedSyscallsInternal(syscall))
1403         return 1;
1404 #endif
1405
1406     // This is probably an error case... but I'm not sure.
1407     return 0;
1408 }
1409
1410 int showProcStatus(lwpstatus_t status)
1411 {
1412    switch (status.pr_why) {
1413      case PR_SIGNALLED:
1414         cerr << "PR_SIGNALED, what: " << (int)status.pr_what << endl;
1415         break;
1416      case PR_SYSENTRY:
1417         cerr << "PR_SYSENTRY, what: " << (int)status.pr_what << endl;
1418         break;
1419      case PR_SYSEXIT:
1420         cerr << "PR_SYSEXIT, what: " << (int)status.pr_what << endl;
1421         break;
1422      case PR_REQUESTED:
1423         cerr << "PR_REQUESTED\n";
1424         break;
1425 #if defined(PR_SUSPENDED)
1426      case PR_SUSPENDED:
1427         // I'm seeing this state at times with a forking multi-threaded
1428         // child process, currently handling by just continuing the process
1429         cerr << "PR_SUSPENDED\n";
1430         break;
1431 #endif
1432      case PR_JOBCONTROL:
1433      case PR_FAULTED:
1434      default:
1435         cerr << "OTHER\n";
1436         assert(0);
1437         break;
1438    }
1439    return 1;
1440 }
1441
1442 bool find_matching_event(pdvector<EventRecord> &events,
1443                          EventRecord &ev,
1444                          EventRecord &matching_ev) 
1445 {
1446    bool found = false;
1447    process *proc = ev.proc;
1448    for(unsigned i=0; i<events.size(); i++) {
1449       EventRecord *cur_event = &(events[i]);
1450       if(cur_event->proc == proc && cur_event->type == ev.type &&
1451          cur_event->what == ev.what) {
1452          // assume that there's at most one matching event
1453          assert(!found);
1454          matching_ev = *cur_event;
1455          found = true;
1456       }
1457    }
1458
1459    return found;
1460 }
1461
1462 // returns true if updated events structure for this lwp 
1463 bool SignalGenerator::updateEventsWithLwpStatus(process *curProc, dyn_lwp *lwp,
1464                                pdvector<EventRecord> &events)
1465 {
1466   lwpstatus_t lwpstatus;
1467   if (!lwp->get_status(&lwpstatus)) {
1468     fprintf(stderr, "%s[%d]:  failed to get status for lwp %d\n", 
1469             FILE__, __LINE__, lwp->get_lwp_id());
1470     return false;
1471   }
1472
1473   // This is the "why" for the lwps that were stopped because some other
1474   // lwp stopped for an interesting reason.  We don't care about lwps
1475   // that stopped for this reason.
1476   if (lwpstatus.pr_why == PR_REQUESTED) {
1477      return false;
1478   }
1479    
1480   EventRecord ev;
1481   ev.type = evtUndefined;
1482   ev.what = 0;
1483   ev.info = 0;
1484   ev.proc = curProc;
1485   ev.lwp = lwp;
1486
1487   if (!decodeProcStatus(lwpstatus, ev)) {
1488      fprintf(stderr, "%s[%d]:  failed to decodeProcStatus\n", FILE__, __LINE__);
1489      return false;
1490   }
1491    
1492
1493   EventRecord matching_event;
1494   bool found_match = find_matching_event(events, ev, matching_event);
1495
1496   if (!found_match) {
1497      events.push_back(ev);
1498   } else 
1499      matching_event.lwp = lwp;
1500    
1501 #if 0
1502   char buf[128];
1503   fprintf(stderr, "%s[%d]:  updateEvents got event %s\n", FILE__, __LINE__, ev.sprint_event(buf));
1504 #endif
1505   return true;
1506 }
1507
1508 bool SignalGenerator::updateEvents(pdvector<EventRecord> &events, process *p, int lwp_to_use)
1509 {
1510   //  returns true if events are updated
1511   dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(p->real_lwps);
1512   dyn_lwp *cur_lwp;
1513   unsigned index;
1514   dyn_lwp *replwp = p->getRepresentativeLWP();
1515   int numreal_lwps = p->real_lwps.size();
1516   bool updated_events = false;
1517
1518   if (numreal_lwps == 0)
1519      updated_events = updateEventsWithLwpStatus(p, replwp, events);
1520   else {
1521      while (lwp_iter.next(index, cur_lwp)) {
1522        if (cur_lwp->get_lwp_id() != (unsigned)lwp_to_use)
1523          continue;
1524        if (updateEventsWithLwpStatus(p, cur_lwp, events)) {
1525          updated_events = true;
1526          break;
1527        }
1528      }
1529   }
1530   return updated_events;
1531 }
1532
1533 bool SignalGenerator::decodeEvent(EventRecord &ev)
1534 {
1535
1536   if ((ev.info & POLLHUP) || (ev.info & POLLNVAL)) {
1537      // True if the process exited out from under us
1538      ev.lwp = ev.proc->getRepresentativeLWP();
1539      int status;
1540      int ret; 
1541      do {
1542          ret = waitpid(pid, &status, 0);
1543      } while ((ret < 0) && (errno == EINTR));
1544      if (ret < 0) { 
1545          //  if we get ECHILD it just means that the child process no longer exists.
1546          //  just create an exit event and keep quiet
1547          if (errno != ECHILD) {
1548            fprintf(stderr, "%s[%d]:  This shouldn't happen\n", FILE__, __LINE__);         
1549            perror("waitpid");
1550          }
1551          //  but really it _should_ be our child since 
1552          ev.type = evtProcessExit;
1553          ev.what = 0;
1554          status = 0;
1555          return true;
1556      }
1557
1558      if (!decodeWaitPidStatus(status, ev)) {
1559         fprintf(stderr, "%s[%d]:  failed to decodeWaitPidStatus\n", FILE__, __LINE__);
1560         return true;
1561      }
1562
1563      if (ev.type == evtSignalled && !decodeSignal(ev)) {
1564         fprintf(stderr, "%s[%d]:  failed to decodeSignal\n", FILE__, __LINE__);
1565         return true;
1566      }
1567
1568      signal_printf("%s[%d]:  new event: %s\n", FILE__, __LINE__, eventType2str(ev.type));
1569      return true;
1570   }
1571
1572    procProcStatus_t procstatus;
1573    if(! ev.proc->getRepresentativeLWP()->get_status(&procstatus)) {
1574       if (ev.type == evtUndefined) {
1575         ev.type = evtProcessExit;
1576         fprintf(stderr, "%s[%d]:  file desc for process exit not available\n",
1577                 FILE__, __LINE__);
1578         return true;
1579       }
1580       fprintf(stderr, "%s[%d]:  file desc for %s not available\n",
1581               FILE__, __LINE__, eventType2str(ev.type));
1582       return false;
1583    }
1584
1585    // copied from old code, must not care about events that don't stop proc
1586    if ( !(procstatus.pr_flags & PR_STOPPED || procstatus.pr_flags & PR_ISTOP) ) {
1587      ev.type = evtNullEvent;
1588      signal_printf("%s[%d]:  new event: %s\n",
1589                    FILE__, __LINE__, eventType2str(ev.type));
1590      return true;
1591    }
1592
1593    bool updated_events = false;
1594    unsigned lwp_to_use = (unsigned) procstatus.pr_lwpid;
1595    updated_events = updateEvents(events_to_handle, ev.proc, lwp_to_use);
1596
1597    if (events_to_handle.size()) {
1598      ev = events_to_handle[0];
1599      events_to_handle.erase(0,0);
1600    }
1601    else
1602      ev.type = evtUndefined;
1603
1604 #if 0
1605    char buf[128];
1606    fprintf(stderr, "%s[%d]:  decodeEvent got %s\n", FILE__, __LINE__, ev.sprint_event(buf));
1607 #endif
1608    return updated_events;
1609
1610 }
1611
1612 pdstring process::tryToFindExecutable(const pdstring &iprogpath, int pid) {
1613   // This is called by exec, so we might have a valid file path. If so,
1614   // use it... otherwise go to /proc. Helps with exec aliasing problems.
1615
1616    if (iprogpath.c_str()) {
1617        int filedes = open(iprogpath.c_str(), O_RDONLY);
1618        if (filedes != -1) {
1619           P_close(filedes);
1620           return iprogpath;
1621        }
1622    }
1623
1624   // We need to dereference the /proc link.
1625   // Case 1: multiple copies of the same file opened with multiple
1626   // pids will not match (and should)
1627   // Case 2: an exec'ed program will have the same /proc path,
1628   // but different program paths
1629   pdstring procpath = pdstring("/proc/") + pdstring(pid) + pdstring("/object/a.out");
1630
1631   // Sure would be nice if we could get the original....
1632
1633   return procpath;
1634 }
1635
1636
1637
1638