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