aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/python-frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/python/python-frame.c')
-rw-r--r--gdb/python/python-frame.c539
1 files changed, 0 insertions, 539 deletions
diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c
deleted file mode 100644
index 279415c..0000000
--- a/gdb/python/python-frame.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* Python interface to stack frames
-
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "defs.h"
-#include "charset.h"
-#include "block.h"
-#include "frame.h"
-#include "exceptions.h"
-#include "symtab.h"
-#include "stack.h"
-#include "value.h"
-#include "python-internal.h"
-
-typedef struct {
- PyObject_HEAD
- struct frame_id frame_id;
- struct gdbarch *gdbarch;
-
- /* Marks that the FRAME_ID member actually holds the ID of the frame next
- to this, and not this frames' ID itself. This is a hack to permit Python
- frame objects which represent invalid frames (i.e., the last frame_info
- in a corrupt stack). The problem arises from the fact that this code
- relies on FRAME_ID to uniquely identify a frame, which is not always true
- for the last "frame" in a corrupt stack (it can have a null ID, or the same
- ID as the previous frame). Whenever get_prev_frame returns NULL, we
- record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
- int frame_id_is_next;
-} frame_object;
-
-/* Require a valid frame. This must be called inside a TRY_CATCH, or
- another context in which a gdb exception is allowed. */
-#define FRAPY_REQUIRE_VALID(frame_obj, frame) \
- do { \
- frame = frame_object_to_frame_info (frame_obj); \
- if (frame == NULL) \
- error ("Frame is invalid."); \
- } while (0)
-
-static PyTypeObject frame_object_type;
-
-/* Returns the frame_info object corresponding to the given Python Frame
- object. If the frame doesn't exist anymore (the frame id doesn't
- correspond to any frame in the inferior), returns NULL. */
-
-static struct frame_info *
-frame_object_to_frame_info (frame_object *frame_obj)
-{
- struct frame_info *frame;
-
- frame = frame_find_by_id (frame_obj->frame_id);
- if (frame == NULL)
- return NULL;
-
- if (frame_obj->frame_id_is_next)
- frame = get_prev_frame (frame);
-
- return frame;
-}
-
-/* Called by the Python interpreter to obtain string representation
- of the object. */
-
-static PyObject *
-frapy_str (PyObject *self)
-{
- char *s;
- PyObject *result;
- struct ui_file *strfile;
-
- strfile = mem_fileopen ();
- fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
- s = ui_file_xstrdup (strfile, NULL);
- result = PyString_FromString (s);
- xfree (s);
-
- return result;
-}
-
-/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
- Returns True if the frame corresponding to the frame_id of this
- object still exists in the inferior. */
-
-static PyObject *
-frapy_is_valid (PyObject *self, PyObject *args)
-{
- struct frame_info *frame;
-
- frame = frame_object_to_frame_info ((frame_object *) self);
- if (frame == NULL)
- Py_RETURN_FALSE;
-
- Py_RETURN_TRUE;
-}
-
-/* Implementation of gdb.Frame.name (self) -> String.
- Returns the name of the function corresponding to this frame. */
-
-static PyObject *
-frapy_name (PyObject *self, PyObject *args)
-{
- struct frame_info *frame;
- char *name;
- enum language lang;
- PyObject *result;
- volatile struct gdb_exception except;
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- find_frame_funname (frame, &name, &lang);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- if (name)
- result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
- else
- {
- result = Py_None;
- Py_INCREF (Py_None);
- }
-
- return result;
-}
-
-/* Implementation of gdb.Frame.type (self) -> Integer.
- Returns the frame type, namely one of the gdb.*_FRAME constants. */
-
-static PyObject *
-frapy_type (PyObject *self, PyObject *args)
-{
- struct frame_info *frame;
- enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */
- volatile struct gdb_exception except;
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- type = get_frame_type (frame);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- return PyInt_FromLong (type);
-}
-
-/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
- Returns one of the gdb.FRAME_UNWIND_* constants. */
-
-static PyObject *
-frapy_unwind_stop_reason (PyObject *self, PyObject *args)
-{
- struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
- volatile struct gdb_exception except;
- enum unwind_stop_reason stop_reason;
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- stop_reason = get_frame_unwind_stop_reason (frame);
-
- return PyInt_FromLong (stop_reason);
-}
-
-/* Implementation of gdb.Frame.pc (self) -> Long.
- Returns the frame's resume address. */
-
-static PyObject *
-frapy_pc (PyObject *self, PyObject *args)
-{
- CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
- struct frame_info *frame;
- volatile struct gdb_exception except;
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- pc = get_frame_pc (frame);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- return PyLong_FromUnsignedLongLong (pc);
-}
-
-/* Convert a frame_info struct to a Python Frame object.
- Sets a Python exception and returns NULL on error. */
-
-static frame_object *
-frame_info_to_frame_object (struct frame_info *frame)
-{
- frame_object *frame_obj;
-
- frame_obj = PyObject_New (frame_object, &frame_object_type);
- if (frame_obj == NULL)
- {
- PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object.");
- return NULL;
- }
-
- /* Try to get the previous frame, to determine if this is the last frame
- in a corrupt stack. If so, we need to store the frame_id of the next
- frame and not of this one (which is possibly invalid). */
- if (get_prev_frame (frame) == NULL
- && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
- && get_next_frame (frame) != NULL)
- {
- frame_obj->frame_id = get_frame_id (get_next_frame (frame));
- frame_obj->frame_id_is_next = 1;
- }
- else
- {
- frame_obj->frame_id = get_frame_id (frame);
- frame_obj->frame_id_is_next = 0;
- }
-
- frame_obj->gdbarch = get_frame_arch (frame);
-
- return frame_obj;
-}
-
-/* Implementation of gdb.Frame.older (self) -> gdb.Frame.
- Returns the frame immediately older (outer) to this frame, or None if
- there isn't one. */
-
-static PyObject *
-frapy_older (PyObject *self, PyObject *args)
-{
- struct frame_info *frame, *prev;
- volatile struct gdb_exception except;
- PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- prev = get_prev_frame (frame);
- if (prev)
- prev_obj = (PyObject *) frame_info_to_frame_object (prev);
- else
- {
- Py_INCREF (Py_None);
- prev_obj = Py_None;
- }
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- return prev_obj;
-}
-
-/* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
- Returns the frame immediately newer (inner) to this frame, or None if
- there isn't one. */
-
-static PyObject *
-frapy_newer (PyObject *self, PyObject *args)
-{
- struct frame_info *frame, *next;
- volatile struct gdb_exception except;
- PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- next = get_next_frame (frame);
- if (next)
- next_obj = (PyObject *) frame_info_to_frame_object (next);
- else
- {
- Py_INCREF (Py_None);
- next_obj = Py_None;
- }
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- return next_obj;
-}
-
-/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
- Returns the value of the given variable in this frame. The argument must be
- a string. Returns None if GDB can't find the specified variable. */
-
-static PyObject *
-frapy_read_var (PyObject *self, PyObject *args)
-{
- struct frame_info *frame;
- PyObject *sym_obj;
- struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
- struct value *val = NULL;
- volatile struct gdb_exception except;
-
- if (!PyArg_ParseTuple (args, "O", &sym_obj))
- return NULL;
-
- if (gdbpy_is_string (sym_obj))
- {
- char *var_name;
- struct block *block = NULL;
- struct cleanup *cleanup;
- volatile struct gdb_exception except;
-
- var_name = python_string_to_target_string (sym_obj);
- if (!var_name)
- return NULL;
- cleanup = make_cleanup (xfree, var_name);
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- block = block_for_pc (get_frame_address_in_block (frame));
- var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- if (!var)
- {
- PyErr_Format (PyExc_ValueError,
- _("variable '%s' not found"), var_name);
- do_cleanups (cleanup);
-
- return NULL;
- }
-
- do_cleanups (cleanup);
- }
- else
- {
- PyErr_SetString (PyExc_TypeError,
- _("argument must be a symbol or string"));
- return NULL;
- }
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
-
- val = read_var_value (var, frame);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- if (val)
- return value_to_value_object (val);
-
- Py_RETURN_NONE;
-}
-
-/* Implementation of gdb.selected_frame () -> gdb.Frame.
- Returns the selected frame object. */
-
-PyObject *
-gdbpy_selected_frame (PyObject *self, PyObject *args)
-{
- struct frame_info *frame;
- frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */
- volatile struct gdb_exception except;
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- frame = get_selected_frame ("No frame is currently selected.");
- frame_obj = frame_info_to_frame_object (frame);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- return (PyObject *) frame_obj;
-}
-
-/* Implementation of gdb.stop_reason_string (Integer) -> String.
- Return a string explaining the unwind stop reason. */
-
-PyObject *
-gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
-{
- int reason;
- const char *str;
-
- if (!PyArg_ParseTuple (args, "i", &reason))
- return NULL;
-
- if (reason < 0 || reason > UNWIND_NO_SAVED_PC)
- {
- PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason.");
- return NULL;
- }
-
- str = frame_stop_reason_string (reason);
- return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
-}
-
-/* Implements the equality comparison for Frame objects.
- All other comparison operators will throw a TypeError Python exception,
- as they aren't valid for frames. */
-
-static PyObject *
-frapy_richcompare (PyObject *self, PyObject *other, int op)
-{
- int result;
-
- if (!PyObject_TypeCheck (other, &frame_object_type)
- || (op != Py_EQ && op != Py_NE))
- {
- Py_INCREF (Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- if (frame_id_eq (((frame_object *) self)->frame_id,
- ((frame_object *) other)->frame_id))
- result = Py_EQ;
- else
- result = Py_NE;
-
- if (op == result)
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
-}
-
-/* Sets up the Frame API in the gdb module. */
-
-void
-gdbpy_initialize_frames (void)
-{
- if (PyType_Ready (&frame_object_type) < 0)
- return;
-
- /* Note: These would probably be best exposed as class attributes of Frame,
- but I don't know how to do it except by messing with the type's dictionary.
- That seems too messy. */
- PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME);
- PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME);
- PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
- PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID);
- PyModule_AddIntConstant (gdb_module,
- "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC);
-
- Py_INCREF (&frame_object_type);
- PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
-}
-
-
-
-static PyMethodDef frame_object_methods[] = {
- { "is_valid", frapy_is_valid, METH_NOARGS,
- "is_valid () -> Boolean.\n\
-Return true if this frame is valid, false if not." },
- { "name", frapy_name, METH_NOARGS,
- "name () -> String.\n\
-Return the function name of the frame, or None if it can't be determined." },
- { "type", frapy_type, METH_NOARGS,
- "type () -> Integer.\n\
-Return the type of the frame." },
- { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
- "unwind_stop_reason () -> Integer.\n\
-Return the reason why it's not possible to find frames older than this." },
- { "pc", frapy_pc, METH_NOARGS,
- "pc () -> Long.\n\
-Return the frame's resume address." },
- { "older", frapy_older, METH_NOARGS,
- "older () -> gdb.Frame.\n\
-Return the frame that called this frame." },
- { "newer", frapy_newer, METH_NOARGS,
- "newer () -> gdb.Frame.\n\
-Return the frame called by this frame." },
- { "read_var", frapy_read_var, METH_VARARGS,
- "read_var (variable) -> gdb.Value.\n\
-Return the value of the variable in this frame." },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject frame_object_type = {
- PyObject_HEAD_INIT (NULL)
- 0, /* ob_size */
- "gdb.Frame", /* tp_name */
- sizeof (frame_object), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- frapy_str, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- "GDB frame object", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- frapy_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- frame_object_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew /* tp_new */
-};