Update copyright to LGPL on all files
[dyninst.git] / stackwalk / src / walker.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/walker.h"
33 #include "stackwalk/h/frame.h"
34 #include "stackwalk/h/swk_errors.h"
35 #include "stackwalk/h/procstate.h"
36 #include "stackwalk/h/symlookup.h"
37 #include "stackwalk/h/framestepper.h"
38 #include "stackwalk/h/steppergroup.h"
39 #include "stackwalk/src/sw.h"
40 #include <assert.h>
41
42 using namespace Dyninst;
43 using namespace Dyninst::Stackwalker;
44 using namespace std;
45
46 Walker::Walker(ProcessState *p, 
47                StepperGroup *grp,
48                SymbolLookup *sym, 
49                bool default_steppers,
50                const std::string &exec_name) :
51    proc(NULL), 
52    lookup(NULL),
53    creation_error(false),
54    call_count(0)
55 {
56    bool result;
57    //Always start with a process object
58    assert(p);
59    proc = p;
60    
61    sw_printf("[%s:%u] - Creating new Walker with proc=%p, sym=%p, step = %d\n",
62              __FILE__, __LINE__, proc, sym, (int) default_steppers);
63    group = grp ? grp : createDefaultStepperGroup();
64    if (default_steppers) {
65       result = createDefaultSteppers();
66       if (!result) {
67          sw_printf("[%s:%u] - Error creating default steppers\n",
68                    __FILE__, __LINE__);
69          creation_error = true;
70          return;
71       }
72    }
73
74    lookup = sym ? sym : createDefaultSymLookup(exec_name);
75    if (!lookup) {
76       sw_printf("[%s:%u] - WARNING, no symbol lookup available\n",
77                 __FILE__, __LINE__);
78    }
79 }
80
81 Walker* Walker::newWalker() 
82 {
83   sw_printf("[%s:%u] - Creating new stackwalker on current process\n",
84             __FILE__, __LINE__);
85    
86   ProcessState *newproc = createDefaultProcess();
87   if (!newproc) {
88     sw_printf("[%s:%u] - Error creating default process\n",
89               __FILE__, __LINE__);
90     return NULL;
91   }
92   
93   Walker *newwalker = new Walker(newproc, NULL, NULL, true, "");
94   if (!newwalker || newwalker->creation_error) {
95     sw_printf("[%s:%u] - Error creating new Walker object %p\n",
96               __FILE__, __LINE__, newwalker);
97     return NULL;
98   }
99   
100   sw_printf("[%s:%u] - Successfully created Walker %p\n", 
101             __FILE__, __LINE__, newwalker);
102   
103   return newwalker;
104 }
105
106 Walker *Walker::newWalker(Dyninst::PID pid,
107                           const std::string &executable)
108 {
109   sw_printf("[%s:%u] - Creating new stackwalker for process %d\n",
110             __FILE__, __LINE__, (int) pid);
111   
112   ProcessState *newproc = createDefaultProcess(pid, executable);
113   if (!newproc) {
114     sw_printf("[%s:%u] - Error creating default process\n",
115               __FILE__, __LINE__);
116     return NULL;
117   }
118
119   Walker *newwalker = new Walker(newproc, NULL, NULL, true, executable);
120   if (!newwalker || newwalker->creation_error) {
121     sw_printf("[%s:%u] - Error creating new Walker object %p\n",
122               __FILE__, __LINE__, newwalker);
123     return NULL;
124   }
125   
126   sw_printf("[%s:%u] - Successfully created Walker %p\n", 
127             __FILE__, __LINE__, newwalker);
128   
129   return newwalker;
130 }
131
132 Walker *Walker::newWalker(const std::string &exec_name, 
133                           const std::vector<std::string> &argv)
134 {
135    sw_printf("[%s:%u] - Creating new stackwalker with process %s\n",
136              __FILE__, __LINE__, exec_name.c_str());
137
138    ProcessState *newproc = createDefaultProcess(exec_name, argv);
139    if (!newproc) {
140       sw_printf("[%s:%u] - Error creating default process\n",
141                 __FILE__, __LINE__);
142       return NULL;
143    }
144
145    Walker *newwalker = new Walker(newproc, NULL, NULL, true, exec_name);
146    if (!newwalker || newwalker->creation_error) {
147       sw_printf("[%s:%u] - Error creating new Walker object %p\n",
148                 __FILE__, __LINE__, newwalker);
149       return NULL;
150    }
151
152    sw_printf("[%s:%u] - Successfully created Walker %p\n", 
153              __FILE__, __LINE__, newwalker);
154
155    return newwalker;
156 }
157
158 Walker *Walker::newWalker(ProcessState *proc, 
159                           StepperGroup *grp,
160                           SymbolLookup *lookup,
161                           bool default_steppers)
162 {
163    if (!proc) {
164       sw_printf("[%s:%u] - Error proc parameter to newWalker must not be NULL\n",
165                 __FILE__, __LINE__);
166       setLastError(err_badparam, "Tried to create a walker with a NULL " \
167                    "ProcessState param");
168       return NULL;
169    }
170    sw_printf("[%s:%u] - Creating custom Walker with proc = %p" \
171              "lookup = %p\n", __FILE__, __LINE__, proc, lookup);
172   
173    Walker *newwalker = new Walker(proc, grp, lookup, default_steppers, "");
174    if (!newwalker || newwalker->creation_error) {
175       sw_printf("[%s:%u] - Error creating new Walker object %p\n",
176                 __FILE__, __LINE__, newwalker);
177       return NULL;
178    }
179   
180    sw_printf("[%s:%u] - Successfully created Walker %p\n", 
181              __FILE__, __LINE__, newwalker);
182   
183    return newwalker;
184 }
185
186 Walker *Walker::newWalker(Dyninst::PID pid)
187 {
188    return newWalker(pid, "");
189 }
190
191 bool Walker::newWalker(const std::vector<Dyninst::PID> &pids,
192                        std::vector<Walker *> &walkers_out)
193 {
194    return newWalker(pids, walkers_out, "");
195 }
196
197 bool Walker::newWalker(const std::vector<Dyninst::PID> &pids,
198                        std::vector<Walker *> &walkers_out,
199                        const std::string &executable)
200 {
201   sw_printf("[%s:%u] - Creating multiple stackwalkers\n",
202             __FILE__, __LINE__);
203   unsigned num_errors = 0;
204   
205   vector<ProcDebug *> new_dbs;
206   bool pd_result = createDefaultProcess(pids, new_dbs);
207   if (!pd_result) {
208      sw_printf("[%s:%u] - Errors attaching to some processes\n",
209                __FILE__, __LINE__);
210   }
211
212   vector<ProcDebug *>::iterator i;
213   for (i = new_dbs.begin(); i != new_dbs.end(); i++) {
214      ProcDebug *pd = *i;
215      if (!pd) {
216         assert(!pd_result);
217         walkers_out.push_back(NULL);
218         num_errors++;
219         continue;
220      }
221
222      Walker *newwalker = new Walker((ProcessState *) pd, NULL, NULL, true, executable);
223      if (!newwalker || newwalker->creation_error) {
224         sw_printf("[%s:%u] - Error creating new Walker object %p\n",
225                   __FILE__, __LINE__, newwalker);
226         walkers_out.push_back(NULL);
227         num_errors++;
228         continue;
229      }
230
231      sw_printf("[%s:%u] - Successfully created walker for %d\n",
232                __FILE__, __LINE__, pd->getProcessId());
233      walkers_out.push_back(newwalker);
234   }
235
236   if (num_errors == pids.size())
237      return false;
238   return true;
239 }
240
241 Walker::~Walker() {
242    if (proc)
243       delete proc;
244    if (lookup)
245       delete lookup;
246    //TODO: Stepper cleanup
247 }
248
249
250 /**
251  * What is happening here, you may ask?  
252  *
253  * getInitialFrame returns the active frame on the stack.  However, 
254  * this is a problem if we want to do a first party stackwalk, because
255  * getInitialFrame will return a copy of its own frame and then deconstruct
256  * the frame, leaving us with an invalid stack frame.
257  *
258  * Instead we put the implementation of getInitialFrame into a macro, which
259  * means it's inlined into any function that uses it.  Thus, we can do a 
260  * first party stackwalk by embedding this into the walkStack call, which will
261  * get its own frame, then generate a stack frame without destroying the 
262  * initial frame.
263  *
264  * This is used in two places, so I figure it's better to use a 
265  * #define rather than make two copies of this code.  Also, this is only
266  * legal to call from a Walker object.
267  **/
268 #define getInitialFrameImpl(frame, thread) \
269 { \
270   result = true; \
271   if (thread == NULL_THR_ID) { \
272     result = proc->getDefaultThread(thread); \
273     if (!result) { \
274       sw_printf("getDefaultThread returned an error\n"); \
275       result = false; \
276       goto done_gifi; \
277     } \
278   } \
279   Dyninst::MachRegisterVal pc, sp, fp; \
280   result = proc->getRegValue(Dyninst::MachRegPC, thread, pc); \
281   result = !result || proc->getRegValue(Dyninst::MachRegStackBase, thread, sp); \
282   result = !result || proc->getRegValue(Dyninst::MachRegFrameBase, thread, fp); \
283   if (!result) { \
284     sw_printf("Failed to get registers from process\n"); \
285     result = false; \
286     goto done_gifi; \
287   } \
288   frame.setRA(pc); \
289   frame.setFP(fp); \
290   frame.setSP(sp); \
291   frame.setThread(thread); \
292   done_gifi: ; \
293 }
294
295 bool Walker::walkStack(std::vector<Frame> &stackwalk, THR_ID thread)
296 {
297    bool result;
298    Frame initialFrame(this);
299
300    if (thread == NULL_THR_ID) {
301       result = proc->getDefaultThread(thread);
302       if (!result) {
303          sw_printf("[%s:%u] - Couldn't get initial thread on %d\n",
304                    __FILE__, __LINE__, proc->getProcessId());
305          return false;
306       }
307    }
308
309    callPreStackwalk(thread);
310
311    sw_printf("[%s:%u] - Starting stackwalk on thread %d\n",
312              __FILE__, __LINE__, (int) thread);
313
314    getInitialFrameImpl(initialFrame, thread);
315    if (!result) {
316       sw_printf("[%s:%u] - Failed to get registers from process\n",
317                 __FILE__, __LINE__, (int) thread);
318       goto done;
319    }                       
320
321    result = walkStackFromFrame(stackwalk, initialFrame);
322    if (!result) {
323       sw_printf("[%s:%u] - walkStackFromFrame failed\n",
324                 __FILE__, __LINE__, (int) thread);
325       goto done;
326    }
327
328  done:
329    callPostStackwalk(thread);
330    return result;
331 }
332
333 bool Walker::walkStackFromFrame(std::vector<Frame> &stackwalk, 
334                                 const Frame &frame)
335 {
336    bool result;
337
338    stackwalk.clear();
339    stackwalk.push_back(frame);
340
341    sw_printf("[%s:%u] - walkStackFromFrame called with frame at %lx\n",
342              __FILE__, __LINE__, stackwalk.back().getRA());
343
344    callPreStackwalk();
345
346    for (;;) {
347      Frame cur_frame(this);
348      sw_printf("[%s:%u] - Walking single frame from %lx\n", __FILE__, __LINE__, 
349                stackwalk.back().getRA());
350
351      result = walkSingleFrame(stackwalk.back(), cur_frame);
352      if (!result) {
353         if (getLastError() == err_stackbottom) {
354            sw_printf("[%s:%u] - Reached bottom of stack\n", __FILE__, __LINE__);
355            clearLastError();
356            result = true;
357            goto done;
358         }
359         sw_printf("[%s:%u] - Error walking through stack frame %s\n", 
360                   __FILE__, __LINE__, getLastErrorMsg());
361         result = false;
362         goto done;
363      }
364      stackwalk.push_back(cur_frame);
365    }       
366
367  done:
368    callPostStackwalk();
369    return result;
370 }
371
372 bool Walker::walkSingleFrame(const Frame &in, Frame &out)
373 {
374    gcframe_ret_t gcf_result;
375    bool result;
376    Frame last_frame = in;
377
378    sw_printf("[%s:%u] - Attempting to walk through frame with RA 0x%lx\n",
379              __FILE__, __LINE__, last_frame.getRA());
380
381    callPreStackwalk();
382    
383    if (!group) {
384       setLastError(err_nogroup, "Attempt to walk a stack without a StepperGroup");
385       return false;
386    }
387
388    FrameStepper *last_stepper = NULL;
389    for (;;)
390    {
391      FrameStepper *cur_stepper = NULL;
392      bool res = group->findStepperForAddr(last_frame.getRA(), cur_stepper,
393                                           last_stepper);
394      if (!res) {
395         sw_printf("[%s:%u] - Unable to find a framestepper for %lx\n",
396                   __FILE__, __LINE__, last_frame.getRA());
397         result = false;
398         goto done;
399      }
400      sw_printf("[%s:%u] - Attempting to use stepper %p\n", 
401                __FILE__, __LINE__, cur_stepper);
402      gcf_result = cur_stepper->getCallerFrame(in, out);
403      if (gcf_result == gcf_success) {
404        sw_printf("[%s:%u] - Success using stepper %p on 0x%lx\n", 
405                  __FILE__, __LINE__, cur_stepper, in.getRA());
406        sw_printf("[%s:%u] - Returning frame with RA %lx, SP %lx, FP %lx\n",
407                  __FILE__, __LINE__, out.getRA(), out.getSP(), out.getFP());
408        result = true;
409        goto done;
410      }
411      else if (gcf_result == gcf_not_me) {
412        last_stepper = cur_stepper;
413        sw_printf("[%s:%u] - Stepper %p declined address 0x%lx\n", 
414                  __FILE__, __LINE__, cur_stepper, in.getRA());
415        continue; 
416      }
417      else if (gcf_result == gcf_stackbottom) {
418         sw_printf("[%s:%u] - Stepper %p bottomed out on 0x%lx\n", 
419                   __FILE__, __LINE__, cur_stepper, in.getRA());
420        setLastError(err_stackbottom, "walkSingleFrame reached bottom of stack");
421        result = false;
422        goto done;
423      }
424      else if (gcf_result == gcf_error) {
425         sw_printf("[%s:%u] - A stepper reported error %d on frame at %lx\n", 
426                   __FILE__, __LINE__, cur_stepper, in.getRA());
427        result = false;
428        goto done;
429      }
430    }
431
432  done:
433    out.setThread(in.getThread());
434    callPostStackwalk();
435    return result;
436 }
437
438 bool Walker::getInitialFrame(Frame &frame, THR_ID thread) {
439    bool result;
440    callPreStackwalk(thread);
441    getInitialFrameImpl(frame, thread);
442    if (!result) {
443       sw_printf("[%s:%u] - getInitialFrameImpl failed\n",
444                 __FILE__, __LINE__, (int) thread);
445    }
446    callPostStackwalk(thread);
447    return result;
448 }
449
450
451 bool Walker::getAvailableThreads(std::vector<THR_ID> &threads) const {
452    threads.clear();
453    bool result = proc->getThreadIds(threads);
454    if (dyn_debug_stackwalk) {
455       if (!result) {
456          sw_printf("[%s:%u] - getThreadIds error\n", __FILE__, __LINE__);
457       }
458       else {
459          sw_printf("[%s:%u] - getThreadIds returning %d values:\t\n", 
460                    __FILE__, __LINE__, threads.size());
461          for (unsigned i=0; i<threads.size(); i++) {
462             sw_printf("%d ", (int) threads[i]);
463          }
464          sw_printf("\n ");
465       }
466    }
467    return result;
468 }
469
470 ProcessState *Walker::getProcessState() const {
471    return proc;
472 }
473
474 SymbolLookup *Walker::getSymbolLookup() const {
475    return lookup;
476 }
477
478 ProcessState *Walker::createDefaultProcess()
479 {
480    ProcSelf *pself = new ProcSelf();
481    pself->initialize();
482    return pself;
483 }
484
485 ProcessState *Walker::createDefaultProcess(PID pid, const std::string& executable)
486 {
487    ProcDebug *pdebug = ProcDebug::newProcDebug(pid, executable);
488    return pdebug;
489 }
490
491 bool Walker::createDefaultProcess(const vector<Dyninst::PID> &pids,
492                                   vector<ProcDebug *> &pds)
493 {
494    return ProcDebug::newProcDebugSet(pids, pds);
495 }
496
497 ProcessState *Walker::createDefaultProcess(const std::string &exec_name, 
498                                            const std::vector<std::string> &argv)
499 {
500    ProcDebug *pdebug = ProcDebug::newProcDebug(exec_name, argv);
501    return pdebug;
502 }
503
504 bool Walker::addStepper(FrameStepper *s)
505 {
506    assert(group);
507    sw_printf("[%s:%u] - Registering stepper %p with group %p\n",
508              __FILE__, __LINE__, s, group);
509    group->registerStepper(s);
510    return true;
511 }
512
513 void Walker::callPreStackwalk(Dyninst::THR_ID tid)
514 {
515    call_count++;
516    if (call_count != 1)
517       return;
518    
519    getProcessState()->preStackwalk(tid);
520 }
521
522 void Walker::callPostStackwalk(Dyninst::THR_ID tid)
523 {
524    call_count--;
525
526    if (call_count != 0)
527       return;
528
529    getProcessState()->postStackwalk(tid);
530 }
531
532 StepperGroup *Walker::createDefaultStepperGroup()
533 {
534    return new AddrRangeGroup(this);
535 }
536
537 StepperGroup *Walker::getStepperGroup() const
538 {
539    return group;
540 }