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