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