Infrastructure for SW CallTrees and group operations
[dyninst.git] / stackwalk / src / sw_c.C
1 /*
2  * Copyright (c) 1996-2011 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 extern "C" {
33 #include "stackwalk/h/sw_c.h"
34 }
35
36 #include "stackwalk/h/walker.h"
37 #include "stackwalk/h/frame.h"
38
39 using namespace Dyninst;
40 using namespace Stackwalker;
41 using namespace std;
42
43 walker_t newWalkerLocal()
44 {
45    walker_t ret;
46    ret.walker = (void *) Walker::newWalker();
47    return ret;
48 }
49
50 walker_t newWalkerAttach(int pid)
51 {
52    walker_t ret;
53    ret.walker = (void *) Walker::newWalker(pid);
54    return ret;
55 }
56
57 walker_t newWalkerCreate(char *executable, char **args)
58 {
59    vector<string> cpp_args;
60    while (*args) {
61       cpp_args.push_back(*args);
62       args++;
63    }
64    string cpp_executable(executable);
65
66    walker_t ret;
67    ret.walker = (void *) Walker::newWalker(cpp_executable, cpp_args);
68    return ret;
69 }
70
71 int walkStack(walker_t walker, frame_t **out_frames, unsigned int *out_frames_size)
72 {
73    Walker *w = (Walker *) walker.walker;
74    
75    vector<Frame> frames;
76    bool result = w->walkStack(frames);
77    if (!frames.size())
78       return -1;
79    
80    *out_frames = (frame_t *) malloc(sizeof(frame_t) * frames.size());
81    if (!*out_frames)
82       return -1;
83    
84    unsigned j=0;
85    for (vector<Frame>::iterator i = frames.begin(); i != frames.end(); i++, j++) {
86       (*out_frames)[j].frame = (void *) new Frame(*i);
87    }
88    *out_frames_size = frames.size();
89
90    return result ? 0 : -1;
91 }
92
93 int walkStackFromFrame(walker_t walker, frame_t frame, frame_t **out_frames,
94                        unsigned int *out_frames_size)
95 {
96    Walker *w = (Walker *) walker.walker;
97    Frame *f = (Frame *) frame.frame;
98    
99    vector<Frame> frames;
100    bool result = w->walkStackFromFrame(frames, *f);
101    if (!frames.size())
102       return -1;
103    
104    *out_frames = (frame_t *) malloc(sizeof(frame_t) * frames.size());
105    if (!*out_frames)
106       return -1;
107    
108    unsigned j=0;
109    for (vector<Frame>::iterator i = frames.begin(); i != frames.end(); i++, j++) {
110       (*out_frames)[j].frame = (void *) new Frame(*i);
111    }
112    *out_frames_size = frames.size();
113
114    return result ? 0 : -1;
115 }
116
117
118 int walkSingleFrame(walker_t walker, frame_t frame, frame_t out_frame)
119 {
120    Walker *w = (Walker *) walker.walker;
121    Frame *f = (Frame *) frame.frame;
122
123    Frame oframe(w);
124    bool result = w->walkSingleFrame(*f, oframe);
125    if (!result) 
126       return -1;
127
128    out_frame.frame = (void *) new Frame(oframe);
129    return 0;
130 }
131
132 int getInitialFrame(walker_t walker, frame_t out_frame)
133 {   
134    Walker *w = (Walker *) walker.walker;
135
136    Frame oframe(w);
137    bool result = w->getInitialFrame(oframe);
138    if (!result) 
139       return -1;
140    
141    out_frame.frame = (void *) new Frame(oframe);
142    return 0;
143 }
144
145 unsigned long frameGetReturnAddress(frame_t frame)
146 {
147    Frame *f = (Frame *) frame.frame;
148    return f->getRA();
149 }
150
151 unsigned long frameGetFramePointer(frame_t frame)
152 {
153    Frame *f = (Frame *) frame.frame;
154    return f->getFP();
155 }
156
157 unsigned long frameGetStackPointer(frame_t frame)
158 {
159    Frame *f = (Frame *) frame.frame;
160    return f->getSP();
161 }
162
163 int frameGetName(frame_t frame, char **buffer)
164 {
165    Frame *f = (Frame *) frame.frame;
166    std::string name;
167    bool result = f->getName(name);
168    if (!result)
169       return -1;
170
171    unsigned int name_length = (unsigned int) name.length();
172    *buffer = (char *) malloc(name_length+1);
173    strncpy(*buffer, name.c_str(), name_length);
174    (*buffer)[name_length] = '\0';
175
176    return 0;
177 }
178
179 int frameGetLibOffset(frame_t frame, char **libname, unsigned long *offset)
180 {
181    Frame *f = (Frame *) frame.frame;
182
183    Dyninst::Offset dyn_offset;
184    std::string name;
185    void *extra_handle = NULL;
186    bool result = f->getLibOffset(name, dyn_offset, extra_handle);
187    if (!result)
188       return -1;
189
190    if (*libname) {
191       unsigned int name_length = (unsigned int) name.length();
192       *libname = (char *) malloc(name_length+1);
193       strncpy(*libname, name.c_str(), name_length);
194       (*libname)[name_length] = '\0';
195    }
196
197    if (*offset) {
198       *offset = (unsigned long) dyn_offset;
199    }
200
201    return 0;
202 }
203
204 int frameIsTopFrame(frame_t frame)
205 {
206    Frame *f = (Frame *) frame.frame;
207    return f->isTopFrame() ? 1 : 0;
208 }
209
210 int frameIsBottomFrame(frame_t frame)
211 {
212    Frame *f = (Frame *) frame.frame;
213    return f->isBottomFrame() ? 1 : 0;
214 }
215
216 int freeStackwalk(frame_t *frames, unsigned int frames_size)
217 {
218    for (unsigned i=0; i<frames_size; i++) {
219       freeFrame(frames+i);
220    }
221    free(frames);
222    return 0;
223 }
224
225 int freeFrame(frame_t *frame)
226 {
227    Frame *f = (Frame *) frame->frame;
228    if (!f)
229       return -1;
230    delete f;
231    frame->frame = NULL;
232    return 0;
233 }
234
235 int freeName(char *name)
236 {
237    free(name);
238    return 0;
239 }