stackwalk: Fix Coverity UNINIT_CTOR errors
[dyninst.git] / stackwalk / src / sw_pcontrol.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "stackwalk/h/procstate.h"
32 #include "stackwalk/h/swk_errors.h"
33 #include "stackwalk/h/walker.h"
34 #include "stackwalk/h/steppergroup.h"
35
36 #include "proccontrol/h/PCProcess.h"
37 #include "proccontrol/h/ProcessSet.h"
38 #include "proccontrol/h/PlatFeatures.h"
39 #include "proccontrol/h/PCErrors.h"
40
41 #include "common/h/dyn_regs.h"
42 #include "common/h/SymReader.h"
43
44 #include "stackwalk/src/libstate.h"
45 #include "stackwalk/src/sw.h"
46 #include "common/src/IntervalTree.h"
47 #include <vector>
48
49 using namespace Dyninst;
50 using namespace ProcControlAPI;
51 using namespace Stackwalker;
52 using namespace std;
53
54 class PCLibraryState : public LibraryState {
55 private:
56    ProcDebug *pdebug;
57
58    typedef std::pair<LibAddrPair, Library::ptr> cache_t;
59
60    IntervalTree<Address, cache_t> loadedLibs;
61
62    cache_t makeCache(LibAddrPair a, Library::ptr b) { return std::make_pair(a, b); }
63    bool findInCache(Process::ptr proc, Address addr, LibAddrPair &lib);
64    void removeLibFromCache(cache_t element);
65
66 public:
67    PCLibraryState(ProcessState *pd);
68    ~PCLibraryState();
69
70    bool checkLibraryContains(Address addr, Library::ptr lib);
71    virtual bool getLibraryAtAddr(Address addr, LibAddrPair &lib);
72    virtual bool getLibraries(std::vector<LibAddrPair> &libs, bool allow_refresh);
73    virtual void notifyOfUpdate();
74    virtual Address getLibTrapAddress();
75    virtual bool getAOut(LibAddrPair &ao);
76   
77    bool updateLibraries();
78    bool cacheLibraryRanges(Library::ptr lib);
79    bool memoryScan(Process::ptr proc, Address addr, LibAddrPair &lib);
80
81    void checkForNewLib(Library::ptr lib);
82 };
83
84 ProcDebug::ProcDebug(Process::ptr p) :
85    ProcessState(p->getPid()),
86    proc(p)
87 {
88 }
89
90 ProcDebug *ProcDebug::newProcDebug(PID pid, std::string executable)
91 {
92    Process::ptr proc = Process::attachProcess(pid, executable);
93    if (!proc) {
94       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
95       sw_printf("[%s:%u] - ProcControl error creating process\n", __FILE__, __LINE__);
96       return NULL;
97    }
98    
99    return newProcDebug(proc);
100 }
101
102 ProcDebug *ProcDebug::newProcDebug(Dyninst::ProcControlAPI::Process::ptr proc)
103 {
104    ProcDebug *pd = new ProcDebug(proc);
105    pd->library_tracker = new PCLibraryState(pd);
106
107    return pd;
108 }
109
110 bool ProcDebug::newProcDebugSet(const std::vector<PID> &pids,
111                                 std::vector<ProcDebug *> & out_set)
112 {
113    for (vector<PID>::const_iterator i = pids.begin(); i != pids.end(); i++) {
114       ProcDebug *pd = ProcDebug::newProcDebug(*i);
115       if (!pd)
116          return false;
117       out_set.push_back(pd);
118    }
119    return true;
120 }
121
122 ProcDebug *ProcDebug::newProcDebug(std::string executable, 
123                                    const std::vector<std::string> &argv)
124 {
125    Process::ptr proc = Process::createProcess(executable, argv);
126    if (!proc) {
127       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
128       sw_printf("[%s:%u] - ProcControl error creating process\n", __FILE__, __LINE__);
129       return NULL;
130    }
131
132    ProcDebug *pd = new ProcDebug(proc);
133    pd->library_tracker = new PCLibraryState(pd);
134    
135    return pd;
136 }
137
138 ProcDebug::~ProcDebug()
139 {
140    if (library_tracker)
141       delete library_tracker;
142    library_tracker = NULL;
143 }
144
145 #define CHECK_PROC_LIVE_RET(val) \
146    do { \
147    if (!proc || proc->isTerminated()) { \
148      sw_printf("[%s:%u] - operation on exited process\n", __FILE__, __LINE__); \
149      Stackwalker::setLastError(err_procexit, "Process has exited or been detached"); \
150      return (val); \
151    } \
152    } while (0)
153 #define CHECK_PROC_LIVE CHECK_PROC_LIVE_RET(false)
154
155 bool ProcDebug::getRegValue(MachRegister reg, THR_ID thread, 
156                             MachRegisterVal &val)
157 {
158    CHECK_PROC_LIVE;
159    if (reg == FrameBase) {
160       reg = MachRegister::getFramePointer(getArchitecture());
161    }
162    else if (reg == ReturnAddr) {
163       reg = MachRegister::getPC(getArchitecture());
164    }
165    else if (reg == StackTop) {
166       reg = MachRegister::getStackPointer(getArchitecture());
167    }
168    ThreadPool::iterator thrd_i = proc->threads().find(thread);
169    if (thrd_i == proc->threads().end()) {
170       sw_printf("[%s:%u] - Invalid thread ID to getRegValue\n", __FILE__, __LINE__);
171       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
172       return false;
173    }
174    Thread::ptr thrd = *thrd_i;
175    bool result = thrd->getRegister(reg, val);
176    if (!result) {
177       sw_printf("[%s:%u] - ProcControlAPI error reading register\n", __FILE__, __LINE__);
178       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
179    }
180    return result;
181 }
182
183 bool ProcDebug::readMem(void *dest, Address source, size_t size)
184 {
185    CHECK_PROC_LIVE;
186    bool result = proc->readMemory(dest, source, size);
187    if (!result) {
188      sw_printf("[%s:%u] - ProcControlAPI error reading memory at 0x%lx\n", __FILE__, __LINE__, source);
189       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
190    }
191    return result;
192 }
193
194 bool ProcDebug::getThreadIds(std::vector<THR_ID> &thrds)
195 {
196    CHECK_PROC_LIVE;
197    ThreadPool::iterator i = proc->threads().begin();
198    for (; i != proc->threads().end(); i++) {
199       thrds.push_back((*i)->getLWP());
200    }
201    return true;
202 }
203
204 bool ProcDebug::getDefaultThread(THR_ID &default_tid)
205 {
206    CHECK_PROC_LIVE;
207    default_tid = proc->threads().getInitialThread()->getLWP();
208    return true;
209 }
210
211 unsigned ProcDebug::getAddressWidth() 
212 {
213    CHECK_PROC_LIVE;
214    return getArchAddressWidth(proc->getArchitecture());
215 }
216
217 bool ProcDebug::preStackwalk(THR_ID tid)
218 {
219    CHECK_PROC_LIVE;
220    if (tid == NULL_THR_ID)
221       getDefaultThread(tid);
222    sw_printf("[%s:%u] - Calling preStackwalk for thread %d\n", __FILE__, __LINE__, tid);
223    
224    ThreadPool::iterator thread_iter = proc->threads().find(tid);
225    if (thread_iter == proc->threads().end()) {
226       sw_printf("[%s:%u] - Stackwalk on non-existant thread\n", __FILE__, __LINE__);
227       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
228       return false;     
229    }
230    Thread::ptr active_thread = *thread_iter;
231
232    if (active_thread->isRunning()) {
233       sw_printf("[%s:%u] - Stopping running thread %d\n", __FILE__, __LINE__, tid);
234       bool result = active_thread->stopThread();
235       if (!result) {
236          sw_printf("[%s:%u] - Error stopping thread\n", __FILE__, __LINE__);
237          Stackwalker::setLastError(err_proccontrol, "Could not stop thread for stackwalk\n");
238          return false;
239       }
240       needs_resume.insert(active_thread);
241    }
242    return true;
243 }   
244
245 bool ProcDebug::postStackwalk(THR_ID tid)
246 {
247    CHECK_PROC_LIVE;
248    if (tid == NULL_THR_ID)
249       getDefaultThread(tid);
250    sw_printf("[%s:%u] - Calling postStackwalk for thread %d\n", __FILE__, __LINE__, tid);
251    
252    ThreadPool::iterator thread_iter = proc->threads().find(tid);
253    if (thread_iter == proc->threads().end()) {
254       sw_printf("[%s:%u] - Stackwalk on non-existant thread\n", __FILE__, __LINE__);
255       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
256       return false;     
257    }
258    Thread::ptr active_thread = *thread_iter;
259    
260    set<Thread::ptr>::iterator i = needs_resume.find(active_thread);
261    if (i != needs_resume.end()) {
262       sw_printf("[%s:%u] - Resuming thread %d after stackwalk\n", __FILE__, __LINE__, tid);
263       bool result = active_thread->continueThread();
264       if (!result) {
265          sw_printf("[%s:%u] - Error resuming stopped thread %d\n", __FILE__, __LINE__, tid);
266          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
267          return false;
268       }
269       needs_resume.erase(i);
270    }
271    return true;
272 }
273   
274 bool ProcDebug::pause(THR_ID tid)
275 {
276    CHECK_PROC_LIVE;
277    if (tid == NULL_THR_ID) {
278       sw_printf("[%s:%u] - Stopping process %d\n", __FILE__, __LINE__, proc->getPid());
279
280       bool result = proc->stopProc();
281       if (!result) {
282          sw_printf("[%s:%u] - Error stopping process %d\n", 
283                    __FILE__, __LINE__, proc->getPid());
284          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
285          return false;
286       }
287       return true;
288    }
289
290    ThreadPool::iterator thread_iter = proc->threads().find(tid);
291    if (thread_iter == proc->threads().end()) {
292       sw_printf("[%s:%u] - stop on non-existant thread\n", __FILE__, __LINE__);
293       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
294       return false;     
295    }
296    Thread::ptr thread = *thread_iter;
297    sw_printf("[%s:%u] - Stopping thread %d\n", __FILE__, __LINE__, tid);
298
299    if (thread->isStopped()) {
300       sw_printf("[%s:%u] - Thread %d is already stopped\n", __FILE__, __LINE__, tid);
301       return true;
302    }
303
304    bool result = thread->stopThread();
305    if (!result) {
306       sw_printf("[%s:%u] - Error stopping thread %d\n", __FILE__, __LINE__, tid);
307       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
308       return false;
309    }
310    
311    return true;
312 }
313
314 bool ProcDebug::resume(THR_ID tid)
315 {
316    CHECK_PROC_LIVE;
317    if (tid == NULL_THR_ID) {
318       sw_printf("[%s:%u] - Running process %d\n", __FILE__, __LINE__, proc->getPid());
319
320       bool result = proc->continueProc();
321       if (!result) {
322          sw_printf("[%s:%u] - Error running process %d\n", 
323                    __FILE__, __LINE__, proc->getPid());
324          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
325          return false;
326       }
327       return true;
328    }
329
330    ThreadPool::iterator thread_iter = proc->threads().find(tid);
331    if (thread_iter == proc->threads().end()) {
332       sw_printf("[%s:%u] - continue on non-existant thread\n", __FILE__, __LINE__);
333       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
334       return false;     
335    }
336    Thread::ptr thread = *thread_iter;
337    sw_printf("[%s:%u] - Running thread %d\n", __FILE__, __LINE__, tid);
338
339    if (thread->isRunning()) {
340       sw_printf("[%s:%u] - Thread %d is already running\n", __FILE__, __LINE__, tid);
341       return true;
342    }
343
344    bool result = thread->continueThread();
345    if (!result) {
346       sw_printf("[%s:%u] - Error running thread %d\n", __FILE__, __LINE__, tid);
347       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
348       return false;
349    }
350    
351    return true;
352 }
353
354 bool ProcDebug::isTerminated()
355 {
356    return (!proc || proc->isTerminated());
357 }
358
359 bool ProcDebug::detach(bool leave_stopped)
360 {
361    CHECK_PROC_LIVE;   
362    bool result = proc->detach(leave_stopped);
363    if (!result) {
364       sw_printf("[%s:%u] - Error detaching from process %d\n", __FILE__, __LINE__, 
365                 proc->getPid());
366       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
367       return false;
368    }
369    return true;
370 }
371
372 int ProcDebug::getNotificationFD()
373 {
374    return -1;
375 }
376
377 std::string ProcDebug::getExecutablePath()
378 {
379    CHECK_PROC_LIVE_RET("");
380    return proc->libraries().getExecutable()->getName();
381 }
382
383 bool ProcDebug::handleDebugEvent(bool block)
384 {
385    bool result = Process::handleEvents(block);
386    if (!result) {
387       sw_printf("[%s:%u] - Error handling debug events\n", __FILE__, __LINE__);
388       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
389       return false;
390    }
391    return true;
392 }
393
394 bool ProcDebug::isFirstParty()
395 {
396    return false;
397 }
398
399 Architecture ProcDebug::getArchitecture()
400 {
401    return proc->getArchitecture();
402 }
403
404 Process::ptr ProcDebug::getProc()
405 {
406    return proc;
407 }
408
409 PCLibraryState::PCLibraryState(ProcessState *pd) :
410    LibraryState(pd)
411 {
412    pdebug = static_cast<ProcDebug *>(pd);
413 }
414    
415 PCLibraryState::~PCLibraryState()
416 {
417 }
418  
419 bool PCLibraryState::cacheLibraryRanges(Library::ptr lib)
420 {
421    std::string filename = lib->getName();
422    Address base = lib->getLoadAddress();
423
424    SymbolReaderFactory *fact = getDefaultSymbolReader();
425    SymReader *reader = fact->openSymbolReader(filename);
426    if (!reader) {
427       sw_printf("[%s:%u] - Error could not open expected file %s\n", 
428                 __FILE__, __LINE__, filename.c_str());
429       return false;
430    }
431
432    int num_segments = reader->numSegments();
433    for (int i=0; i<num_segments; i++) {
434       SymSegment segment;
435       reader->getSegment(i, segment);
436       if (segment.type != 1) continue;
437       Address segment_start = segment.mem_addr + base;
438       Address segment_end = segment_start + segment.mem_size;
439
440       loadedLibs.insert(segment_start, segment_end, 
441                         makeCache(LibAddrPair(lib->getName(), 
442                                               lib->getLoadAddress()), 
443                                   lib));
444    }
445    return true;
446 }
447
448 bool PCLibraryState::findInCache(Process::ptr proc, Address addr, LibAddrPair &lib) {
449    cache_t tmp;
450
451    if (!loadedLibs.find(addr, tmp)) { 
452       return false;
453    }   
454
455    Library::ptr lib_ptr = tmp.second;
456    if (proc->libraries().find(lib_ptr) != proc->libraries().end()) {
457       lib = tmp.first;
458       return true;
459    }
460    removeLibFromCache(tmp);
461    
462    return false;
463 }
464
465 void PCLibraryState::removeLibFromCache(cache_t element) {
466    IntervalTree<Address, cache_t>::iterator iter = loadedLibs.begin();
467
468    while(iter != loadedLibs.end()) {
469       // Can't use a for loop because I need to fiddle with
470       // increments manually.
471       cache_t found = iter->second.second;
472       if (found == element) {
473          IntervalTree<Address, cache_t>::iterator toDelete = iter;
474          ++iter;
475          loadedLibs.erase(toDelete->first);
476       }
477       else {
478          ++iter;
479       }
480    }
481 }
482
483 bool PCLibraryState::checkLibraryContains(Address addr, Library::ptr lib)
484 {
485    cacheLibraryRanges(lib);
486
487    cache_t tmp;
488
489    bool ret = loadedLibs.find(addr, tmp);
490    if (ret && tmp.second == lib)
491       return true;
492    return false;
493 }
494
495 void PCLibraryState::checkForNewLib(Library::ptr lib)
496 {
497    
498    if (lib->getData())
499       return;
500    sw_printf("[%s:%u] - Detected new library %s at %lx, notifying\n",
501              __FILE__, __LINE__, lib->getName().c_str(), lib->getLoadAddress());
502    
503    lib->setData((void *) 0x1);
504
505    StepperGroup *group = pdebug->getWalker()->getStepperGroup();
506    LibAddrPair la(lib->getName(), lib->getLoadAddress());
507
508    group->newLibraryNotification(&la, library_load);
509 }
510
511 /*
512 For a given address, 'addr', PCLibraryState::getLibraryAtAddr returns
513 the name and load address of the library/executable that loaded over
514 'addr'.
515
516 Traditionally when searching for the library that contains an address,
517 we would sequentially open each library, read its program headers and
518 see if that library contained the address.  This caused at-scale
519 performance problems on apps with lots of libraries, as we turned up
520 opening a lot of unnecessary files.
521
522 This function tries to be smarter.  It identifies the libraries that
523 most likely to contain our address, and then targets opens at them.
524 We do this by getting the dynamic address for each library (a pointer
525 given by the link map).  The dynamic address points to the library's
526 DYNAMIC section, which must be loaded into memory as specified by the
527 System V ABI.  We expect that the library containing addr will have a
528 nearby DYNAMIC pointer, and we check the two libraries with a DYNAMIC
529 pointer above and below addr.  One of these libraries should contain
530 addr.
531
532 If, for some reason, we fail to get a DYNAMIC section then we'll stash
533 that library away in 'zero_dynamic_libs' and check it when done.
534 */ 
535
536 bool PCLibraryState::getLibraryAtAddr(Address addr, LibAddrPair &lib)
537 {
538    Process::ptr proc = pdebug->getProc();
539    CHECK_PROC_LIVE;
540
541    /**
542     * An OS can have a list of platform-special libs (currently only the
543     * vsyscall DSO on Linux).  Those don't appear in the normal link_map
544     * and thus won't have dynamic addresses.  Check their library range 
545     * manually.
546     **/
547
548    vector<pair<LibAddrPair, unsigned int> > arch_libs;
549    updateLibsArch(arch_libs);
550    vector<pair<LibAddrPair, unsigned int> >::iterator j;
551    for (j = arch_libs.begin(); j != arch_libs.end(); j++) {
552       string name = (*j).first.first;
553       Address start = (*j).first.second;
554       Address size = (*j).second;
555       if (addr >= start && addr < start + size) {
556          lib.first = name;
557          lib.second = start;
558          return true;
559       }
560    }
561
562    /**
563     * Look up the address in our cache of libraries
564     **/
565
566    bool ret = findInCache(proc, addr, lib);
567    if (ret) {
568       return true;
569    }
570
571    /**
572     * Cache lookup failed. Instead of iterating over every library,
573     * look at the link map in memory. This allows us to avoid opening
574     * files.
575     **/
576
577    // Do a fast in-memory scan
578    ret = memoryScan(proc, addr, lib);
579    if (ret) {
580       return true;
581    }
582
583    return false;
584 }
585
586 bool PCLibraryState::memoryScan(Process::ptr proc, Address addr, LibAddrPair &lib) {
587    
588    LibraryPool::iterator i;
589    Library::ptr nearest_predecessor = Library::ptr();
590    signed int pred_distance = 0;
591    Library::ptr nearest_successor = Library::ptr();
592    signed int succ_distance = 0;
593
594
595    /**
596     * Search the entire library list for the dynamic sections that come
597     * directly before and after our target address (nearest_predecessor
598     * and nearest_successor).
599     *
600     * They dynamic linker (and who-knows-what on future systems) can have a 
601     * dynamic address of zero.  Remember any library with a zero dynamic
602     * address with zero_dynamic_libs, and manually check those if the
603     * nearest_successor and nearest_predecessor.
604     **/
605    std::vector<Library::ptr> zero_dynamic_libs;
606    for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
607    {
608       Library::ptr slib = *i;
609       checkForNewLib(slib);
610
611       Address dyn_addr = slib->getDynamicAddress();
612       if (!dyn_addr) {
613          zero_dynamic_libs.push_back(slib);
614          continue;
615       }
616
617       signed int distance = addr - dyn_addr;
618       if (distance == 0) {
619          lib.first = slib->getName();
620          lib.second = slib->getLoadAddress();
621          sw_printf("[%s:%u] - Found library %s contains address %lx\n",
622                    __FILE__, __LINE__, lib.first.c_str(), addr);
623          return true;
624       }
625       else if (distance < 0) {
626          if (!pred_distance || pred_distance < distance) {
627             nearest_predecessor = slib;
628             pred_distance = distance;
629          }
630       }
631       else if (distance > 0) {
632          if (!succ_distance || succ_distance > distance) {
633             nearest_successor = slib;
634             succ_distance = distance;
635          }
636       }
637    }
638
639    /**
640     * Likely a static binary, set nearest_predecessor so that
641     * the following check will test it.
642     **/
643    if (!nearest_predecessor && !nearest_successor) {
644       nearest_predecessor = proc->libraries().getExecutable();
645    }
646
647    /**
648     * Check if predessor contains our address first--this should be the typical case 
649     **/
650    if (nearest_predecessor && checkLibraryContains(addr, nearest_predecessor)) {
651       lib.first = nearest_predecessor->getName();
652       lib.second = nearest_predecessor->getLoadAddress();
653       sw_printf("[%s:%u] - Found library %s contains address %lx\n",
654                 __FILE__, __LINE__, lib.first.c_str(), addr);
655       return true;
656    }
657    /**
658     * Check successor
659     **/
660    if (nearest_successor && checkLibraryContains(addr, nearest_successor)) {
661       lib.first = nearest_successor->getName();
662       lib.second = nearest_successor->getLoadAddress();
663       sw_printf("[%s:%u] - Found library %s contains address %lx\n",
664                 __FILE__, __LINE__, lib.first.c_str(), addr);
665       return true;
666    }
667
668    /**
669     * The address wasn't located by the dynamic section tests.  Check
670     * any libraries without dynamic pointers, plus the executable.
671     **/
672    std::vector<Library::ptr>::iterator k = zero_dynamic_libs.begin();
673    for (; k != zero_dynamic_libs.end(); k++) {
674       if (checkLibraryContains(addr, *k)) {
675          lib.first = (*k)->getName();
676          lib.second = (*k)->getLoadAddress();
677          return true;
678       }
679    }
680    if(checkLibraryContains(addr, proc->libraries().getExecutable()))
681    {
682      
683      lib.first = proc->libraries().getExecutable()->getName();
684      lib.second = proc->libraries().getExecutable()->getLoadAddress();
685      sw_printf("[%s:%u] - Found executable %s contains address %lx\n", __FILE__,
686                __LINE__, lib.first.c_str(), addr);
687      return true;
688    }
689    
690    sw_printf("[%s:%u] - Could not find library for addr %lx\n", 
691              __FILE__, __LINE__, addr);
692    return false;
693 }
694
695 bool PCLibraryState::getLibraries(std::vector<LibAddrPair> &libs, bool allow_refresh)
696 {
697    Process::ptr proc = pdebug->getProc();
698    CHECK_PROC_LIVE;
699
700    LibraryPool::iterator i;   
701    for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
702    {
703       if (allow_refresh)
704          checkForNewLib(*i);
705       libs.push_back(LibAddrPair((*i)->getName(), (*i)->getLoadAddress()));
706    }
707
708    vector<pair<LibAddrPair, unsigned int> > arch_libs;
709    vector<pair<LibAddrPair, unsigned int> >::iterator j;
710    updateLibsArch(arch_libs);
711    for (j = arch_libs.begin(); j != arch_libs.end(); j++) {
712       libs.push_back(j->first);
713    }
714
715    return true;
716 }
717
718 bool PCLibraryState::updateLibraries()
719 {
720    Process::ptr proc = pdebug->getProc();
721    CHECK_PROC_LIVE;
722
723    LibraryPool::iterator i;   
724    for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
725    {
726       checkForNewLib(*i);
727    }
728
729    return true;
730 }
731
732 void PCLibraryState::notifyOfUpdate()
733 {
734 }
735
736 Address PCLibraryState::getLibTrapAddress()
737 {
738    return 0;
739 }
740
741 bool PCLibraryState::getAOut(LibAddrPair &ao)
742 {
743    Process::ptr proc = pdebug->getProc();
744    CHECK_PROC_LIVE;
745
746    Library::ptr lib = proc->libraries().getExecutable();
747    if (!lib) {
748       sw_printf("[%s:%u] - Could not get executable\n", __FILE__, __LINE__);
749       return false;
750    }
751    ao = LibAddrPair(lib->getName(), lib->getLoadAddress());
752    return true;
753 }
754
755 void int_walkerSet::addToProcSet(ProcDebug *pd)
756 {
757    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
758    Process::ptr proc = pd->getProc();
759    pset->insert(proc);
760 }
761
762 void int_walkerSet::eraseFromProcSet(ProcDebug *pd)
763 {
764    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
765    Process::ptr proc = pd->getProc();
766
767    ProcessSet::iterator i = pset->find(proc);
768    assert(i != pset->end());
769    pset->erase(i);
770 }
771
772 void int_walkerSet::clearProcSet()
773 {
774    ProcessSet::ptr *pset = (ProcessSet::ptr *) procset;
775    (*pset)->clear();
776    delete pset;
777    procset = NULL;
778 }
779
780 void int_walkerSet::initProcSet()
781 {
782    ProcessSet::ptr *p = new ProcessSet::ptr();
783    *p = ProcessSet::newProcessSet();
784    procset = (void *) p;
785 }
786
787 class StackCallback : public Dyninst::ProcControlAPI::CallStackCallback
788 {
789 private:
790    CallTree &tree;
791    FrameNode *cur;
792    Walker *cur_walker;
793 public:
794    StackCallback(CallTree &t);
795    virtual ~StackCallback();
796    
797    virtual bool beginStackWalk(Thread::ptr thr);
798    virtual bool addStackFrame(Thread::ptr thr, Dyninst::Address ra, Dyninst::Address sp, Dyninst::Address fp);
799    virtual void endStackWalk(Thread::ptr thr);
800 };
801
802 StackCallback::StackCallback(CallTree &t) :
803    tree(t),
804    cur(NULL),
805    cur_walker(NULL)
806 {
807    top_first = true;
808 }
809
810 StackCallback::~StackCallback()
811 {
812 }
813
814 bool StackCallback::beginStackWalk(Thread::ptr thr)
815 {
816    assert(!cur);
817    Process::ptr proc = thr->getProcess();
818    ProcessState *pstate = ProcessState::getProcessStateByPid(proc->getPid());
819    if (!pstate) {
820       sw_printf("[%s:%u] - Error, unknown process state for %d while starting stackwalk\n", 
821                 __FILE__, __LINE__, proc->getPid());
822       return false;
823    }
824
825    cur_walker = pstate->getWalker();
826    cur = tree.getHead();
827
828    return true;
829 }
830
831 bool StackCallback::addStackFrame(Thread::ptr thr,
832                                   Dyninst::Address ra, Dyninst::Address sp, Dyninst::Address fp)
833 {
834    Frame f(cur_walker);
835    f.setRA(ra);
836    f.setSP(sp);
837    f.setFP(fp);
838    f.setThread(thr->getLWP());
839    
840    cur = tree.addFrame(f, cur);
841    return true;
842 }
843
844 void StackCallback::endStackWalk(Thread::ptr thr) {
845    THR_ID thrd_lwp = thr->getLWP();
846    Frame *last_frame = cur->getFrame();
847    if (last_frame) {
848       last_frame->markTopFrame();
849    }
850    tree.addThread(thrd_lwp, cur, cur_walker, false);
851    cur = NULL;
852    cur_walker = NULL;
853 }
854
855 bool int_walkerSet::walkStacksProcSet(CallTree &tree, bool &bad_plat, bool walk_initial_only)
856 {
857    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
858    ThreadSet::ptr all_threads = ThreadSet::newThreadSet(pset, walk_initial_only);
859    StackCallback cbs(tree);
860
861    if (!all_threads->getCallStackUnwinding()) {
862       bad_plat = true;
863       return false;
864    }
865    return all_threads->getCallStackUnwinding()->walkStack(&cbs);
866 }