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