Updates for StackwalkerAPI
[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
32 #include "stackwalk/h/swk_errors.h"
33 #include "stackwalk/h/symlookup.h"
34 #include "stackwalk/h/walker.h"
35 #include "stackwalk/h/framestepper.h"
36
37 #include "stackwalk/h/procstate.h"
38 #include "stackwalk/src/bluegene-swk.h"
39 #include "stackwalk/src/symtab-swk.h"
40 #include "common/h/linuxKludges.h"
41
42 #include <string>
43
44 #include <string.h>
45 #include <sys/syscall.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <signal.h>
49 #include <sys/poll.h>
50 #include <assert.h>
51
52 using namespace Dyninst;
53 using namespace Dyninst::Stackwalker;
54 using namespace DebuggerInterface;
55 using namespace std;
56
57 bool ProcSelf::getThreadIds(std::vector<THR_ID> &threads)
58 {
59   bool result;
60   THR_ID tid;
61
62   result = getDefaultThread(tid);
63   if (!result) {
64     sw_printf("[%s:%u] - Could not read default thread\n",
65                __FILE__, __LINE__);
66     return false;
67   }
68   threads.clear();
69   threads.push_back(tid);
70   return true;
71 }
72
73 ProcSelf::ProcSelf() :
74    ProcessState(getpid())
75 {
76 }
77
78 void ProcSelf::initialize()
79 {
80 }
81
82 bool ProcSelf::getDefaultThread(THR_ID &default_tid)
83 {
84   default_tid = 0;
85   return true;
86 }
87
88 static bool fdHasData(int fd)
89 {
90    int result;
91    struct pollfd fds;
92    fds.fd = fd;
93    fds.events = POLLIN;
94    fds.revents = 0;
95    result = poll(&fds, 1, 0);
96    if (result == -1) {
97       int errnum = errno;
98       sw_printf("[%s:%u] - Unable to poll fd %d: %s\n", __FILE__, __LINE__, 
99                 fd, strerror(errnum));
100       return false;
101    }
102    return (bool) (fds.revents & POLLIN);
103 }
104
105 #define SINGLE_STEP_SIG 32064
106
107 DebugEvent ProcDebug::debug_get_event(bool block)
108 {
109    DebugEvent ev;
110    pid_t pid;
111    int sig_encountered;
112    
113    BGL_Debugger_Msg msg;
114
115
116    if (!block && !fdHasData(BGL_DEBUGGER_READ_PIPE))
117    {
118       ev.dbg = dbg_noevent;
119       return ev;
120    }
121
122    sw_printf("[%s:%u] - Waiting for debug event\n", __FILE__, __LINE__);
123    bool result = BGL_Debugger_Msg::readFromFd(BGL_DEBUGGER_READ_PIPE, msg);
124    if (!result) {
125       sw_printf("[%s:%u] - Unable to wait for debug event on process\n",
126                 __FILE__, __LINE__);
127       ev.dbg = dbg_err;
128       return ev;
129    }
130    
131    pid = msg.header.nodeNumber;   
132    sw_printf("[%s:%u] - Recieved debug event %d on %d\n", __FILE__, __LINE__,
133              msg.header.messageType, pid);
134    std::map<PID, ProcessState *>::iterator i = proc_map.find(pid);
135    if (i == proc_map.end())
136    {
137       sw_printf("[%s:%u] - Error, recieved unknown pid %d\n",
138                 __FILE__, __LINE__, pid);
139       setLastError(err_internal, "Error waiting for debug event");
140       ev.dbg = dbg_err;
141       return ev;
142    }
143    ProcDebugBG *procbg = dynamic_cast<ProcDebugBG *>(i->second);
144    assert(procbg);
145    ev.proc = procbg;
146
147    switch (msg.header.messageType)
148    {
149       case PROGRAM_EXITED:
150          ev.proc->initial_thread->setStopped(true);
151          
152          if (msg.dataArea.PROGRAM_EXITED.type == 0) {
153             ev.dbg = dbg_exited;
154          }
155          else if (msg.dataArea.PROGRAM_EXITED.type == 1) {
156             ev.dbg = dbg_crashed;
157          }
158          else {
159             sw_printf("[%s:%u] - Unknown exit code (%d) on process %d\n",
160                       __FILE__, __LINE__, msg.dataArea.PROGRAM_EXITED.type, pid);
161             ev.dbg = dbg_err;
162          }
163          ev.data.idata = msg.dataArea.PROGRAM_EXITED.rc;
164          sw_printf("[%s:%u] - Process %d %s with %d\n", 
165                    __FILE__, __LINE__, pid, 
166                    ev.dbg == dbg_exited ? "exited" : "crashed",
167                    ev.data.idata);
168          break;
169       case SIGNAL_ENCOUNTERED:
170          sw_printf("[%s:%u] - Process %d stopped with %d\n",
171                    __FILE__, __LINE__, pid, msg.dataArea.SIGNAL_ENCOUNTERED.signal);
172          ev.proc->initial_thread->setStopped(true);
173          
174          ev.dbg = dbg_stopped;
175          sig_encountered = msg.dataArea.SIGNAL_ENCOUNTERED.signal;
176          if (sig_encountered == SINGLE_STEP_SIG)
177             sig_encountered = 0;
178          ev.data.idata = msg.dataArea.SIGNAL_ENCOUNTERED.signal;
179          break;
180       case ATTACH_ACK:
181          sw_printf("[%s:%u] - Process %d acknowledged attach\n",
182                    __FILE__, __LINE__, pid);
183          ev.dbg = dbg_attached;
184          break;
185       case CONTINUE_ACK:
186          sw_printf("[%s:%u] - Process %d acknowledged continue\n", 
187                    __FILE__, __LINE__, pid);
188          ev.dbg = dbg_continued;
189          break;
190       case KILL_ACK:
191          sw_printf("[%s:%u] - Process %d acknowledged kill\n", 
192                    __FILE__, __LINE__, pid);
193          ev.dbg = dbg_other;
194          break;
195       case GET_ALL_REGS_ACK:
196          sw_printf("[%s:%u] - RegisterAll ACK on pid %d\n", 
197                    __FILE__, __LINE__, pid);
198          ev.dbg = dbg_allregs_ack;
199          ev.size = msg.header.dataLength;
200          procbg->gprs = msg.dataArea.GET_ALL_REGS_ACK.gprs;
201          break;
202       case GET_MEM_ACK:
203          sw_printf("[%s:%u] - Memread ACK on pid %d\n", 
204                    __FILE__, __LINE__, pid);
205          ev.dbg = dbg_mem_ack;
206          ev.size = msg.header.dataLength;
207          ev.data.pdata = (void *) malloc(msg.header.dataLength);
208          assert(ev.data.pdata);
209          memcpy(ev.data.pdata, &msg.dataArea, msg.header.dataLength);
210          break;
211       case SINGLE_STEP_ACK:
212          sw_printf("[%s:%u] - Process %d recieved SINGLE_STEP\n",
213                    __FILE__, __LINE__, pid, ev.data);
214          assert(!ev.proc->initial_thread->isStopped());
215          ev.proc->initial_thread->setStopped(true);
216          
217          ev.dbg = dbg_stopped;
218          ev.data.idata = 0;
219          break;
220       default:
221          sw_printf("[%s:%u] - Unknown debug message: %d\n",
222                    __FILE__, __LINE__, msg.header.messageType);
223          ev.dbg = dbg_noevent;
224          break;
225    }
226    return ev;
227 }
228
229 bool ProcDebugBG::debug_handle_event(DebugEvent ev)
230 {
231   bool result;
232
233   switch (ev.dbg)
234   {
235      case dbg_stopped:
236         initial_thread->setStopped(true);        
237         
238         if (state() == ps_attached_intermediate) {
239            sw_printf("[%s:%u] - Moving %d to state running\n", 
240                      __FILE__, __LINE__, pid);
241            setState(ps_attached);
242            return true;
243         }
244         
245         if (ev.data.idata == SINGLE_STEP_SIG) {
246            if (!initial_thread->userIsStopped()) {
247               sw_printf("[%s:%u] - handling dbg_stopped SINGLE_STEP on %d\n",
248                         __FILE__, __LINE__, pid);
249               ev.data.idata = 0;
250               result = debug_handle_signal(&ev);
251            }
252         }
253         else if (ev.data.idata != SIGSTOP) {
254            sw_printf("[%s:%u] - handling dbg_stopped SINGLE_STEP on %d\n",
255                      __FILE__,__LINE__, pid);
256            result = debug_handle_signal(&ev);
257            if (!result) {
258               sw_printf("[%s:%u] - Debug continue failed on %d with %d\n", 
259                         __FILE__, __LINE__, pid, ev.data.idata);
260               return false;
261            }
262         }
263         return true;
264     case dbg_crashed:
265       sw_printf("[%s:%u] - Handling process crash on %d\n",
266                 __FILE__, __LINE__, pid);
267     case dbg_exited:
268       sw_printf("[%s:%u] - Handling process death on %d\n",
269                 __FILE__, __LINE__, pid);
270       setState(ps_exited);
271       return true;
272     case dbg_continued:
273        sw_printf("[%s:%u] - Process %d continued\n", __FILE__, __LINE__, pid);
274        clear_cache();
275        assert(initial_thread->isStopped());
276        initial_thread->setStopped(false);
277        break;
278     case dbg_attached:
279        sw_printf("[%s:%u] - Process %d attached\n", __FILE__, __LINE__, pid);
280        assert(state() == ps_neonatal);
281        setState(ps_attached_intermediate);
282        debug_pause(NULL); //TODO or not TODO?
283        break;
284     case dbg_mem_ack:
285        sw_printf("[%s:%u] - Process %d returned a memory chunck of size %u", 
286                  __FILE__, __LINE__, pid, ev.size);
287        assert(!mem_data);
288        mem_data = ev.data.pdata;
289        mem_data_size = ev.size;
290     case dbg_allregs_ack:
291        sw_printf("[%s:%u] - Process %d returned a register chunck of size %u", 
292                  __FILE__, __LINE__, pid, ev.size);
293        gprs_set = true;
294        break;
295     case dbg_other:
296        sw_printf("[%s:%u] - Skipping unimportant event\n", __FILE__, __LINE__);
297        break;
298     case dbg_err:
299     case dbg_noevent:       
300     default:
301       sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d\n", 
302                 __FILE__, __LINE__, ev.dbg, pid);
303       setLastError(err_internal, "Told to handle an unexpected event.");
304       return false;
305   }
306   return true;
307 }
308
309 bool ProcDebugBG::debug_create(const std::string &, 
310                                const std::vector<std::string> &)
311 {
312   setLastError(err_unsupported, "Create mode not supported on BlueGene");
313   return false;
314 }
315
316 bool ProcDebugBG::debug_attach(ThreadState *)
317 {
318    BGL_Debugger_Msg msg(ATTACH, pid, 0, 0, 0);
319    msg.header.dataLength = sizeof(msg.dataArea.ATTACH);
320
321    sw_printf("[%s:%u] - Attaching to pid\n", __FILE__, __LINE__, pid);
322    bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
323    if (!result) {
324       sw_printf("[%s:%u] - Unable to attach to process %d\n",
325                 __FILE__, __LINE__, pid);
326       return false;
327    }
328    return true;
329 }
330
331 bool ProcDebugBG::debug_pause(ThreadState *)
332 {
333    BGL_Debugger_Msg msg(KILL, pid, 0, 0, 0);
334    msg.dataArea.KILL.signal = SIGSTOP;
335    msg.header.dataLength = sizeof(msg.dataArea.KILL);
336
337    sw_printf("[%s:%u] - Sending SIGSTOP to pid %d\n", __FILE__, __LINE__, pid);
338    bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
339
340    if (!result) {
341       sw_printf("[%s:%u] - Unable to send SIGSTOP to process %d\n",
342                 __FILE__, __LINE__, pid);
343       return false;
344    }
345    return true;
346 }
347
348 bool ProcDebugBG::debug_continue(ThreadState *)
349 {
350    return debug_continue_with(NULL, 0);
351 }
352
353 bool ProcDebugBG::debug_continue_with(ThreadState *, long sig)
354 {
355    assert(initial_thread->isStopped());
356    BGL_Debugger_Msg msg(CONTINUE, pid, 0, 0, 0);
357    msg.dataArea.CONTINUE.signal = sig;
358    msg.header.dataLength = sizeof(msg.dataArea.CONTINUE);
359
360
361    sw_printf("[%s:%u] - Sending signal %d to pid %d\n", __FILE__, __LINE__, sig, pid);
362    bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
363    if (!result) {
364       sw_printf("[%s:%u] - Unable to send %d to process %d\n",
365                 __FILE__, __LINE__, sig, pid);
366       return false;
367    }
368    return true;
369 }
370
371 bool ProcDebugBG::debug_handle_signal(DebugEvent *ev)
372 {
373    assert(ev->dbg == dbg_stopped);
374    sw_printf("[%s:%u] - Handling signal for pid %d\n", 
375              __FILE__, __LINE__, pid);
376    return debug_continue_with(NULL, ev->data.idata);
377 }
378
379 #if !defined(BGL_READCACHE_SIZE)
380 #define BGL_READCACHE_SIZE 2048
381 #endif
382
383 bool ProcDebugBG::readMem(void *dest, Address source, size_t size)
384 {
385    unsigned char *ucdest = (unsigned char *) dest;
386    bool result;
387
388    for (;;)
389    {
390       if (size == 0)
391          return true;
392
393       sw_printf("[%s:%u] - Reading memory from 0x%lx to 0x%lx (into %p)\n",
394                 __FILE__, __LINE__, source, source+size, ucdest);
395       if (source >= read_cache_start && 
396           source+size < read_cache_start + read_cache_size)
397       {
398          //Lucky us, we have everything cached.
399          memcpy(ucdest, read_cache + (source - read_cache_start), size);
400          return true;
401       }
402       if (source >= read_cache_start &&
403           source < read_cache_start + read_cache_size)
404       {
405          //The beginning is in the cache, read those bytes
406          long cached_bytes = read_cache_start + read_cache_size - source;
407          memcpy(ucdest, read_cache + (source - read_cache_start), cached_bytes);
408          //Change the parameters and continue the read (this is a kind of
409          // optimized tail call).
410          ucdest += cached_bytes;
411          source = read_cache_start + read_cache_size;
412          size -= cached_bytes;
413          continue;
414       }
415       if (source+size > read_cache_start &&
416           source+size <= read_cache_start + read_cache_size)
417       {
418          //The end is in the cache, read those bytes
419          long cached_bytes = (source+size) - read_cache_start;
420          memcpy(ucdest + read_cache_start - source, read_cache, cached_bytes);
421          //Change the parameters and continue the read (this is a kind of
422          // optimized tail call).
423          size -= cached_bytes;
424          continue;
425       }
426       if (source < read_cache_start &&
427           source+size >= read_cache_start+read_cache_size)
428       {
429          //The middle is in the cache
430          unsigned char *dest_start = ucdest + read_cache_start - source;
431          Address old_read_cache_start = read_cache_start;
432          memcpy(dest_start, read_cache, read_cache_size);
433          //Use actual recursion here, as we need to queue up two reads
434          // First read out of the high memory with recursion
435          result = readMem(dest_start + read_cache_size, 
436                           read_cache_start+read_cache_size,
437                           source+size - read_cache_start+read_cache_size);
438          if (!result) {
439             return false;
440          }
441          // Now read out of the low memory
442          size = old_read_cache_start - source;
443          continue;
444       }
445       //The memory isn't cached, read a new cache'd page.
446       assert(source < read_cache_start || 
447              source >= read_cache_start+read_cache_size);
448       
449       if (!read_cache) {
450          read_cache = (unsigned char *) malloc(BGL_READCACHE_SIZE);
451          assert(read_cache);
452       }
453
454       read_cache_size = BGL_READCACHE_SIZE;
455       read_cache_start = source - (source % read_cache_size);
456       sw_printf("[%s:%u] - Caching memory from 0x%lx to 0x%lx\n",
457              __FILE__, __LINE__, read_cache_start, 
458              read_cache_start+read_cache_size);
459                     
460       //Read read_cache_start to read_cache_start+read_cache_size into our
461       // cache.
462       assert(!mem_data);
463       assert(read_cache_size < BGL_Debugger_Msg_MAX_MEM_SIZE);
464
465       BGL_Debugger_Msg msg(GET_MEM, pid, 0, 0, 0);
466       msg.header.dataLength = sizeof(msg.dataArea.GET_MEM);
467       msg.dataArea.GET_MEM.addr = read_cache_start;
468       msg.dataArea.GET_MEM.len = read_cache_size;
469       bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
470       if (!result) {
471          sw_printf("[%s:%u] - Unable to write to process %d\n",
472                    __FILE__, __LINE__, pid);
473          return true;
474       }
475       
476       //Wait for the read to return
477       sw_printf("[%s:%u] - Waiting for read to return on pid %d\n",
478                 __FILE__, __LINE__);
479       do {
480          bool handled, result;
481          result = debug_wait_and_handle(true, handled);
482          if (!result)
483          {
484             sw_printf("[%s:%u] - Error while waiting for read to return\n",
485                       __FILE__, __LINE__);
486             return false;
487          }
488       } while (!mem_data);
489
490       //TODO: How do we detect errors?
491       BGL_Debugger_Msg::DataArea *da = (BGL_Debugger_Msg::DataArea *) mem_data;
492       assert(da->GET_MEM_ACK.addr == read_cache_start);
493       assert(da->GET_MEM_ACK.len == read_cache_size);
494       memcpy(read_cache, da->GET_MEM_ACK.data, read_cache_size);
495       
496       //Free up the memory data
497       free(mem_data);
498       mem_data = NULL;
499    }
500 }   
501
502 bool ProcDebugBG::getThreadIds(std::vector<THR_ID> &threads)
503 {
504    threads.clear();
505    threads.push_back((THR_ID) 0);
506    return true;
507 }
508
509 bool ProcDebugBG::getDefaultThread(THR_ID &default_tid)
510 {
511    default_tid = (THR_ID) 0;
512    return true;
513 }
514
515 unsigned ProcDebugBG::getAddressWidth()
516 {
517    return sizeof(long);
518 }
519
520 bool ProcDebugBG::getRegValue(Dyninst::MachRegister reg, Dyninst::THR_ID, Dyninst::MachRegisterVal &val)
521 {
522
523    if (!gprs_set)
524    {
525       BGL_Debugger_Msg msg(GET_ALL_REGS, pid, 0, 0, 0);
526       msg.header.dataLength = sizeof(msg.dataArea.GET_ALL_REGS);
527       bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
528       if (!result) {
529          sw_printf("[%s:%u] - Unable to write to process %d\n",
530                    __FILE__, __LINE__, pid);
531          return true;
532       }
533       
534       //Wait for the read to return
535       sw_printf("[%s:%u] - Waiting for read to return on pid %d\n",
536                 __FILE__, __LINE__);
537       do {
538          bool handled, result;
539          result = debug_wait_and_handle(true, handled);
540          if (!result)
541          {
542             sw_printf("[%s:%u] - Error while waiting for read to return\n",
543                       __FILE__, __LINE__);
544             return false;
545          }
546       } while (!gprs_set);
547    }
548    
549    switch(reg)
550    {
551       case Dyninst::MachRegStackBase:
552          val = 0x0;
553          break;
554       case Dyninst::MachRegFrameBase:
555          val = gprs.gpr[BGL_GPR1];
556          break;
557       case Dyninst::MachRegPC:
558          val = gprs.iar;
559          break;
560       default:
561          sw_printf("[%s:%u] - Request for unsupported register %d\n",
562                    __FILE__, __LINE__, reg);
563          setLastError(err_badparam, "Unknown register passed in reg field");
564          return false;
565    }   
566    return true;
567 }
568
569 ProcDebugBG::~ProcDebugBG()
570 {
571 }
572
573 ProcDebugBG::ProcDebugBG(PID pid)
574    : ProcDebug(pid),
575      mem_data(NULL),
576      mem_data_size(0),
577      gprs_set(false),
578      read_cache(NULL),
579      read_cache_start(0x0),
580      read_cache_size(0x0)
581 {
582 }
583
584 ProcDebug *ProcDebug::newProcDebug(const std::string &, 
585                                    const std::vector<std::string> &)
586 {
587   setLastError(err_unsupported, "Executable launch not supported on BlueGene");
588   return NULL;
589 }
590
591 ProcDebug *ProcDebug::newProcDebug(PID pid)
592 {
593    ProcDebug *pd = new ProcDebugBG(pid);
594    if (!pd)
595    {
596       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
597                 __FILE__, __LINE__);
598       if (pd)
599          delete pd;
600       return NULL;
601    }
602
603    bool result = pd->attach();
604    if (!result || pd->state() != ps_running && pd->state() != ps_attached) {
605      pd->setState(ps_errorstate);
606      proc_map.erase(pid);
607      sw_printf("[%s:%u] - Error attaching to process %d\n",
608                __FILE__, __LINE__, pid);
609      delete pd;
610      return NULL;
611    }
612
613    return pd;
614 }
615
616 bool ProcDebug::newProcDebugSet(const vector<Dyninst::PID> &pids,
617                                 vector<ProcDebug *> &out_set)
618 {
619    bool result;
620    vector<Dyninst::PID>::const_iterator i;
621    for (i=pids.begin(); i!=pids.end(); i++)
622    {
623       Dyninst::PID pid = *i;
624       ProcDebug *new_pd = new ProcDebugBG(pid);
625       if (!new_pd) {
626          fprintf(stderr, "[%s:%u] - Unable to allocate new ProcDebugBG\n",
627                  __FILE__, __LINE__);
628          return false;
629       }
630       out_set.push_back(new_pd);
631    }
632
633    result = multi_attach(out_set);
634    return result;
635 }
636
637 bool Walker::createDefaultSteppers()
638 {
639   FrameStepper *stepper;
640   bool result;
641
642   stepper = new FrameFuncStepper(this);
643   result = addStepper(stepper);
644   if (!result) {
645     sw_printf("[%s:%u] - Error adding stepper %p\n", __FILE__, __LINE__,
646               stepper);
647     return false;
648   }
649
650   return true;
651 }
652
653 bool BGL_Debugger_Msg::writeOnFd(int fd, 
654                                  DebuggerInterface::BGL_Debugger_Msg &msg)
655 {
656    int result;
657    result = write(fd, &msg.header, sizeof(msg.header));
658    if (result != -1) {
659       result = write(fd, &msg.dataArea, msg.header.dataLength);
660    }
661
662    if (result == -1) {
663       int errnum = errno;
664       sw_printf("[%s:%u] - Error writing to process: %s\n", 
665                 __FILE__, __LINE__, strerror(errnum));
666       setLastError(err_internal, "Error writing message to process");
667       return false;
668    }
669    
670    return true;
671 }
672
673 bool BGL_Debugger_Msg::readFromFd(int fd, 
674                                   DebuggerInterface::BGL_Debugger_Msg &msg)
675 {
676    int result;
677    result = read(fd, &msg.header, sizeof(msg.header));
678    if (result != -1 && msg.header.dataLength) {
679       result = read(fd, &msg.dataArea, msg.header.dataLength);
680    }
681    if (result == -1) {
682       int errnum = errno;
683       sw_printf("[%s:%u] - Error reading from process: %s\n", 
684                 __FILE__, __LINE__, strerror(errnum));
685       setLastError(err_internal, "Error reading message from process");
686       return false;
687    }
688    return true;
689 }
690
691 bool ProcSelf::readMem(void *dest, Address source, size_t size)
692 {
693    memcpy(dest, (void *) source, size);
694    return true;
695 }
696
697 int ProcDebug::getNotificationFD() {
698   return BGL_DEBUGGER_READ_PIPE;
699 }
700
701 void ProcDebugBG::clear_cache()
702 {
703   gprs_set = false;
704   read_cache_start = 0x0;
705   read_cache_size = 0x0;
706   mem_data = NULL;
707   mem_data_size = 0x0;
708 }
709
710 bool ProcDebugBG::debug_waitfor_version_msg()
711 {
712    sw_printf("[%s:%u] - At debug_waitfor_Version_msg, isStopped = %d\n",
713              __FILE__, __LINE__, initial_thread->isStopped());
714    bool handled, result;
715    
716    result = debug_wait_and_handle(true, handled);
717    if (!result || state() == ps_errorstate) {
718       sw_printf("[%s:%u] - Error,  Process %d errored during version_msg\n",
719                 __FILE__, __LINE__, pid);
720       return false;
721    }
722    if (state() == ps_exited) {
723       sw_printf("[%s:%u] - Error.  Process %d exited during version_msg\n",
724                 __FILE__, __LINE__, pid);
725       return false;
726    }
727    sw_printf("[%s:%u] - Successfully version_msg %d\n",
728              __FILE__, __LINE__, pid);
729    return true;      
730 }
731
732 bool ProcDebugBG::debug_version_msg()
733 {
734   BGL_Debugger_Msg msg(VERSION_MSG, pid, 0, 0, 0);
735   msg.header.dataLength = sizeof(msg.dataArea.VERSION_MSG);
736
737   sw_printf("[%s:%u] - Sending VERSION_MSG to pid %d\n", __FILE__, __LINE__, pid);
738   bool result = BGL_Debugger_Msg::writeOnFd(BGL_DEBUGGER_WRITE_PIPE, msg);
739
740   if (!result) {
741      sw_printf("[%s:%u] - Unable to send VERSION_MSG to process %d\n",
742                __FILE__, __LINE__, pid);
743      return false;
744   }
745   return true;
746 }
747
748 bool ProcDebugBG::version_msg()
749 {
750    bool result = debug_version_msg();
751    if (!result) {
752       sw_printf("[%s:%u] - Could not version msg debugee %d\n",
753                 __FILE__, __LINE__, pid);
754       return false;
755    }
756    
757    result = debug_waitfor_version_msg();
758    if (state() == ps_exited) {
759       setLastError(err_procexit, "Process exited unexpectedly during version_msg");
760       return false;
761    }
762    if (!result) {
763       sw_printf("[%s:%u] - Error during process version_msg for %d\n",
764                 __FILE__, __LINE__, pid);
765       return false;
766    }   
767    return true;
768 }
769
770 ThreadState* ThreadState::createThreadState(ProcDebug *parent,
771                                             Dyninst::THR_ID,
772                                             bool)
773 {
774    ThreadState *ts = new ThreadState(parent, 0);
775    return ts;
776 }
777
778 bool SymtabLibState::updateLibsArch()
779 {
780    return true;
781 }
782
783 SigHandlerStepper::SigHandlerStepper(Walker *w) :
784    FrameStepper(w)
785 {
786    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported platform\n",
787              __FILE__, __LINE__);
788    assert(0);
789 }
790
791 gcframe_ret_t SigHandlerStepper::getCallerFrame(const Frame &, Frame &)
792 {
793    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported platform\n",
794              __FILE__, __LINE__);
795    assert(0);
796    return gcf_error;
797 }
798
799 unsigned SigHandlerStepper::getPriority() const
800 {
801    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported platform\n",
802              __FILE__, __LINE__);
803    assert(0);
804    return 0;
805 }
806
807 void SigHandlerStepper::registerStepperGroup(StepperGroup *)
808 {
809    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported "
810              "platform\n",  __FILE__, __LINE__);
811    assert(0);
812 }
813
814 SigHandlerStepper::~SigHandlerStepper()
815 {
816    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported "
817              "platform\n",  __FILE__, __LINE__);
818    assert(0);
819 }