* target.h (struct section_table): Rename to ...
[deliverable/binutils-gdb.git] / gdb / python / python-frame.c
CommitLineData
f8f6f20b
TJB
1/* Python interface to stack frames
2
3 Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "charset.h"
22#include "block.h"
23#include "frame.h"
24#include "exceptions.h"
25#include "symtab.h"
26#include "stack.h"
27#include "value.h"
28#include "python-internal.h"
29
30typedef struct {
31 PyObject_HEAD
32 struct frame_id frame_id;
33 struct gdbarch *gdbarch;
34
35 /* Marks that the FRAME_ID member actually holds the ID of the frame next
36 to this, and not this frames' ID itself. This is a hack to permit Python
37 frame objects which represent invalid frames (i.e., the last frame_info
38 in a corrupt stack). The problem arises from the fact that this code
39 relies on FRAME_ID to uniquely identify a frame, which is not always true
40 for the last "frame" in a corrupt stack (it can have a null ID, or the same
41 ID as the previous frame). Whenever get_prev_frame returns NULL, we
42 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
43 int frame_id_is_next;
44} frame_object;
45
46/* Require a valid frame. This must be called inside a TRY_CATCH, or
47 another context in which a gdb exception is allowed. */
48#define FRAPY_REQUIRE_VALID(frame_obj, frame) \
49 do { \
50 frame = frame_object_to_frame_info (frame_obj); \
51 if (frame == NULL) \
52 error ("Frame is invalid."); \
53 } while (0)
54
55static PyTypeObject frame_object_type;
56
57/* Returns the frame_info object corresponding to the given Python Frame
58 object. If the frame doesn't exist anymore (the frame id doesn't
59 correspond to any frame in the inferior), returns NULL. */
60
61static struct frame_info *
62frame_object_to_frame_info (frame_object *frame_obj)
63{
64 struct frame_info *frame;
65
66 frame = frame_find_by_id (frame_obj->frame_id);
67 if (frame == NULL)
68 return NULL;
69
70 if (frame_obj->frame_id_is_next)
71 frame = get_prev_frame (frame);
72
73 return frame;
74}
75
76/* Called by the Python interpreter to obtain string representation
77 of the object. */
78
79static PyObject *
80frapy_str (PyObject *self)
81{
82 char *s;
83 long len;
84 PyObject *result;
85 struct ui_file *strfile;
86
87 strfile = mem_fileopen ();
88 fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
89 s = ui_file_xstrdup (strfile, &len);
90 result = PyString_FromString (s);
91 xfree (s);
92
93 return result;
94}
95
96/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
97 Returns True if the frame corresponding to the frame_id of this
98 object still exists in the inferior. */
99
100static PyObject *
101frapy_is_valid (PyObject *self, PyObject *args)
102{
103 struct frame_info *frame;
104
105 frame = frame_object_to_frame_info ((frame_object *) self);
106 if (frame == NULL)
107 Py_RETURN_FALSE;
108
109 Py_RETURN_TRUE;
110}
111
112/* Implementation of gdb.Frame.name (self) -> String.
113 Returns the name of the function corresponding to this frame. */
114
115static PyObject *
116frapy_name (PyObject *self, PyObject *args)
117{
118 struct frame_info *frame;
119 char *name;
120 enum language lang;
121 PyObject *result;
122 volatile struct gdb_exception except;
123
124 TRY_CATCH (except, RETURN_MASK_ALL)
125 {
126 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
127
128 find_frame_funname (frame, &name, &lang);
129 }
130 GDB_PY_HANDLE_EXCEPTION (except);
131
132 if (name)
133 result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
134 else
135 {
136 result = Py_None;
137 Py_INCREF (Py_None);
138 }
139
140 return result;
141}
142
143/* Implementation of gdb.Frame.type (self) -> Integer.
144 Returns the frame type, namely one of the gdb.*_FRAME constants. */
145
146static PyObject *
147frapy_type (PyObject *self, PyObject *args)
148{
149 struct frame_info *frame;
150 enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */
151 volatile struct gdb_exception except;
152
153 TRY_CATCH (except, RETURN_MASK_ALL)
154 {
155 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
156
157 type = get_frame_type (frame);
158 }
159 GDB_PY_HANDLE_EXCEPTION (except);
160
161 return PyInt_FromLong (type);
162}
163
164/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
165 Returns one of the gdb.FRAME_UNWIND_* constants. */
166
167static PyObject *
168frapy_unwind_stop_reason (PyObject *self, PyObject *args)
169{
170 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
171 volatile struct gdb_exception except;
172 enum unwind_stop_reason stop_reason;
173
174 TRY_CATCH (except, RETURN_MASK_ALL)
175 {
176 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
177 }
178 GDB_PY_HANDLE_EXCEPTION (except);
179
180 stop_reason = get_frame_unwind_stop_reason (frame);
181
182 return PyInt_FromLong (stop_reason);
183}
184
185/* Implementation of gdb.Frame.pc (self) -> Long.
186 Returns the frame's resume address. */
187
188static PyObject *
189frapy_pc (PyObject *self, PyObject *args)
190{
191 CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
192 struct frame_info *frame;
193 volatile struct gdb_exception except;
194
195 TRY_CATCH (except, RETURN_MASK_ALL)
196 {
197 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
198
199 pc = get_frame_pc (frame);
200 }
201 GDB_PY_HANDLE_EXCEPTION (except);
202
203 return PyLong_FromUnsignedLongLong (pc);
204}
205
206/* Convert a frame_info struct to a Python Frame object.
207 Sets a Python exception and returns NULL on error. */
208
209static frame_object *
210frame_info_to_frame_object (struct frame_info *frame)
211{
212 frame_object *frame_obj;
213
214 frame_obj = PyObject_New (frame_object, &frame_object_type);
215 if (frame_obj == NULL)
216 {
217 PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object.");
218 return NULL;
219 }
220
221 /* Try to get the previous frame, to determine if this is the last frame
222 in a corrupt stack. If so, we need to store the frame_id of the next
223 frame and not of this one (which is possibly invalid). */
224 if (get_prev_frame (frame) == NULL
225 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
226 && get_next_frame (frame) != NULL)
227 {
228 frame_obj->frame_id = get_frame_id (get_next_frame (frame));
229 frame_obj->frame_id_is_next = 1;
230 }
231 else
232 {
233 frame_obj->frame_id = get_frame_id (frame);
234 frame_obj->frame_id_is_next = 0;
235 }
236
237 frame_obj->gdbarch = get_frame_arch (frame);
238
239 return frame_obj;
240}
241
242/* Implementation of gdb.Frame.older (self) -> gdb.Frame.
243 Returns the frame immediately older (outer) to this frame, or None if
244 there isn't one. */
245
246static PyObject *
247frapy_older (PyObject *self, PyObject *args)
248{
249 struct frame_info *frame, *prev;
250 volatile struct gdb_exception except;
251 PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
252
253 TRY_CATCH (except, RETURN_MASK_ALL)
254 {
255 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
256
257 prev = get_prev_frame (frame);
258 if (prev)
259 prev_obj = (PyObject *) frame_info_to_frame_object (prev);
260 else
261 {
262 Py_INCREF (Py_None);
263 prev_obj = Py_None;
264 }
265 }
266 GDB_PY_HANDLE_EXCEPTION (except);
267
268 return prev_obj;
269}
270
271/* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
272 Returns the frame immediately newer (inner) to this frame, or None if
273 there isn't one. */
274
275static PyObject *
276frapy_newer (PyObject *self, PyObject *args)
277{
278 struct frame_info *frame, *next;
279 volatile struct gdb_exception except;
280 PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
281
282 TRY_CATCH (except, RETURN_MASK_ALL)
283 {
284 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
285
286 next = get_next_frame (frame);
287 if (next)
288 next_obj = (PyObject *) frame_info_to_frame_object (next);
289 else
290 {
291 Py_INCREF (Py_None);
292 next_obj = Py_None;
293 }
294 }
295 GDB_PY_HANDLE_EXCEPTION (except);
296
297 return next_obj;
298}
299
300/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
301 Returns the value of the given variable in this frame. The argument must be
302 a string. Returns None if GDB can't find the specified variable. */
303
304static PyObject *
305frapy_read_var (PyObject *self, PyObject *args)
306{
307 struct frame_info *frame;
308 PyObject *sym_obj;
309 struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
310 struct value *val = NULL;
311 volatile struct gdb_exception except;
312
313 if (!PyArg_ParseTuple (args, "O", &sym_obj))
314 return NULL;
315
316 if (gdbpy_is_string (sym_obj))
317 {
318 char *var_name;
319 struct block *block = NULL;
320 struct cleanup *cleanup;
321 volatile struct gdb_exception except;
322
323 var_name = python_string_to_target_string (sym_obj);
324 if (!var_name)
325 return NULL;
326 cleanup = make_cleanup (xfree, var_name);
327
328 TRY_CATCH (except, RETURN_MASK_ALL)
329 {
330 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
331
332 block = block_for_pc (get_frame_address_in_block (frame));
333 var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
334 }
335 GDB_PY_HANDLE_EXCEPTION (except);
336
337 if (!var)
338 {
339 PyErr_Format (PyExc_ValueError,
340 _("variable '%s' not found"), var_name);
341 do_cleanups (cleanup);
342
343 return NULL;
344 }
345
346 do_cleanups (cleanup);
347 }
348 else
349 {
350 PyErr_SetString (PyExc_TypeError,
351 _("argument must be a symbol or string"));
352 return NULL;
353 }
354
355 TRY_CATCH (except, RETURN_MASK_ALL)
356 {
357 FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
358
359 val = read_var_value (var, frame);
360 }
361 GDB_PY_HANDLE_EXCEPTION (except);
362
363 if (val)
364 return value_to_value_object (val);
365
366 Py_RETURN_NONE;
367}
368
369/* Implementation of gdb.selected_frame () -> gdb.Frame.
370 Returns the selected frame object. */
371
372PyObject *
373gdbpy_selected_frame (PyObject *self, PyObject *args)
374{
375 struct frame_info *frame;
376 frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */
377 volatile struct gdb_exception except;
378
379 TRY_CATCH (except, RETURN_MASK_ALL)
380 {
381 frame = get_selected_frame ("No frame is currently selected.");
382 frame_obj = frame_info_to_frame_object (frame);
383 }
384 GDB_PY_HANDLE_EXCEPTION (except);
385
386 return (PyObject *) frame_obj;
387}
388
389/* Implementation of gdb.stop_reason_string (Integer) -> String.
390 Return a string explaining the unwind stop reason. */
391
392PyObject *
393gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
394{
395 int reason;
396 const char *str;
397
398 if (!PyArg_ParseTuple (args, "i", &reason))
399 return NULL;
400
401 if (reason < 0 || reason > UNWIND_NO_SAVED_PC)
402 {
403 PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason.");
404 return NULL;
405 }
406
407 str = frame_stop_reason_string (reason);
408 return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
409}
410
411/* Implements the equality comparison for Frame objects.
412 All other comparison operators will throw a TypeError Python exception,
413 as they aren't valid for frames. */
414
415static PyObject *
416frapy_richcompare (PyObject *self, PyObject *other, int op)
417{
18e8c3bc
TT
418 int result;
419
420 if (!PyObject_TypeCheck (other, &frame_object_type)
421 || (op != Py_EQ && op != Py_NE))
f8f6f20b 422 {
18e8c3bc
TT
423 Py_INCREF (Py_NotImplemented);
424 return Py_NotImplemented;
f8f6f20b
TJB
425 }
426
427 if (frame_id_eq (((frame_object *) self)->frame_id,
428 ((frame_object *) other)->frame_id))
18e8c3bc
TT
429 result = Py_EQ;
430 else
431 result = Py_NE;
f8f6f20b 432
18e8c3bc
TT
433 if (op == result)
434 Py_RETURN_TRUE;
f8f6f20b
TJB
435 Py_RETURN_FALSE;
436}
437
438/* Sets up the Frame API in the gdb module. */
439
440void
441gdbpy_initialize_frames (void)
442{
443 if (PyType_Ready (&frame_object_type) < 0)
444 return;
445
446 /* Note: These would probably be best exposed as class attributes of Frame,
447 but I don't know how to do it except by messing with the type's dictionary.
448 That seems too messy. */
449 PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME);
450 PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME);
451 PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
452 PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
453 PyModule_AddIntConstant (gdb_module,
454 "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON);
455 PyModule_AddIntConstant (gdb_module,
456 "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID);
457 PyModule_AddIntConstant (gdb_module,
458 "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR);
459 PyModule_AddIntConstant (gdb_module,
460 "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID);
461 PyModule_AddIntConstant (gdb_module,
462 "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID);
463 PyModule_AddIntConstant (gdb_module,
464 "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC);
465
466 Py_INCREF (&frame_object_type);
467 PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
468}
469
470\f
471
472static PyMethodDef frame_object_methods[] = {
473 { "is_valid", frapy_is_valid, METH_NOARGS,
474 "is_valid () -> Boolean.\n\
475Return true if this frame is valid, false if not." },
476 { "name", frapy_name, METH_NOARGS,
477 "name () -> String.\n\
478Return the function name of the frame, or None if it can't be determined." },
479 { "type", frapy_type, METH_NOARGS,
480 "type () -> Integer.\n\
481Return the type of the frame." },
482 { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
483 "unwind_stop_reason () -> Integer.\n\
484Return the reason why it's not possible to find frames older than this." },
485 { "pc", frapy_pc, METH_NOARGS,
486 "pc () -> Long.\n\
487Return the frame's resume address." },
488 { "older", frapy_older, METH_NOARGS,
489 "older () -> gdb.Frame.\n\
490Return the frame that called this frame." },
491 { "newer", frapy_newer, METH_NOARGS,
492 "newer () -> gdb.Frame.\n\
493Return the frame called by this frame." },
494 { "read_var", frapy_read_var, METH_VARARGS,
495 "read_var (variable) -> gdb.Value.\n\
496Return the value of the variable in this frame." },
497 {NULL} /* Sentinel */
498};
499
500static PyTypeObject frame_object_type = {
501 PyObject_HEAD_INIT (NULL)
502 0, /* ob_size */
503 "gdb.Frame", /* tp_name */
504 sizeof (frame_object), /* tp_basicsize */
505 0, /* tp_itemsize */
506 0, /* tp_dealloc */
507 0, /* tp_print */
508 0, /* tp_getattr */
509 0, /* tp_setattr */
510 0, /* tp_compare */
511 0, /* tp_repr */
512 0, /* tp_as_number */
513 0, /* tp_as_sequence */
514 0, /* tp_as_mapping */
515 0, /* tp_hash */
516 0, /* tp_call */
517 frapy_str, /* tp_str */
518 0, /* tp_getattro */
519 0, /* tp_setattro */
520 0, /* tp_as_buffer */
521 Py_TPFLAGS_DEFAULT, /* tp_flags */
522 "GDB frame object", /* tp_doc */
523 0, /* tp_traverse */
524 0, /* tp_clear */
525 frapy_richcompare, /* tp_richcompare */
526 0, /* tp_weaklistoffset */
527 0, /* tp_iter */
528 0, /* tp_iternext */
529 frame_object_methods, /* tp_methods */
530 0, /* tp_members */
531 0, /* tp_getset */
532 0, /* tp_base */
533 0, /* tp_dict */
534 0, /* tp_descr_get */
535 0, /* tp_descr_set */
536 0, /* tp_dictoffset */
537 0, /* tp_init */
538 0, /* tp_alloc */
539 PyType_GenericNew /* tp_new */
540};
This page took 0.082827 seconds and 4 git commands to generate.