Have StackwalkerAPI use ProcControlAPI for debug interface, works on x86 family
[dyninst.git] / stackwalk / src / bluegene-swk.C
1 /*
2  * Copyright (c) 1996-2009 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  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #include "stackwalk/src/bluegene-swk.h"
32 using namespace DebuggerInterface;
33
34 #include "stackwalk/src/bluegenel-swk.h"
35 #include "stackwalk/src/bluegenep-swk.h"
36
37 #include "stackwalk/h/swk_errors.h"
38 #include "stackwalk/h/symlookup.h"
39 #include "stackwalk/h/walker.h"
40 #include "stackwalk/h/framestepper.h"
41 #include "stackwalk/h/procstate.h"
42 #include "stackwalk/src/symtab-swk.h"
43 using namespace Dyninst;
44 using namespace Dyninst::Stackwalker;
45
46 #include <string>
47 #include <memory>
48 #include <string.h>
49 #include <sys/syscall.h>
50 #include <unistd.h>
51 #include <errno.h>
52 #include <signal.h>
53 #include <sys/poll.h>
54 #include <assert.h>
55 using namespace std;
56
57
58 namespace Dyninst {
59   namespace Stackwalker {
60
61     bool bg_fdHasData(int fd) {
62       int result;
63       struct pollfd fds;
64       fds.fd = fd;
65       fds.events = POLLIN;
66       fds.revents = 0;
67       result = poll(&fds, 1, 0);
68       if (result == -1) {
69         int errnum = errno;
70         sw_printf("[%s:%u] - Unable to poll fd %d: %s\n", __FILE__, __LINE__, 
71                   fd, strerror(errnum));
72         return false;
73       }
74       return (bool) (fds.revents & POLLIN);
75     }
76
77
78     // ============================================================ //
79     // Walker
80     // ============================================================ //
81     bool Walker::createDefaultSteppers() {
82       FrameStepper *stepper = new FrameFuncStepper(this);
83       bool result = addStepper(stepper);
84       if (!result) {
85         sw_printf("[%s:%u] - Error adding stepper %p\n", __FILE__, __LINE__, stepper);
86       }
87       return result;
88     }
89
90
91     // ============================================================ //
92     // ProcSelf -- all stubs; this is 3rd-party only
93     // ============================================================ //
94     static bool proc_self_unsupported(const char *file, size_t line) {
95       const char *msg = "ProcSelf not supported for 3rd party BG stackwalkers!";
96       sw_printf("[%s:%u] - %s\n", file, line, msg);
97       setLastError(err_procread, msg);
98       return false;
99     }
100
101     bool ProcSelf::getThreadIds(std::vector<THR_ID> &) {
102       return proc_self_unsupported(__FILE__, __LINE__);
103     }
104
105
106     ProcSelf::ProcSelf() : ProcessState(getpid()) {
107       proc_self_unsupported(__FILE__, __LINE__);
108     }
109
110
111     void ProcSelf::initialize() {
112       proc_self_unsupported(__FILE__, __LINE__);
113     }
114
115
116     bool ProcSelf::getDefaultThread(THR_ID &) {
117       return proc_self_unsupported(__FILE__, __LINE__);
118     }
119
120
121     bool ProcSelf::readMem(void *, Address, size_t) {
122       return proc_self_unsupported(__FILE__, __LINE__);
123     }
124
125
126     // ============================================================ //
127     // ProcDebug
128     // ============================================================ //
129     ProcDebug *ProcDebug::newProcDebug(PID pid, string executable) {
130       auto_ptr<ProcDebug> pd(ProcDebugBG::createProcDebugBG(pid, executable));
131       if (!pd.get()) {
132         const char *msg = "Error creating new ProcDebug object";
133         sw_printf("[%s:%u] - %s\n", __FILE__, __LINE__, msg);
134         setLastError(err_internal, msg);
135         return NULL;
136       }
137   
138       bool result = pd->attach();
139       if (!result || (pd->state() != ps_running && pd->state() != ps_attached))
140       {
141         pd->setState(ps_errorstate);
142         proc_map.erase(pid);
143         const char *msg = "Error attaching to process";
144         sw_printf("[%s:%u] - %s %d\n", __FILE__, __LINE__, msg, pid);
145         setLastError(err_noproc, msg);
146         return NULL;
147       }
148   
149       return pd.release();
150     }
151
152
153     bool ProcDebug::newProcDebugSet(const vector<Dyninst::PID>&, vector<ProcDebug*>&) {
154       setLastError(err_unsupported, "ERROR: newProcDebugSet not implemented for BlueGene Stackwalker!");
155       return false;
156     }
157
158
159     ProcDebug *ProcDebug::newProcDebug(const std::string &, const std::vector<std::string> &) {
160       setLastError(err_unsupported, "Executable launch not supported on BlueGene");
161       return NULL;
162     }
163
164
165     bool ProcDebugBG::isLibraryTrap(Dyninst::THR_ID) {
166       // Base ProcDebugBG doesn't support dynamic libs.
167       return false;
168     }
169
170
171     DebugEvent ProcDebug::debug_get_event(bool block) {
172       DebugEvent ev;   
173       BG_Debugger_Msg msg;
174
175       if (!block && !bg_fdHasData(BG_DEBUGGER_READ_PIPE)) {
176         ev.dbg = dbg_noevent;
177         return ev;
178       }
179
180       // Read an event from the debug filehandle.
181       sw_printf("[%s:%u] - Waiting for debug event\n", __FILE__, __LINE__);
182       bool result = BG_Debugger_Msg::readFromFd(BG_DEBUGGER_READ_PIPE, msg);
183       if (!result) {
184         sw_printf("[%s:%u] - Unable to wait for debug event on process\n",
185                   __FILE__, __LINE__);
186         ev.dbg = dbg_err;
187         return ev;
188       }
189
190       // extract process and thread id from the BG message.
191       pid_t pid = msg.header.nodeNumber;   
192       THR_ID tid = msg.header.thread;
193       int returnCode = msg.header.returnCode;
194       sw_printf("[%s:%u] - Received debug event %s from pid %d, tid %d, rc %d\n", __FILE__, __LINE__,
195                 BG_Debugger_Msg::getMessageName(msg.header.messageType), pid, tid, returnCode);
196
197       if (returnCode > 0) {
198         // Print out a message if we get a return code we don't expect.  Consult the debugger header
199         // for the meanings of these.
200         sw_printf("[%s:%u] - WARNING: return code for %s on pid %d, tid %d was non-zero: %d\n",
201                   __FILE__, __LINE__, 
202                   BG_Debugger_Msg::getMessageName(msg.header.messageType), pid, tid,
203                   msg.header.returnCode);
204       }
205
206       // Look up the ProcDebugBG from which the event originated.      
207       std::map<PID, ProcessState *>::iterator i = proc_map.find(pid);
208       if (i == proc_map.end()) {
209         sw_printf("[%s:%u] - Error, received unknown pid %d\n", __FILE__, __LINE__, pid);
210         setLastError(err_internal, "Error waiting for debug event");
211         ev.dbg = dbg_err;
212         return ev;
213       }
214       ProcDebugBG *procbg = dynamic_cast<ProcDebugBG*>(i->second);
215       assert(procbg);
216       ev.proc = procbg;
217       
218       // below is some (somewhat nasty) magic to allow stackwalker to discover the 
219       // initial thread's id after it attaches.
220       thread_map_t::iterator t = procbg->threads.find(tid);
221       if (t == procbg->threads.end()) {
222         BGThreadState *initial_thread = dynamic_cast<BGThreadState*>(procbg->initial_thread);
223
224         if (tid != 0) {
225           // Check to see if the initial thread is valid.  If its id is zero, it's a stub
226           // from creation time and we got a signal from the real initial thread.  If it's
227           // not zero, then we're seeing a strange thread id.
228           if (initial_thread->getTid() != 0) {
229             const char *msg = "Saw unknown thread id in ProcDebug::debug_get_evet()!";
230             sw_printf("[%s:%u] - %s on pid %d\n", __FILE__, __LINE__, msg, pid);
231             setLastError(err_internal, msg);
232             ev.dbg = dbg_err;
233             return ev;
234           }
235           
236           // if we see a threadid we don't know about, it's because we got a SIGNAL_ENCOUNTERED
237           // from the main thread.  We default the initial thread id to zero, but this is only because
238           // we need to start somewhere to attach.  This sets the main thread id to the real thread id
239           // for the process.  This should happen relatively early when we stop the thread during attach.
240           procbg->threads.erase(initial_thread->getTid());
241           initial_thread->setTid(tid);
242           procbg->threads[tid] = initial_thread;
243           t = procbg->threads.find(tid);
244
245         } else {
246           // if the thread id we don't know about is zero, we got an ack for something we
247           // did before we discovered what the initial thread id was.  So just point the event
248           // at the initial thread
249           t = procbg->threads.find(initial_thread->getTid());
250         }
251       }
252
253       ThreadState *ts = t->second;
254       assert(ts);
255       ev.thr = ts;
256       
257       procbg->translate_event(msg, ev);
258       return ev;
259     }
260
261
262    int ProcDebug::getNotificationFD() {
263       return BG_DEBUGGER_READ_PIPE;
264     }
265
266
267     // ============================================================ //
268     // ProcDebugBG
269     // ============================================================ /
270     void ProcDebugBG::translate_event(const BG_Debugger_Msg& msg, DebugEvent& ev) {
271       switch (msg.header.messageType) {
272       case PROGRAM_EXITED:
273         {
274           ev.data.idata = msg.dataArea.PROGRAM_EXITED.rc;
275           int exit_type = msg.dataArea.PROGRAM_EXITED.type;
276
277           if (exit_type == 0) {
278             ev.dbg = dbg_exited;
279             sw_printf("[%s:%u] - Process %d exited with %d\n", __FILE__, __LINE__, pid, ev.data.idata);
280           } else if (exit_type == 1) {
281             ev.dbg = dbg_crashed;
282             sw_printf("[%s:%u] - Process %d crashed with %d\n", __FILE__, __LINE__, pid, ev.data.idata);
283           } else {
284             ev.dbg = dbg_err;
285             sw_printf("[%s:%u] - WARNING: Unknown exit type (%d) on process %d. "
286                       "May be using outdated BG Debugger Interface!\n", __FILE__, __LINE__, 
287                       msg.dataArea.PROGRAM_EXITED.type, pid);
288           }
289         }
290         break;
291         
292       case SIGNAL_ENCOUNTERED:
293         ev.dbg = dbg_stopped;
294         ev.data.idata = msg.dataArea.SIGNAL_ENCOUNTERED.signal;
295         sw_printf("[%s:%u] - Process %d stopped with %d\n",
296                   __FILE__, __LINE__, pid, msg.dataArea.SIGNAL_ENCOUNTERED.signal);
297         break;
298
299       case ATTACH_ACK:
300         ev.dbg = dbg_attached;
301         sw_printf("[%s:%u] - Process %d acknowledged attach\n", __FILE__, __LINE__, pid);
302         break;
303       case DETACH_ACK:
304         ev.dbg = dbg_detached;
305         sw_printf("[%s:%u] - Process %d acknowledged detach\n", __FILE__, __LINE__, pid);
306         break;
307       case CONTINUE_ACK:
308         ev.dbg = dbg_continued;
309         sw_printf("[%s:%u] - Process %d acknowledged continue\n", __FILE__, __LINE__, pid);
310         break;
311
312       case KILL_ACK:
313         ev.dbg = dbg_other;
314         sw_printf("[%s:%u] - Process %d acknowledged kill\n", __FILE__, __LINE__, pid);
315         break;
316
317       case GET_ALL_REGS_ACK:
318         {
319           ev.dbg = dbg_allregs_ack;
320           ev.size = msg.header.dataLength;
321           BG_GPRSet_t *data = new BG_GPRSet_t();
322           *data = msg.dataArea.GET_ALL_REGS_ACK.gprs;
323           ev.data.pdata = data;
324           sw_printf("[%s:%u] - RegisterAll ACK on pid %d\n", __FILE__, __LINE__, pid);
325         }
326         break;
327       case SET_REG_ACK:
328         {
329           ev.dbg = dbg_setreg_ack;
330           sw_printf("[%s:%u] - SET_REG ACK on pid %d\n", __FILE__, __LINE__, pid);
331           break;
332         }
333
334       case GET_MEM_ACK:
335         ev.dbg = dbg_mem_ack;
336         ev.size = msg.header.dataLength;
337         ev.data.pdata = new unsigned char[msg.header.dataLength];
338         if (!ev.data.pdata) {
339           ev.dbg = dbg_err;
340           sw_printf("[%s:%u] - FATAL: Couldn't allocate enough space for memory read on pid %d\n", 
341                     __FILE__, __LINE__, pid);
342         } else {
343           memcpy(ev.data.pdata, &msg.dataArea, msg.header.dataLength);
344           sw_printf("[%s:%u] - Memory read ACK on pid %d\n", __FILE__, __LINE__, pid);
345         }
346         break;
347
348     case SET_MEM_ACK:
349         ev.dbg = dbg_setmem_ack;
350         ev.size = msg.dataArea.SET_MEM_ACK.len;
351         sw_printf("[%s:%u] - Memory write ACK on pid %d ($d bytes at %x).  \n", __FILE__, __LINE__, 
352                   msg.dataArea.SET_MEM_ACK.len, msg.dataArea.SET_MEM_ACK.addr);
353         break;
354
355       case SINGLE_STEP_ACK:
356         // single step ack is just an ack (like KILL_ACK). We ignore this event and 
357         // handle SINGLE_STEP_SIG specially in debug_handle_signal().
358         ev.dbg = dbg_other;
359         sw_printf("[%s:%u] - Process %d received SINGLE_STEP\n", __FILE__, __LINE__, pid, ev.data);
360         break;
361
362       default:
363         sw_printf("[%s:%u] - Unknown debug message: %s (%d)\n",
364                   __FILE__, __LINE__, 
365                   BG_Debugger_Msg::getMessageName(msg.header.messageType),
366                   msg.header.messageType);
367         ev.dbg = dbg_noevent;
368         break;
369      }
370   }
371
372
373     void copy_thread_state(ThreadState *source, ThreadState *dest) {
374       dest->setState(source->state());
375       dest->setStopped(source->isStopped());
376       dest->setShouldResume(source->shouldResume());
377       dest->setUserStopped(source->userIsStopped());
378     }
379
380     bool ProcDebugBG::pollForNewThreads() {
381       return true;  // by default, we don't find anything.
382     }
383
384
385     // This basic implementation assumes *only* the initial thread.
386     bool ProcDebugBG::getThreadIds(std::vector<THR_ID> &threads) {
387       threads.clear();
388       threads.push_back(initial_thread->getTid());
389       return true;
390     }
391
392
393     bool ProcDebugBG::getDefaultThread(THR_ID &default_tid) {
394       default_tid = initial_thread->getTid();
395       return true;
396     }
397
398
399     unsigned ProcDebugBG::getAddressWidth() {
400       return sizeof(DebuggerInterface::BG_Addr_t);
401     }
402
403
404     bool ProcDebugBG::debug_continue(ThreadState *ts) {
405       return debug_continue_with(ts, 0);
406     }
407
408
409     ProcDebugBG::~ProcDebugBG() {
410       if (read_cache) delete [] read_cache;
411     }
412
413
414     ProcDebugBG::ProcDebugBG(PID pid, string exe)
415       : ProcDebug(pid, exe),
416         mem_data(NULL),
417         read_cache(NULL),
418         read_cache_start(0x0),
419         read_cache_size(0x0),
420         detached(false),
421         write_ack(false)
422     {
423     }
424
425
426     bool ProcDebugBG::debug_create(const std::string &, const std::vector<std::string> &) 
427     {
428       setLastError(err_unsupported, "Create mode not supported on BlueGene");
429       return false;
430     }
431
432
433     struct set_gprs {
434       bool val;
435       set_gprs(bool v) : val(v) { }
436       void operator()(ThreadState *ts) {
437         dynamic_cast<BGThreadState*>(ts)->gprs_set = val;
438       }
439     };
440
441
442     void ProcDebugBG::clear_cache() {
443       for_all_threads(set_gprs(false));
444       read_cache_start = 0x0;
445       read_cache_size = 0x0;
446       mem_data = NULL;
447     }
448
449
450     bool ProcDebugBG::version_msg()
451     {
452       bool result = debug_version_msg();
453       if (!result) {
454         sw_printf("[%s:%u] - Could not version msg debugee %d\n", __FILE__, __LINE__, pid);
455         return false;
456       }
457    
458       result = debug_waitfor_version_msg();
459       if (state() == ps_exited) {
460         setLastError(err_procexit, "Process exited unexpectedly during version_msg");
461         return false;
462       }
463       if (!result) {
464         sw_printf("[%s:%u] - Error during process version_msg for %d\n",
465                   __FILE__, __LINE__, pid);
466         return false;
467       }   
468       return true;
469     }
470
471
472     bool ProcDebugBG::debug_waitfor_version_msg() {
473       sw_printf("[%s:%u] - At debug_waitfor_Version_msg.\n", __FILE__, __LINE__);
474       bool handled, result;
475    
476       result = debug_wait_and_handle(true, false, handled);
477       if (!result || state() == ps_errorstate) {
478         sw_printf("[%s:%u] - Error,  Process %d errored during version_msg\n",
479                   __FILE__, __LINE__, pid);
480         return false;
481       }
482       if (state() == ps_exited) {
483         sw_printf("[%s:%u] - Error.  Process %d exited during version_msg\n",
484                   __FILE__, __LINE__, pid);
485         return false;
486       }
487       sw_printf("[%s:%u] - Successfully version_msg %d\n",
488                 __FILE__, __LINE__, pid);
489       return true;      
490     }
491
492
493
494     bool ProcDebugBG::debug_handle_event(DebugEvent ev)
495     {
496       BGThreadState *thr = dynamic_cast<BGThreadState*>(ev.thr);
497
498       switch (ev.dbg) {
499       case dbg_stopped:
500         // we got a signal from the process.  Stop all the threads and let 
501         // debug_handle_signal() take care of things.
502         for_all_threads(set_stopped(true));
503         return debug_handle_signal(&ev);
504
505       case dbg_crashed:
506         sw_printf("[%s:%u] - Process %d crashed!\n", __FILE__, __LINE__, pid);
507         // fallthru
508
509       case dbg_exited:
510         sw_printf("[%s:%u] - Handling process exit on %d\n", __FILE__, __LINE__, pid);
511         for_all_threads(set_stopped(true));
512         for_all_threads(set_state(ps_exited));
513         break;
514
515       case dbg_continued:
516         sw_printf("[%s:%u] - Process %d continued\n", __FILE__, __LINE__, pid);
517         clear_cache();
518         assert(thr->isStopped());
519         for_all_threads(set_stopped(false));
520         break;
521
522       case dbg_attached:
523         sw_printf("[%s:%u] - Process %d attached\n", __FILE__, __LINE__, pid);
524         assert(state() == ps_neonatal);
525         for_all_threads(set_state(ps_attached_intermediate));
526         //debug_pause(NULL); //immediately after debug_attach, pause the process.
527         break;
528       case dbg_detached:
529         sw_printf("[%s:%u] - Process %d detached\n", __FILE__, __LINE__, pid);
530         detached = true;
531         break;
532
533       case dbg_mem_ack:
534         sw_printf("[%s:%u] - Process %d returned a memory chunk of size %u\n", 
535                   __FILE__, __LINE__, pid, ev.size);
536         assert(!mem_data);
537         mem_data = static_cast<BG_Debugger_Msg::DataArea*>(ev.data.pdata);
538         break;
539
540       case dbg_setmem_ack:
541         sw_printf("[%s:%u] - Process %d set a chunk of memory of size %u\n", 
542                   __FILE__, __LINE__, pid, ev.size);
543         write_ack = true;
544         break;
545
546       case dbg_allregs_ack:
547         {
548           sw_printf("[%s:%u] - Process %d returned a register chunk of size %u\n", 
549                     __FILE__, __LINE__, pid, ev.size);
550           BG_GPRSet_t *data = static_cast<BG_GPRSet_t*>(ev.data.pdata);
551           thr->gprs = *data;
552           thr->gprs_set = true;
553           ev.data.pdata = NULL;
554           delete data;
555         }
556         break;
557       case dbg_setreg_ack:
558         {
559           sw_printf("[%s:%u] - Handling set reg ack on process %d\n", 
560                     __FILE__, __LINE__, pid);
561           thr->write_ack = true;
562           break;
563         }
564       case dbg_other:
565         sw_printf("[%s:%u] - Skipping unimportant event\n", __FILE__, __LINE__);
566         break;
567
568       case dbg_err:
569       case dbg_noevent:       
570       default:
571         sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d\n", 
572                   __FILE__, __LINE__, ev.dbg, pid);
573         setLastError(err_internal, "Told to handle an unexpected event.");
574         return false;
575       }
576
577       return true;
578     }
579
580
581     bool ProcDebugBG::debug_handle_signal(DebugEvent *ev) {
582       assert(ev->dbg == dbg_stopped); 
583       // PRE: we got a signal event, and things are stopped.
584
585       sw_printf("[%s:%u] - Handling signal for pid %d\n", __FILE__, __LINE__, pid);
586       BGThreadState *thr = dynamic_cast<BGThreadState*>(ev->thr);
587
588       switch (ev->data.idata) {
589       case SIGSTOP:
590         // if we're attaching, SIGSTOP tells us we've completed.
591         if (state() == ps_attached_intermediate) {
592           setState(ps_attached);
593           sw_printf("[%s:%u] - Moving %d to state ps_attached\n", __FILE__, __LINE__, pid);
594         }
595         // if we're not attaching, do nothing.  leave the thread stopped.
596         break;
597         
598       case SINGLE_STEP_SIG:
599         // BG uses this special signal to indicate completion of a single step.
600         // Ignore the event and continue if the user didn't stop. TODO: why?
601         // Otherwise, if *we* stopped, just stay stopped.
602         clear_cache();  // took a step, need to clear cache.
603         return thr->userIsStopped() ? true : debug_continue_with(thr, 0);
604         break;
605         
606       default:
607         // by default, pass the signal back to the process being debugged.
608         if (sigfunc) {
609            bool user_stopped = ev->thr->userIsStopped();
610            ev->thr->setUserStopped(true);
611            sigfunc(ev->data.idata, ev->thr);
612            ev->thr->setUserStopped(user_stopped);           
613         }
614         return debug_continue_with(thr, ev->data.idata);
615       }
616       
617       return true;
618     }
619
620
621     bool ProcDebugBG::debug_attach(ThreadState *ts)
622     {
623       THR_ID tid = ts->getTid();
624       BG_Debugger_Msg msg(ATTACH, pid, tid, 0, 0);
625       msg.header.dataLength = sizeof(msg.dataArea.ATTACH);
626       
627       // send attach message
628       sw_printf("[%s:%u] - Attaching to pid %d, thread %d\n", __FILE__, __LINE__, pid, tid);
629       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
630       if (!result) {
631         sw_printf("[%s:%u] - Error sending attach to process %d, thread %d\n",
632                   __FILE__, __LINE__, pid, tid);
633       }
634        
635       return result;
636     }
637
638     bool ProcDebugBG::cleanOnDetach() {
639       //Overridden on BG/P
640       return true;
641     }
642
643     bool ProcDebugBG::detach(bool /*leave_stopped*/) {
644       // TODO: send detach message
645       sw_printf("[%s:%u] - Detaching from process %d\n", __FILE__, __LINE__, 
646                 pid);
647       bool result = cleanOnDetach();
648       if (!result) {
649         sw_printf("[%s:%u] - Failed to clean process %d\n", 
650                   __FILE__, __LINE__, pid);
651         return false;
652       }
653       
654       result = resume();
655       if (!result) {
656         sw_printf("[%s:%u] - Error resuming process before detach\n");
657       }
658
659       BG_Debugger_Msg msg(DETACH, pid, 0, 0, 0);
660       msg.header.dataLength = sizeof(msg.dataArea.DETACH);
661       result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
662       if (!result) {
663         sw_printf("[%s:%u] - Failed to write detach to process %d\n",
664                   __FILE__, __LINE__, pid);
665         setLastError(err_internal, "Could not write to debug pipe\n");
666         return false;
667       }
668       while (!detached) {
669         bool handled;
670         bool result = debug_wait_and_handle(true, false, handled);
671         if (!result) {
672           sw_printf("[%s:%u] - Error while waiting for detach\n", 
673                     __FILE__, __LINE__);
674             return false;
675         }
676       }
677       return true;
678     }
679
680
681     bool ProcDebugBG::debug_pause(ThreadState *ts)
682     {
683       THR_ID tid = initial_thread->getTid();  // default to initial thread.
684       if (ts) tid = ts->getTid();
685
686       BG_Debugger_Msg msg(KILL, pid, tid, 0, 0);
687       msg.dataArea.KILL.signal = SIGSTOP;
688       msg.header.dataLength = sizeof(msg.dataArea.KILL);
689       
690       sw_printf("[%s:%u] - Sending SIGSTOP to pid %d, thread %d\n", __FILE__, __LINE__, pid, tid);
691       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
692       if (!result) {
693         sw_printf("[%s:%u] - Unable to send SIGSTOP to process %d, thread\n", __FILE__, __LINE__, pid, tid);
694       }
695       return result;
696     }
697
698
699     bool ProcDebugBG::debug_continue_with(ThreadState *ts, long sig)
700     {
701       THR_ID tid = ts->getTid();
702       if (!ts->isStopped()) {
703         sw_printf("[%s:%u] - Error in debug_continue_with(): pid %d, thread %d not stopped.\n",
704                   __FILE__, __LINE__, pid, tid);
705         return false;
706       }
707
708       BG_Debugger_Msg msg(CONTINUE, pid, tid, 0, 0);
709       msg.dataArea.CONTINUE.signal = sig;
710       msg.header.dataLength = sizeof(msg.dataArea.CONTINUE);
711
712       sw_printf("[%s:%u] - Sending signal %d to pid %d, thread %d\n", __FILE__, __LINE__, sig, pid, tid);
713       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
714       if (!result) {
715         sw_printf("[%s:%u] - Unable to send %d to process %d, thread %d\n", __FILE__, __LINE__, sig, pid, tid);
716       }
717       return result;
718     }
719
720
721     bool ProcDebugBG::getRegValue(MachRegister reg, THR_ID tid, MachRegisterVal &val) {
722       assert(threads.count(tid));
723       BGThreadState *thr = dynamic_cast<BGThreadState*>(threads[tid]);
724
725       if (!thr->gprs_set) {
726         BG_Debugger_Msg msg(GET_ALL_REGS, pid, tid, 0, 0);
727         msg.header.dataLength = sizeof(msg.dataArea.GET_ALL_REGS);
728
729         bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
730         if (!result) {
731           sw_printf("[%s:%u] - Unable to write to process %d, thread %d\n",
732                     __FILE__, __LINE__, pid, tid);
733           return true;
734         }
735       
736         //Wait for the read to return
737         sw_printf("[%s:%u] - Waiting for read to return on pid %d, tid %d\n",
738                   __FILE__, __LINE__, pid, tid);
739         
740         do {
741           bool handled, result;
742           result = debug_wait_and_handle(true, false, handled);
743           if (!result)
744           {
745             sw_printf("[%s:%u] - Error while waiting for read to return\n",
746                       __FILE__, __LINE__);
747             return false;
748           }
749         } while (!thr->gprs_set);
750       }
751    
752       switch(reg)
753       {
754       case Dyninst::MachRegStackBase:
755         val = 0x0;
756         break;
757       case Dyninst::MachRegFrameBase:
758         val = thr->gprs.gpr[BG_GPR1];
759         break;
760       case Dyninst::MachRegPC:
761         val = thr->gprs.iar;
762         break;
763       default:
764         sw_printf("[%s:%u] - Request for unsupported register %d\n", __FILE__, __LINE__, reg);
765         setLastError(err_badparam, "Unknown register passed in reg field");
766         return false;
767       }   
768       return true;
769     }
770
771
772
773     bool ProcDebugBG::setRegValue(MachRegister reg, THR_ID tid, MachRegisterVal val) {
774       assert(threads.count(tid));
775       BGThreadState *thr = dynamic_cast<BGThreadState*>(threads[tid]);
776
777       BG_Debugger_Msg msg(SET_REG, pid, tid, 0, 0);
778       msg.header.dataLength = sizeof(msg.dataArea.SET_REG);
779       msg.dataArea.SET_REG.value = val;
780       switch(reg)
781       {
782       case Dyninst::MachRegFrameBase:
783         msg.dataArea.SET_REG.registerNumber = BG_GPR1;
784         break;
785       case Dyninst::MachRegPC:
786         msg.dataArea.SET_REG.registerNumber = BG_IAR;
787         break;
788       default:
789         sw_printf("[%s:%u] - Request for unsupported register %d\n", __FILE__, __LINE__, reg);
790         setLastError(err_badparam, "Unknown register passed in reg field");
791         return false;
792       }  
793       thr->write_ack = false;
794       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
795       if (!result) {
796         sw_printf("[%s:%u] - Unable to set reg to process %d, thread %d\n",
797                   __FILE__, __LINE__, pid, tid);
798         return true;
799       }
800       
801       //Wait for the read to return
802       sw_printf("[%s:%u] - Waiting for set reg to return on pid %d, tid %d\n",
803                 __FILE__, __LINE__, pid, tid);
804         
805       do {
806         bool handled, result;
807         result = debug_wait_and_handle(true, false, handled);
808         if (!result)
809           {
810             sw_printf("[%s:%u] - Error while waiting for read to return\n",
811                       __FILE__, __LINE__);
812             return false;
813           }
814       } while (!thr->write_ack);
815    
816       return true;
817     }
818
819     bool ProcDebugBG::readMem(void *dest, Address source, size_t size)
820     {
821       unsigned char *ucdest = (unsigned char *) dest;
822       bool result;
823
824       for (;;)
825       {
826         if (size == 0)
827           return true;
828
829         sw_printf("[%s:%u] - Reading memory from 0x%lx to 0x%lx (into %p)\n",
830                   __FILE__, __LINE__, source, source+size, ucdest);
831         if (source >= read_cache_start && 
832             source+size < read_cache_start + read_cache_size)
833         {
834           //Lucky us, we have everything cached.
835           memcpy(ucdest, read_cache + (source - read_cache_start), size);
836           return true;
837         }
838         if (source >= read_cache_start &&
839             source < read_cache_start + read_cache_size)
840         {
841           //The beginning is in the cache, read those bytes
842           long cached_bytes = read_cache_start + read_cache_size - source;
843           memcpy(ucdest, read_cache + (source - read_cache_start), cached_bytes);
844           //Change the parameters and continue the read (this is a kind of
845           // optimized tail call).
846           ucdest += cached_bytes;
847           source = read_cache_start + read_cache_size;
848           size -= cached_bytes;
849           continue;
850         }
851         if (source+size > read_cache_start &&
852             source+size <= read_cache_start + read_cache_size)
853         {
854           //The end is in the cache, read those bytes
855           long cached_bytes = (source+size) - read_cache_start;
856           memcpy(ucdest + read_cache_start - source, read_cache, cached_bytes);
857           //Change the parameters and continue the read (this is a kind of
858           // optimized tail call).
859           size -= cached_bytes;
860           continue;
861         }
862         if (source < read_cache_start &&
863             source+size >= read_cache_start+read_cache_size)
864         {
865           //The middle is in the cache
866           unsigned char *dest_start = ucdest + read_cache_start - source;
867           Address old_read_cache_start = read_cache_start;
868           memcpy(dest_start, read_cache, read_cache_size);
869           //Use actual recursion here, as we need to queue up two reads
870           // First read out of the high memory with recursion
871           result = readMem(dest_start + read_cache_size, 
872                            read_cache_start+read_cache_size,
873                            source+size - read_cache_start+read_cache_size);
874           if (!result) {
875             return false;
876           }
877           // Now read out of the low memory
878           size = old_read_cache_start - source;
879           continue;
880         }
881         //The memory isn't cached, read a new cache'd page.
882         assert(source < read_cache_start || 
883                source >= read_cache_start+read_cache_size);
884       
885         if (!read_cache) {
886           read_cache = new unsigned char[BG_READCACHE_SIZE];
887           assert(read_cache);
888         }
889
890         read_cache_size = BG_READCACHE_SIZE;
891         read_cache_start = source - (source % read_cache_size);
892         sw_printf("[%s:%u] - Caching memory from 0x%lx to 0x%lx\n",
893                   __FILE__, __LINE__, read_cache_start, 
894                   read_cache_start+read_cache_size);
895                     
896         //Read read_cache_start to read_cache_start+read_cache_size into our
897         // cache.
898         assert(!mem_data);
899         assert(read_cache_size < BG_Debugger_Msg_MAX_MEM_SIZE);
900
901         BG_Debugger_Msg msg(GET_MEM, pid, 0, 0, 0);
902         msg.header.dataLength = sizeof(msg.dataArea.GET_MEM);
903         msg.dataArea.GET_MEM.addr = read_cache_start;
904         msg.dataArea.GET_MEM.len = read_cache_size;
905         bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
906         if (!result) {
907           sw_printf("[%s:%u] - Unable to write to process %d\n", __FILE__, __LINE__, pid);
908           return true;
909         }
910       
911         //Wait for the read to return
912         sw_printf("[%s:%u] - Waiting for read to return on pid %d\n", __FILE__, __LINE__);
913
914         if (!debug_waitfor(dbg_mem_ack)) {
915           sw_printf("[%s:%u] - Error while waiting for read to return\n", __FILE__, __LINE__);
916           return false;
917         }
918
919         sw_printf("[%s:%u] - Asserting mem_data post-read.\n", __FILE__, __LINE__);
920         assert(mem_data->GET_MEM_ACK.addr == read_cache_start);
921         assert(mem_data->GET_MEM_ACK.len == read_cache_size);
922         memcpy(read_cache, mem_data->GET_MEM_ACK.data, read_cache_size);
923       
924         //Free up the memory data
925         delete mem_data;
926         mem_data = NULL;
927       }
928     }   
929
930
931     bool ProcDebugBG::debug_version_msg()
932     {
933       BG_Debugger_Msg msg(VERSION_MSG, pid, 0, 0, 0);
934       msg.header.dataLength = sizeof(msg.dataArea.VERSION_MSG);
935
936       sw_printf("[%s:%u] - Sending VERSION_MSG to pid %d\n", __FILE__, __LINE__, pid);
937       bool result = BG_Debugger_Msg::writeOnFd(BG_DEBUGGER_WRITE_PIPE, msg);
938
939       if (!result) {
940         sw_printf("[%s:%u] - Unable to send VERSION_MSG to process %d\n",
941                   __FILE__, __LINE__, pid);
942         return false;
943       }
944       return true;
945     }
946
947     // ============================================================ //
948     // SymtabLibState -- need to differentiate for P
949     // ============================================================ //
950      bool LibraryState::updateLibsArch(vector<pair<LibAddrPair, unsigned int> > &)
951      {
952         return true;
953      }
954
955
956     // ============================================================ //
957     // ThreadState
958     // ============================================================ //
959     ThreadState* ThreadState::createThreadState(ProcDebug *parent, Dyninst::THR_ID tid, bool) {
960       THR_ID thread_id = tid;
961       if (thread_id == NULL_THR_ID) {
962         thread_id = 0;
963       }
964       BGThreadState *ts = new BGThreadState(parent, thread_id);
965       return ts;
966     }
967
968   } // namespace Stackwalker
969 } // namespace Dyninst
970