1 /* Python interface to stack frames
3 Copyright (C) 2008, 2009 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
24 #include "exceptions.h"
28 #include "python-internal.h"
32 struct frame_id frame_id
;
33 struct gdbarch
*gdbarch
;
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. */
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) \
50 frame = frame_object_to_frame_info (frame_obj); \
52 error ("Frame is invalid."); \
55 static PyTypeObject frame_object_type
;
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. */
61 static struct frame_info
*
62 frame_object_to_frame_info (frame_object
*frame_obj
)
64 struct frame_info
*frame
;
66 frame
= frame_find_by_id (frame_obj
->frame_id
);
70 if (frame_obj
->frame_id_is_next
)
71 frame
= get_prev_frame (frame
);
76 /* Called by the Python interpreter to obtain string representation
80 frapy_str (PyObject
*self
)
84 struct ui_file
*strfile
;
86 strfile
= mem_fileopen ();
87 fprint_frame_id (strfile
, ((frame_object
*) self
)->frame_id
);
88 s
= ui_file_xstrdup (strfile
, NULL
);
89 result
= PyString_FromString (s
);
95 /* Implementation of gdb.Frame.is_valid (self) -> Boolean.
96 Returns True if the frame corresponding to the frame_id of this
97 object still exists in the inferior. */
100 frapy_is_valid (PyObject
*self
, PyObject
*args
)
102 struct frame_info
*frame
;
104 frame
= frame_object_to_frame_info ((frame_object
*) self
);
111 /* Implementation of gdb.Frame.name (self) -> String.
112 Returns the name of the function corresponding to this frame. */
115 frapy_name (PyObject
*self
, PyObject
*args
)
117 struct frame_info
*frame
;
121 volatile struct gdb_exception except
;
123 TRY_CATCH (except
, RETURN_MASK_ALL
)
125 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
127 find_frame_funname (frame
, &name
, &lang
);
129 GDB_PY_HANDLE_EXCEPTION (except
);
132 result
= PyUnicode_Decode (name
, strlen (name
), host_charset (), NULL
);
142 /* Implementation of gdb.Frame.type (self) -> Integer.
143 Returns the frame type, namely one of the gdb.*_FRAME constants. */
146 frapy_type (PyObject
*self
, PyObject
*args
)
148 struct frame_info
*frame
;
149 enum frame_type type
= NORMAL_FRAME
;/* Initialize to appease gcc warning. */
150 volatile struct gdb_exception except
;
152 TRY_CATCH (except
, RETURN_MASK_ALL
)
154 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
156 type
= get_frame_type (frame
);
158 GDB_PY_HANDLE_EXCEPTION (except
);
160 return PyInt_FromLong (type
);
163 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
164 Returns one of the gdb.FRAME_UNWIND_* constants. */
167 frapy_unwind_stop_reason (PyObject
*self
, PyObject
*args
)
169 struct frame_info
*frame
= NULL
; /* Initialize to appease gcc warning. */
170 volatile struct gdb_exception except
;
171 enum unwind_stop_reason stop_reason
;
173 TRY_CATCH (except
, RETURN_MASK_ALL
)
175 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
177 GDB_PY_HANDLE_EXCEPTION (except
);
179 stop_reason
= get_frame_unwind_stop_reason (frame
);
181 return PyInt_FromLong (stop_reason
);
184 /* Implementation of gdb.Frame.pc (self) -> Long.
185 Returns the frame's resume address. */
188 frapy_pc (PyObject
*self
, PyObject
*args
)
190 CORE_ADDR pc
= 0; /* Initialize to appease gcc warning. */
191 struct frame_info
*frame
;
192 volatile struct gdb_exception except
;
194 TRY_CATCH (except
, RETURN_MASK_ALL
)
196 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
198 pc
= get_frame_pc (frame
);
200 GDB_PY_HANDLE_EXCEPTION (except
);
202 return PyLong_FromUnsignedLongLong (pc
);
205 /* Convert a frame_info struct to a Python Frame object.
206 Sets a Python exception and returns NULL on error. */
208 static frame_object
*
209 frame_info_to_frame_object (struct frame_info
*frame
)
211 frame_object
*frame_obj
;
213 frame_obj
= PyObject_New (frame_object
, &frame_object_type
);
214 if (frame_obj
== NULL
)
216 PyErr_SetString (PyExc_MemoryError
, "Could not allocate frame object.");
220 /* Try to get the previous frame, to determine if this is the last frame
221 in a corrupt stack. If so, we need to store the frame_id of the next
222 frame and not of this one (which is possibly invalid). */
223 if (get_prev_frame (frame
) == NULL
224 && get_frame_unwind_stop_reason (frame
) != UNWIND_NO_REASON
225 && get_next_frame (frame
) != NULL
)
227 frame_obj
->frame_id
= get_frame_id (get_next_frame (frame
));
228 frame_obj
->frame_id_is_next
= 1;
232 frame_obj
->frame_id
= get_frame_id (frame
);
233 frame_obj
->frame_id_is_next
= 0;
236 frame_obj
->gdbarch
= get_frame_arch (frame
);
241 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
242 Returns the frame immediately older (outer) to this frame, or None if
246 frapy_older (PyObject
*self
, PyObject
*args
)
248 struct frame_info
*frame
, *prev
;
249 volatile struct gdb_exception except
;
250 PyObject
*prev_obj
= NULL
; /* Initialize to appease gcc warning. */
252 TRY_CATCH (except
, RETURN_MASK_ALL
)
254 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
256 prev
= get_prev_frame (frame
);
258 prev_obj
= (PyObject
*) frame_info_to_frame_object (prev
);
265 GDB_PY_HANDLE_EXCEPTION (except
);
270 /* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
271 Returns the frame immediately newer (inner) to this frame, or None if
275 frapy_newer (PyObject
*self
, PyObject
*args
)
277 struct frame_info
*frame
, *next
;
278 volatile struct gdb_exception except
;
279 PyObject
*next_obj
= NULL
; /* Initialize to appease gcc warning. */
281 TRY_CATCH (except
, RETURN_MASK_ALL
)
283 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
285 next
= get_next_frame (frame
);
287 next_obj
= (PyObject
*) frame_info_to_frame_object (next
);
294 GDB_PY_HANDLE_EXCEPTION (except
);
299 /* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
300 Returns the value of the given variable in this frame. The argument must be
301 a string. Returns None if GDB can't find the specified variable. */
304 frapy_read_var (PyObject
*self
, PyObject
*args
)
306 struct frame_info
*frame
;
308 struct symbol
*var
= NULL
; /* gcc-4.3.2 false warning. */
309 struct value
*val
= NULL
;
310 volatile struct gdb_exception except
;
312 if (!PyArg_ParseTuple (args
, "O", &sym_obj
))
315 if (gdbpy_is_string (sym_obj
))
318 struct block
*block
= NULL
;
319 struct cleanup
*cleanup
;
320 volatile struct gdb_exception except
;
322 var_name
= python_string_to_target_string (sym_obj
);
325 cleanup
= make_cleanup (xfree
, var_name
);
327 TRY_CATCH (except
, RETURN_MASK_ALL
)
329 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
331 block
= block_for_pc (get_frame_address_in_block (frame
));
332 var
= lookup_symbol (var_name
, block
, VAR_DOMAIN
, NULL
);
334 GDB_PY_HANDLE_EXCEPTION (except
);
338 PyErr_Format (PyExc_ValueError
,
339 _("variable '%s' not found"), var_name
);
340 do_cleanups (cleanup
);
345 do_cleanups (cleanup
);
349 PyErr_SetString (PyExc_TypeError
,
350 _("argument must be a symbol or string"));
354 TRY_CATCH (except
, RETURN_MASK_ALL
)
356 FRAPY_REQUIRE_VALID ((frame_object
*) self
, frame
);
358 val
= read_var_value (var
, frame
);
360 GDB_PY_HANDLE_EXCEPTION (except
);
363 return value_to_value_object (val
);
368 /* Implementation of gdb.selected_frame () -> gdb.Frame.
369 Returns the selected frame object. */
372 gdbpy_selected_frame (PyObject
*self
, PyObject
*args
)
374 struct frame_info
*frame
;
375 frame_object
*frame_obj
= NULL
; /* Initialize to appease gcc warning. */
376 volatile struct gdb_exception except
;
378 TRY_CATCH (except
, RETURN_MASK_ALL
)
380 frame
= get_selected_frame ("No frame is currently selected.");
381 frame_obj
= frame_info_to_frame_object (frame
);
383 GDB_PY_HANDLE_EXCEPTION (except
);
385 return (PyObject
*) frame_obj
;
388 /* Implementation of gdb.stop_reason_string (Integer) -> String.
389 Return a string explaining the unwind stop reason. */
392 gdbpy_frame_stop_reason_string (PyObject
*self
, PyObject
*args
)
397 if (!PyArg_ParseTuple (args
, "i", &reason
))
400 if (reason
< 0 || reason
> UNWIND_NO_SAVED_PC
)
402 PyErr_SetString (PyExc_ValueError
, "Invalid frame stop reason.");
406 str
= frame_stop_reason_string (reason
);
407 return PyUnicode_Decode (str
, strlen (str
), host_charset (), NULL
);
410 /* Implements the equality comparison for Frame objects.
411 All other comparison operators will throw a TypeError Python exception,
412 as they aren't valid for frames. */
415 frapy_richcompare (PyObject
*self
, PyObject
*other
, int op
)
419 if (!PyObject_TypeCheck (other
, &frame_object_type
)
420 || (op
!= Py_EQ
&& op
!= Py_NE
))
422 Py_INCREF (Py_NotImplemented
);
423 return Py_NotImplemented
;
426 if (frame_id_eq (((frame_object
*) self
)->frame_id
,
427 ((frame_object
*) other
)->frame_id
))
437 /* Sets up the Frame API in the gdb module. */
440 gdbpy_initialize_frames (void)
442 if (PyType_Ready (&frame_object_type
) < 0)
445 /* Note: These would probably be best exposed as class attributes of Frame,
446 but I don't know how to do it except by messing with the type's dictionary.
447 That seems too messy. */
448 PyModule_AddIntConstant (gdb_module
, "NORMAL_FRAME", NORMAL_FRAME
);
449 PyModule_AddIntConstant (gdb_module
, "DUMMY_FRAME", DUMMY_FRAME
);
450 PyModule_AddIntConstant (gdb_module
, "SIGTRAMP_FRAME", SIGTRAMP_FRAME
);
451 PyModule_AddIntConstant (gdb_module
, "SENTINEL_FRAME", SENTINEL_FRAME
);
452 PyModule_AddIntConstant (gdb_module
,
453 "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON
);
454 PyModule_AddIntConstant (gdb_module
,
455 "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID
);
456 PyModule_AddIntConstant (gdb_module
,
457 "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR
);
458 PyModule_AddIntConstant (gdb_module
,
459 "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID
);
460 PyModule_AddIntConstant (gdb_module
,
461 "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID
);
462 PyModule_AddIntConstant (gdb_module
,
463 "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC
);
465 Py_INCREF (&frame_object_type
);
466 PyModule_AddObject (gdb_module
, "Frame", (PyObject
*) &frame_object_type
);
471 static PyMethodDef frame_object_methods
[] = {
472 { "is_valid", frapy_is_valid
, METH_NOARGS
,
473 "is_valid () -> Boolean.\n\
474 Return true if this frame is valid, false if not." },
475 { "name", frapy_name
, METH_NOARGS
,
476 "name () -> String.\n\
477 Return the function name of the frame, or None if it can't be determined." },
478 { "type", frapy_type
, METH_NOARGS
,
479 "type () -> Integer.\n\
480 Return the type of the frame." },
481 { "unwind_stop_reason", frapy_unwind_stop_reason
, METH_NOARGS
,
482 "unwind_stop_reason () -> Integer.\n\
483 Return the reason why it's not possible to find frames older than this." },
484 { "pc", frapy_pc
, METH_NOARGS
,
486 Return the frame's resume address." },
487 { "older", frapy_older
, METH_NOARGS
,
488 "older () -> gdb.Frame.\n\
489 Return the frame that called this frame." },
490 { "newer", frapy_newer
, METH_NOARGS
,
491 "newer () -> gdb.Frame.\n\
492 Return the frame called by this frame." },
493 { "read_var", frapy_read_var
, METH_VARARGS
,
494 "read_var (variable) -> gdb.Value.\n\
495 Return the value of the variable in this frame." },
496 {NULL
} /* Sentinel */
499 static PyTypeObject frame_object_type
= {
500 PyObject_HEAD_INIT (NULL
)
502 "gdb.Frame", /* tp_name */
503 sizeof (frame_object
), /* tp_basicsize */
511 0, /* tp_as_number */
512 0, /* tp_as_sequence */
513 0, /* tp_as_mapping */
516 frapy_str
, /* tp_str */
519 0, /* tp_as_buffer */
520 Py_TPFLAGS_DEFAULT
, /* tp_flags */
521 "GDB frame object", /* tp_doc */
524 frapy_richcompare
, /* tp_richcompare */
525 0, /* tp_weaklistoffset */
528 frame_object_methods
, /* tp_methods */
533 0, /* tp_descr_get */
534 0, /* tp_descr_set */
535 0, /* tp_dictoffset */
538 PyType_GenericNew
/* tp_new */