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