Infrastructure for SW CallTrees and group operations
[dyninst.git] / stackwalk / src / sw_pcontrol.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
32 #include "stackwalk/h/procstate.h"
33 #include "stackwalk/h/swk_errors.h"
34 #include "stackwalk/h/walker.h"
35 #include "stackwalk/h/steppergroup.h"
36
37 #include "proccontrol/h/Process.h"
38 #include "proccontrol/h/ProcessSet.h"
39 #include "proccontrol/h/PCErrors.h"
40
41 #include "dynutil/h/dyn_regs.h"
42 #include "dynutil/h/SymReader.h"
43
44 #include "stackwalk/src/libstate.h"
45 #include "stackwalk/src/sw.h"
46
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 public:
58    PCLibraryState(ProcessState *pd);
59    ~PCLibraryState();
60
61    bool checkLibraryContains(Address addr, Library::ptr lib);
62    virtual bool getLibraryAtAddr(Address addr, LibAddrPair &lib);
63    virtual bool getLibraries(std::vector<LibAddrPair> &libs);
64    virtual void notifyOfUpdate();
65    virtual Address getLibTrapAddress();
66    virtual bool getAOut(LibAddrPair &ao);
67
68    void checkForNewLib(Library::ptr lib);
69 };
70
71 ProcDebug::ProcDebug(Process::ptr p) :
72    ProcessState(p->getPid()),
73    proc(p)
74 {
75 }
76
77 ProcDebug *ProcDebug::newProcDebug(PID pid, std::string executable)
78 {
79    Process::ptr proc = Process::attachProcess(pid, executable);
80    if (!proc) {
81       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
82       sw_printf("[%s:%u] - ProcControl error creating process\n", __FILE__, __LINE__);
83       return NULL;
84    }
85    
86    return newProcDebug(proc);
87 }
88
89 ProcDebug *ProcDebug::newProcDebug(Dyninst::ProcControlAPI::Process::ptr proc)
90 {
91    ProcDebug *pd = new ProcDebug(proc);
92    pd->library_tracker = new PCLibraryState(pd);
93
94    return pd;
95 }
96
97 bool ProcDebug::newProcDebugSet(const std::vector<PID> &pids,
98                                 std::vector<ProcDebug *> & out_set)
99 {
100    for (vector<PID>::const_iterator i = pids.begin(); i != pids.end(); i++) {
101       ProcDebug *pd = ProcDebug::newProcDebug(*i);
102       if (!pd)
103          return false;
104       out_set.push_back(pd);
105    }
106    return true;
107 }
108
109 ProcDebug *ProcDebug::newProcDebug(std::string executable, 
110                                    const std::vector<std::string> &argv)
111 {
112    Process::ptr proc = Process::createProcess(executable, argv);
113    if (!proc) {
114       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
115       sw_printf("[%s:%u] - ProcControl error creating process\n", __FILE__, __LINE__);
116       return NULL;
117    }
118
119    ProcDebug *pd = new ProcDebug(proc);
120    pd->library_tracker = new PCLibraryState(pd);
121    
122    return pd;
123 }
124
125 ProcDebug::~ProcDebug()
126 {
127    if (library_tracker)
128       delete library_tracker;
129    library_tracker = NULL;
130 }
131
132 #define CHECK_PROC_LIVE \
133    do { \
134    if (!proc || proc->isTerminated()) { \
135      sw_printf("[%s:%u] - operation on exited process\n", __FILE__, __LINE__); \
136      Stackwalker::setLastError(err_procexit, "Process has exited or been detached"); \
137      return false; \
138    } \
139    } while (0)
140
141 bool ProcDebug::getRegValue(MachRegister reg, THR_ID thread, 
142                             MachRegisterVal &val)
143 {
144    CHECK_PROC_LIVE;
145    if (reg == FrameBase) {
146       reg = MachRegister::getFramePointer(getArchitecture());
147    }
148    else if (reg == ReturnAddr) {
149       reg = MachRegister::getPC(getArchitecture());
150    }
151    else if (reg == StackTop) {
152       reg = MachRegister::getStackPointer(getArchitecture());
153    }
154    ThreadPool::iterator thrd_i = proc->threads().find(thread);
155    if (thrd_i == proc->threads().end()) {
156       sw_printf("[%s:%u] - Invalid thread ID to getRegValue\n", __FILE__, __LINE__);
157       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
158       return false;
159    }
160    Thread::ptr thrd = *thrd_i;
161    bool result = thrd->getRegister(reg, val);
162    if (!result) {
163       sw_printf("[%s:%u] - ProcControlAPI error reading register\n", __FILE__, __LINE__);
164       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
165    }
166    return result;
167 }
168
169 bool ProcDebug::readMem(void *dest, Address source, size_t size)
170 {
171    CHECK_PROC_LIVE;
172    bool result = proc->readMemory(dest, source, size);
173    if (!result) {
174       sw_printf("[%s:%u] - ProcControlAPI error reading memory\n", __FILE__, __LINE__);
175       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
176    }
177    return result;
178 }
179
180 bool ProcDebug::getThreadIds(std::vector<THR_ID> &thrds)
181 {
182    CHECK_PROC_LIVE;
183    ThreadPool::iterator i = proc->threads().begin();
184    for (; i != proc->threads().end(); i++) {
185       thrds.push_back((*i)->getLWP());
186    }
187    return true;
188 }
189
190 bool ProcDebug::getDefaultThread(THR_ID &default_tid)
191 {
192    CHECK_PROC_LIVE;
193    default_tid = proc->threads().getInitialThread()->getLWP();
194    return true;
195 }
196
197 unsigned ProcDebug::getAddressWidth() 
198 {
199    CHECK_PROC_LIVE;
200    return getArchAddressWidth(proc->getArchitecture());
201 }
202
203 bool ProcDebug::preStackwalk(THR_ID tid)
204 {
205    CHECK_PROC_LIVE;
206    if (tid == NULL_THR_ID)
207       getDefaultThread(tid);
208    sw_printf("[%s:%u] - Calling preStackwalk for thread %d\n", __FILE__, __LINE__, tid);
209    
210    ThreadPool::iterator thread_iter = proc->threads().find(tid);
211    if (thread_iter == proc->threads().end()) {
212       sw_printf("[%s:%u] - Stackwalk on non-existant thread\n", __FILE__, __LINE__);
213       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
214       return false;     
215    }
216    Thread::ptr active_thread = *thread_iter;
217
218    if (active_thread->isRunning()) {
219       sw_printf("[%s:%u] - Stopping running thread %d\n", __FILE__, __LINE__, tid);
220       bool result = active_thread->stopThread();
221       if (!result) {
222          sw_printf("[%s:%u] - Error stopping thread\n", __FILE__, __LINE__);
223          Stackwalker::setLastError(err_proccontrol, "Could not stop thread for stackwalk\n");
224          return false;
225       }
226       needs_resume.insert(active_thread);
227    }
228    return true;
229 }   
230
231 bool ProcDebug::postStackwalk(THR_ID tid)
232 {
233    CHECK_PROC_LIVE;
234    if (tid == NULL_THR_ID)
235       getDefaultThread(tid);
236    sw_printf("[%s:%u] - Calling preStackwalk for thread %d\n", __FILE__, __LINE__, tid);
237    
238    ThreadPool::iterator thread_iter = proc->threads().find(tid);
239    if (thread_iter == proc->threads().end()) {
240       sw_printf("[%s:%u] - Stackwalk on non-existant thread\n", __FILE__, __LINE__);
241       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
242       return false;     
243    }
244    Thread::ptr active_thread = *thread_iter;
245    
246    set<Thread::ptr>::iterator i = needs_resume.find(active_thread);
247    if (i != needs_resume.end()) {
248       sw_printf("[%s:%u] - Resuming thread %d after stackwalk\n", __FILE__, __LINE__, tid);
249       bool result = active_thread->continueThread();
250       if (!result) {
251          sw_printf("[%s:%u] - Error resuming stopped thread %d\n", __FILE__, __LINE__, tid);
252          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
253          return false;
254       }
255       needs_resume.erase(i);
256    }
257    return true;
258 }
259   
260 bool ProcDebug::pause(THR_ID tid)
261 {
262    CHECK_PROC_LIVE;
263    if (tid == NULL_THR_ID) {
264       sw_printf("[%s:%u] - Stopping process %d\n", __FILE__, __LINE__, proc->getPid());
265
266       bool result = proc->stopProc();
267       if (!result) {
268          sw_printf("[%s:%u] - Error stopping process %d\n", 
269                    __FILE__, __LINE__, proc->getPid());
270          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
271          return false;
272       }
273       return true;
274    }
275
276    ThreadPool::iterator thread_iter = proc->threads().find(tid);
277    if (thread_iter == proc->threads().end()) {
278       sw_printf("[%s:%u] - stop on non-existant thread\n", __FILE__, __LINE__);
279       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
280       return false;     
281    }
282    Thread::ptr thread = *thread_iter;
283    sw_printf("[%s:%u] - Stopping thread %d\n", __FILE__, __LINE__, tid);
284
285    if (thread->isStopped()) {
286       sw_printf("[%s:%u] - Thread %d is already stopped\n", __FILE__, __LINE__, tid);
287       return true;
288    }
289
290    bool result = thread->stopThread();
291    if (!result) {
292       sw_printf("[%s:%u] - Error stopping thread %d\n", __FILE__, __LINE__, tid);
293       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
294       return false;
295    }
296    
297    return true;
298 }
299
300 bool ProcDebug::resume(THR_ID tid)
301 {
302    CHECK_PROC_LIVE;
303    if (tid == NULL_THR_ID) {
304       sw_printf("[%s:%u] - Running process %d\n", __FILE__, __LINE__, proc->getPid());
305
306       bool result = proc->continueProc();
307       if (!result) {
308          sw_printf("[%s:%u] - Error running process %d\n", 
309                    __FILE__, __LINE__, proc->getPid());
310          Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
311          return false;
312       }
313       return true;
314    }
315
316    ThreadPool::iterator thread_iter = proc->threads().find(tid);
317    if (thread_iter == proc->threads().end()) {
318       sw_printf("[%s:%u] - continue on non-existant thread\n", __FILE__, __LINE__);
319       Stackwalker::setLastError(err_badparam, "Invalid thread ID\n");
320       return false;     
321    }
322    Thread::ptr thread = *thread_iter;
323    sw_printf("[%s:%u] - Running thread %d\n", __FILE__, __LINE__, tid);
324
325    if (thread->isRunning()) {
326       sw_printf("[%s:%u] - Thread %d is already running\n", __FILE__, __LINE__, tid);
327       return true;
328    }
329
330    bool result = thread->continueThread();
331    if (!result) {
332       sw_printf("[%s:%u] - Error running thread %d\n", __FILE__, __LINE__, tid);
333       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
334       return false;
335    }
336    
337    return true;
338 }
339
340 bool ProcDebug::isTerminated()
341 {
342    return (!proc || proc->isTerminated());
343 }
344
345 bool ProcDebug::detach(bool)
346 {
347    CHECK_PROC_LIVE;   
348    bool result = proc->detach();
349    if (!result) {
350       sw_printf("[%s:%u] - Error detaching from process %d\n", __FILE__, __LINE__, 
351                 proc->getPid());
352       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
353       return false;
354    }
355    return true;
356 }
357
358 int ProcDebug::getNotificationFD()
359 {
360    return -1;
361 }
362
363 std::string ProcDebug::getExecutablePath()
364 {
365    CHECK_PROC_LIVE;
366    return proc->libraries().getExecutable()->getName();
367 }
368
369 bool ProcDebug::handleDebugEvent(bool block)
370 {
371    bool result = Process::handleEvents(block);
372    if (!result) {
373       sw_printf("[%s:%u] - Error handling debug events\n", __FILE__, __LINE__);
374       Stackwalker::setLastError(err_proccontrol, ProcControlAPI::getLastErrorMsg());
375       return false;
376    }
377    return true;
378 }
379
380 bool ProcDebug::isFirstParty()
381 {
382    return false;
383 }
384
385 Architecture ProcDebug::getArchitecture()
386 {
387    return proc->getArchitecture();
388 }
389
390 Process::ptr ProcDebug::getProc()
391 {
392    return proc;
393 }
394
395 PCLibraryState::PCLibraryState(ProcessState *pd) :
396    LibraryState(pd)
397 {
398    pdebug = static_cast<ProcDebug *>(pd);
399 }
400    
401 PCLibraryState::~PCLibraryState()
402 {
403 }
404  
405 bool PCLibraryState::checkLibraryContains(Address addr, Library::ptr lib)
406 {
407    std::string filename = lib->getName();
408    Address base = lib->getLoadAddress();
409
410    SymbolReaderFactory *fact = getDefaultSymbolReader();
411    SymReader *reader = fact->openSymbolReader(filename);
412    if (!reader) {
413       sw_printf("[%s:%u] - Error could not open expected file %s\n", 
414                 __FILE__, __LINE__, filename.c_str());
415       return false;
416    }
417
418    int num_regions = reader->numRegions();
419    for (int i=0; i<num_regions; i++) {
420       SymRegion region;
421       reader->getRegion(i, region);
422       Address region_start = region.mem_addr + base;
423       Address region_end = region_start + region.mem_size;
424       if (region_start <= addr && region_end > addr) 
425          return true;
426    }
427    return false;
428 }
429
430 void PCLibraryState::checkForNewLib(Library::ptr lib)
431 {
432    
433    if (lib->getData())
434       return;
435    sw_printf("[%s:%u] - Detected new library %s, notifying\n",
436              __FILE__, __LINE__, lib->getName().c_str());
437    
438    lib->setData((void *) 0x1);
439    StepperGroup *group = pdebug->getWalker()->getStepperGroup();
440    LibAddrPair la(lib->getName(), lib->getLoadAddress());
441    group->newLibraryNotification(&la, library_load);
442 }
443
444 bool PCLibraryState::getLibraryAtAddr(Address addr, LibAddrPair &lib)
445 {
446    Process::ptr proc = pdebug->getProc();
447    CHECK_PROC_LIVE;
448    
449    LibraryPool::iterator i;
450    Library::ptr nearest_predecessor = Library::ptr();
451    signed int pred_distance = 0;
452    Library::ptr nearest_successor = Library::ptr();
453    signed int succ_distance = 0;
454
455    vector<pair<LibAddrPair, unsigned int> > arch_libs;
456    updateLibsArch(arch_libs);
457    vector<pair<LibAddrPair, unsigned int> >::iterator j;
458    for (j = arch_libs.begin(); j != arch_libs.end(); j++) {
459       string name = (*j).first.first;
460       Address start = (*j).first.second;
461       Address size = (*j).second;
462       if (addr >= start && addr < start + size) {
463          lib.first = name;
464          lib.second = start;
465          return true;
466       }
467    }
468
469    std::vector<Library::ptr> zero_dynamic_libs;
470    for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
471    {
472       Library::ptr slib = *i;
473       checkForNewLib(slib);
474
475       Address dyn_addr = slib->getDynamicAddress();
476       if (!dyn_addr) {
477          zero_dynamic_libs.push_back(slib);
478          continue;
479       }
480
481       signed int distance = addr - dyn_addr;
482       if (distance == 0) {
483          lib.first = slib->getName();
484          lib.second = slib->getLoadAddress();
485          sw_printf("[%s:%u] - Found library %s contains address %lx\n",
486                    __FILE__, __LINE__, lib.first.c_str(), addr);
487          return true;
488       }
489       else if (distance < 0) {
490          if (!pred_distance || pred_distance < distance) {
491             nearest_predecessor = slib;
492             pred_distance = distance;
493          }
494       }
495       else if (distance > 0) {
496          if (!succ_distance || succ_distance > distance) {
497             nearest_successor = slib;
498             succ_distance = distance;
499          }
500       }
501    }
502
503    if (!nearest_predecessor && !nearest_successor) {
504       //Likely a static binary, set nearest_predecessor so that
505       // the following check will test it.
506       nearest_predecessor = proc->libraries().getExecutable();
507    }
508
509    if (nearest_predecessor && checkLibraryContains(addr, nearest_predecessor)) {
510       lib.first = nearest_predecessor->getName();
511       lib.second = nearest_predecessor->getLoadAddress();
512       sw_printf("[%s:%u] - Found library %s contains address %lx\n",
513                 __FILE__, __LINE__, lib.first.c_str(), addr);
514       return true;
515    }
516    if (nearest_successor && checkLibraryContains(addr, nearest_successor)) {
517       lib.first = nearest_successor->getName();
518       lib.second = nearest_successor->getLoadAddress();
519       sw_printf("[%s:%u] - Found library %s contains address %lx\n",
520                 __FILE__, __LINE__, lib.first.c_str(), addr);
521       return true;
522    }
523
524    std::vector<Library::ptr>::iterator k = zero_dynamic_libs.begin();
525    for (; k != zero_dynamic_libs.end(); k++) {
526       if (checkLibraryContains(addr, *k)) {
527          lib.first = (*k)->getName();
528          lib.second = (*k)->getLoadAddress();
529          return true;
530       }
531    }
532    sw_printf("[%s:%u] - Could not find library for addr %lx\n", 
533              __FILE__, __LINE__, addr);
534    return false;
535 }
536
537 bool PCLibraryState::getLibraries(std::vector<LibAddrPair> &libs)
538 {
539    Process::ptr proc = pdebug->getProc();
540    CHECK_PROC_LIVE;
541
542    LibraryPool::iterator i;   
543    for (i = proc->libraries().begin(); i != proc->libraries().end(); i++)
544    {
545       checkForNewLib(*i);
546       libs.push_back(LibAddrPair((*i)->getName(), (*i)->getLoadAddress()));
547    }
548
549    vector<pair<LibAddrPair, unsigned int> > arch_libs;
550    vector<pair<LibAddrPair, unsigned int> >::iterator j;
551    updateLibsArch(arch_libs);
552    for (j = arch_libs.begin(); j != arch_libs.end(); j++) {
553       libs.push_back(j->first);
554    }
555
556    return true;
557 }
558
559 void PCLibraryState::notifyOfUpdate()
560 {
561 }
562
563 Address PCLibraryState::getLibTrapAddress()
564 {
565    return 0;
566 }
567
568 bool PCLibraryState::getAOut(LibAddrPair &ao)
569 {
570    Process::ptr proc = pdebug->getProc();
571    CHECK_PROC_LIVE;
572
573    Library::ptr lib = proc->libraries().getExecutable();
574    if (!lib) {
575       sw_printf("[%s:%u] - Could not get executable\n", __FILE__, __LINE__);
576       return false;
577    }
578    ao = LibAddrPair(lib->getName(), lib->getLoadAddress());
579    return true;
580 }
581
582 void int_walkerSet::addToProcSet(ProcDebug *pd)
583 {
584    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
585    Process::ptr proc = pd->getProc();
586    pset->insert(proc);
587 }
588
589 void int_walkerSet::eraseFromProcSet(ProcDebug *pd)
590 {
591    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
592    Process::ptr proc = pd->getProc();
593
594    ProcessSet::iterator i = pset->find(proc);
595    assert(i != pset->end());
596    pset->erase(i);
597 }
598
599 void int_walkerSet::clearProcSet()
600 {
601    ProcessSet::ptr *pset = (ProcessSet::ptr *) procset;
602    (*pset)->clear();
603    delete pset;
604    procset = NULL;
605 }
606
607 void int_walkerSet::initProcSet()
608 {
609    ProcessSet::ptr *p = new ProcessSet::ptr();
610    *p = ProcessSet::newProcessSet();
611    procset = (void *) p;
612 }
613
614 bool int_walkerSet::walkStacksProcSet(CallTree &tree, bool &bad_plat)
615 {
616    ProcessSet::ptr &pset = *((ProcessSet::ptr *) procset);
617 }
618