/* Python interface to stack frames
- Copyright (C) 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of GDB.
#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"
#include "symfile.h"
#include "objfiles.h"
+#include "user-regs.h"
+#include "py-ref.h"
typedef struct {
PyObject_HEAD
struct frame_info *
frame_object_to_frame_info (PyObject *obj)
{
- frame_object *frame_obj = (frame_object *) obj;
+ frame_object *frame_obj = (frame_object *) obj;
struct frame_info *frame;
frame = frame_find_by_id (frame_obj->frame_id);
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);
+ string_file strfile;
- return result;
+ fprint_frame_id (&strfile, ((frame_object *) self)->frame_id);
+ return PyString_FromString (strfile.c_str ());
}
/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
frapy_is_valid (PyObject *self, PyObject *args)
{
struct frame_info *frame = NULL;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
frame = frame_object_to_frame_info (self);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
if (frame == NULL)
Py_RETURN_FALSE;
frapy_name (PyObject *self, PyObject *args)
{
struct frame_info *frame;
- const char *name;
+ gdb::unique_xmalloc_ptr<char> name;
enum language lang;
PyObject *result;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
- find_frame_funname (frame, &name, &lang, NULL);
+ name = find_frame_funname (frame, &lang, NULL);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
if (name)
- result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
+ {
+ result = PyUnicode_Decode (name.get (), strlen (name.get ()),
+ host_charset (), NULL);
+ }
else
{
result = Py_None;
{
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)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
type = get_frame_type (frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return PyInt_FromLong (type);
}
{
struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
frame_object *obj = (frame_object *) self;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return gdbarch_to_arch_object (obj->gdbarch);
}
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)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
stop_reason = get_frame_unwind_stop_reason (frame);
{
CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
struct frame_info *frame;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
pc = get_frame_pc (frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return gdb_py_long_from_ulongest (pc);
}
+/* Implementation of gdb.Frame.read_register (self, register) -> gdb.Value.
+ Returns the value of a register in this frame. */
+
+static PyObject *
+frapy_read_register (PyObject *self, PyObject *args)
+{
+ const char *regnum_str;
+ struct value *val = NULL;
+
+ if (!PyArg_ParseTuple (args, "s", ®num_str))
+ return NULL;
+
+ TRY
+ {
+ struct frame_info *frame;
+ int regnum;
+
+ FRAPY_REQUIRE_VALID (self, frame);
+
+ regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
+ regnum_str,
+ strlen (regnum_str));
+ if (regnum >= 0)
+ val = value_of_register (regnum, frame);
+
+ if (val == NULL)
+ PyErr_SetString (PyExc_ValueError, _("Unknown register."));
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
+
+ return val == NULL ? NULL : value_to_value_object (val);
+}
+
/* Implementation of gdb.Frame.block (self) -> gdb.Block.
Returns the frame's code block. */
frapy_block (PyObject *self, PyObject *args)
{
struct frame_info *frame;
- struct block *block = NULL, *fn_block;
- volatile struct gdb_exception except;
+ const struct block *block = NULL, *fn_block;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
block = get_frame_block (frame, NULL);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
for (fn_block = block;
fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
{
PyErr_SetString (PyExc_RuntimeError,
- _("Cannot locate object file for block."));
+ _("Cannot locate block for frame."));
return NULL;
}
if (block)
{
- struct symtab *symt;
-
- symt = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
- return block_to_block_object (block, symt->objfile);
+ return block_to_block_object
+ (block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
}
Py_RETURN_NONE;
{
struct symbol *sym = NULL;
struct frame_info *frame;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
+ enum language funlang;
+
FRAPY_REQUIRE_VALID (self, frame);
- sym = find_pc_function (get_frame_address_in_block (frame));
+ gdb::unique_xmalloc_ptr<char> funname
+ = find_frame_funname (frame, &funlang, &sym);
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ END_CATCH
if (sym)
return symbol_to_symbol_object (sym);
PyObject *
frame_info_to_frame_object (struct frame_info *frame)
{
- frame_object *frame_obj;
- volatile struct gdb_exception except;
-
- frame_obj = PyObject_New (frame_object, &frame_object_type);
+ gdbpy_ref<frame_object> frame_obj (PyObject_New (frame_object,
+ &frame_object_type));
if (frame_obj == NULL)
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
/* Try to get the previous frame, to determine if this is the last frame
}
frame_obj->gdbarch = get_frame_arch (frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ gdbpy_convert_exception (except);
+ return NULL;
+ }
+ END_CATCH
- return (PyObject *) frame_obj;
+ return (PyObject *) frame_obj.release ();
}
/* Implementation of gdb.Frame.older (self) -> gdb.Frame.
static PyObject *
frapy_older (PyObject *self, PyObject *args)
{
- struct frame_info *frame, *prev;
- volatile struct gdb_exception except;
+ struct frame_info *frame, *prev = NULL;
PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (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);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
+
+ if (prev)
+ prev_obj = (PyObject *) frame_info_to_frame_object (prev);
+ else
+ {
+ Py_INCREF (Py_None);
+ prev_obj = Py_None;
+ }
return prev_obj;
}
static PyObject *
frapy_newer (PyObject *self, PyObject *args)
{
- struct frame_info *frame, *next;
- volatile struct gdb_exception except;
+ struct frame_info *frame, *next = NULL;
PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (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);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
+
+ if (next)
+ next_obj = (PyObject *) frame_info_to_frame_object (next);
+ else
+ {
+ Py_INCREF (Py_None);
+ next_obj = Py_None;
+ }
return next_obj;
}
frapy_find_sal (PyObject *self, PyObject *args)
{
struct frame_info *frame;
- struct symtab_and_line sal;
- volatile struct gdb_exception except;
PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
- find_frame_sal (frame, &sal);
+ symtab_and_line sal = find_frame_sal (frame);
sal_obj = symtab_and_line_to_sal_object (sal);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return sal_obj;
}
struct frame_info *frame;
PyObject *sym_obj, *block_obj = NULL;
struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
+ const struct block *block = NULL;
struct value *val = NULL;
- volatile struct gdb_exception except;
if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
return NULL;
var = symbol_object_to_symbol (sym_obj);
else if (gdbpy_is_string (sym_obj))
{
- char *var_name;
- const struct block *block = NULL;
- struct cleanup *cleanup;
- volatile struct gdb_exception except;
+ gdb::unique_xmalloc_ptr<char>
+ var_name (python_string_to_target_string (sym_obj));
- var_name = python_string_to_target_string (sym_obj);
if (!var_name)
return NULL;
- cleanup = make_cleanup (xfree, var_name);
if (block_obj)
{
}
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
+ struct block_symbol lookup_sym;
FRAPY_REQUIRE_VALID (self, frame);
if (!block)
block = get_frame_block (frame, NULL);
- var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
+ lookup_sym = lookup_symbol (var_name.get (), block, VAR_DOMAIN, NULL);
+ var = lookup_sym.symbol;
+ block = lookup_sym.block;
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ gdbpy_convert_exception (except);
+ return NULL;
+ }
+ END_CATCH
if (!var)
{
PyErr_Format (PyExc_ValueError,
- _("Variable '%s' not found."), var_name);
- do_cleanups (cleanup);
+ _("Variable '%s' not found."), var_name.get ());
return NULL;
}
-
- do_cleanups (cleanup);
}
else
{
return NULL;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, frame);
- val = read_var_value (var, frame);
+ val = read_var_value (var, block, frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return value_to_value_object (val);
}
frapy_select (PyObject *self, PyObject *args)
{
struct frame_info *fi;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
FRAPY_REQUIRE_VALID (self, fi);
select_frame (fi);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
Py_RETURN_NONE;
}
PyObject *
gdbpy_newest_frame (PyObject *self, PyObject *args)
{
- struct frame_info *frame;
- PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */
- volatile struct gdb_exception except;
+ struct frame_info *frame = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
frame = get_current_frame ();
- frame_obj = frame_info_to_frame_object (frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
- return frame_obj;
+ return frame_info_to_frame_object (frame);
}
/* Implementation of gdb.selected_frame () -> gdb.Frame.
PyObject *
gdbpy_selected_frame (PyObject *self, PyObject *args)
{
- struct frame_info *frame;
- PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */
- volatile struct gdb_exception except;
+ struct frame_info *frame = NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
frame = get_selected_frame ("No frame is currently selected.");
- frame_obj = frame_info_to_frame_object (frame);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
- return frame_obj;
+ return frame_info_to_frame_object (frame);
}
/* Implementation of gdb.stop_reason_string (Integer) -> String.
if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
{
- PyErr_SetString (PyExc_ValueError,
+ PyErr_SetString (PyExc_ValueError,
_("Invalid frame stop reason."));
return NULL;
}
- str = frame_stop_reason_string (reason);
+ str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
}
#define SET(name, description) \
if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
return -1;
-#define FIRST_ERROR(name) \
- if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
- return -1;
#include "unwind_stop_reasons.def"
#undef SET
-#undef FIRST_ERROR
return gdb_pymodule_addobject (gdb_module, "Frame",
(PyObject *) &frame_object_type);
{ "pc", frapy_pc, METH_NOARGS,
"pc () -> Long.\n\
Return the frame's resume address." },
+ { "read_register", frapy_read_register, METH_VARARGS,
+ "read_register (register_name) -> gdb.Value\n\
+Return the value of the register in the frame." },
{ "block", frapy_block, METH_NOARGS,
"block () -> gdb.Block.\n\
Return the frame's code block." },