mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-05-28 22:21:26 +08:00
Use gdbpy_ref in py-prettyprint.c
This changes some spots in py-prettyprint.c to use gdbpy_ref. It also changes push_dummy_python_frame to be a class, rather than having it create a cleanup. 2017-01-10 Tom Tromey <tom@tromey.com> * python/py-prettyprint.c (print_stack_unless_memory_error) (print_string_repr, print_children): Use gdbpy_ref. (dummy_python_frame): New class. (dummy_python_frame::dummy_python_frame): Rename from push_dummy_python_frame. (py_restore_tstate): Remove.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2017-01-10 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
* python/py-prettyprint.c (print_stack_unless_memory_error)
|
||||||
|
(print_string_repr, print_children): Use gdbpy_ref.
|
||||||
|
(dummy_python_frame): New class.
|
||||||
|
(dummy_python_frame::dummy_python_frame): Rename from
|
||||||
|
push_dummy_python_frame.
|
||||||
|
(py_restore_tstate): Remove.
|
||||||
|
|
||||||
2017-01-10 Tom Tromey <tom@tromey.com>
|
2017-01-10 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* python/py-framefilter.c (py_print_frame): Use gdbpy_ref.
|
* python/py-framefilter.c (py_print_frame): Use gdbpy_ref.
|
||||||
|
@ -252,13 +252,13 @@ print_stack_unless_memory_error (struct ui_file *stream)
|
|||||||
{
|
{
|
||||||
if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
|
if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
|
||||||
{
|
{
|
||||||
struct cleanup *cleanup;
|
|
||||||
PyObject *type, *value, *trace;
|
PyObject *type, *value, *trace;
|
||||||
|
|
||||||
PyErr_Fetch (&type, &value, &trace);
|
PyErr_Fetch (&type, &value, &trace);
|
||||||
cleanup = make_cleanup_py_decref (type);
|
|
||||||
make_cleanup_py_decref (value);
|
gdbpy_ref type_ref (type);
|
||||||
make_cleanup_py_decref (trace);
|
gdbpy_ref value_ref (value);
|
||||||
|
gdbpy_ref trace_ref (trace);
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char>
|
gdb::unique_xmalloc_ptr<char>
|
||||||
msg (gdbpy_exception_to_string (type, value));
|
msg (gdbpy_exception_to_string (type, value));
|
||||||
@ -268,8 +268,6 @@ print_stack_unless_memory_error (struct ui_file *stream)
|
|||||||
else
|
else
|
||||||
fprintf_filtered (stream, _("<error reading variable: %s>"),
|
fprintf_filtered (stream, _("<error reading variable: %s>"),
|
||||||
msg.get ());
|
msg.get ());
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
@ -286,17 +284,14 @@ print_string_repr (PyObject *printer, const char *hint,
|
|||||||
struct gdbarch *gdbarch)
|
struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
struct value *replacement = NULL;
|
struct value *replacement = NULL;
|
||||||
PyObject *py_str = NULL;
|
|
||||||
enum string_repr_result result = string_repr_ok;
|
enum string_repr_result result = string_repr_ok;
|
||||||
|
|
||||||
py_str = pretty_print_one_value (printer, &replacement);
|
gdbpy_ref py_str (pretty_print_one_value (printer, &replacement));
|
||||||
if (py_str)
|
if (py_str != NULL)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanup = make_cleanup_py_decref (py_str);
|
|
||||||
|
|
||||||
if (py_str == Py_None)
|
if (py_str == Py_None)
|
||||||
result = string_repr_none;
|
result = string_repr_none;
|
||||||
else if (gdbpy_is_lazy_string (py_str))
|
else if (gdbpy_is_lazy_string (py_str.get ()))
|
||||||
{
|
{
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
long length;
|
long length;
|
||||||
@ -304,7 +299,7 @@ print_string_repr (PyObject *printer, const char *hint,
|
|||||||
gdb::unique_xmalloc_ptr<char> encoding;
|
gdb::unique_xmalloc_ptr<char> encoding;
|
||||||
struct value_print_options local_opts = *options;
|
struct value_print_options local_opts = *options;
|
||||||
|
|
||||||
gdbpy_extract_lazy_string (py_str, &addr, &type,
|
gdbpy_extract_lazy_string (py_str.get (), &addr, &type,
|
||||||
&length, &encoding);
|
&length, &encoding);
|
||||||
|
|
||||||
local_opts.addressprint = 0;
|
local_opts.addressprint = 0;
|
||||||
@ -313,22 +308,20 @@ print_string_repr (PyObject *printer, const char *hint,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PyObject *string;
|
gdbpy_ref string
|
||||||
|
(python_string_to_target_python_string (py_str.get ()));
|
||||||
string = python_string_to_target_python_string (py_str);
|
if (string != NULL)
|
||||||
if (string)
|
|
||||||
{
|
{
|
||||||
char *output;
|
char *output;
|
||||||
long length;
|
long length;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
|
|
||||||
make_cleanup_py_decref (string);
|
|
||||||
#ifdef IS_PY3K
|
#ifdef IS_PY3K
|
||||||
output = PyBytes_AS_STRING (string);
|
output = PyBytes_AS_STRING (string.get ());
|
||||||
length = PyBytes_GET_SIZE (string);
|
length = PyBytes_GET_SIZE (string.get ());
|
||||||
#else
|
#else
|
||||||
output = PyString_AsString (string);
|
output = PyString_AsString (string.get ());
|
||||||
length = PyString_Size (string);
|
length = PyString_Size (string.get ());
|
||||||
#endif
|
#endif
|
||||||
type = builtin_type (gdbarch)->builtin_char;
|
type = builtin_type (gdbarch)->builtin_char;
|
||||||
|
|
||||||
@ -344,8 +337,6 @@ print_string_repr (PyObject *printer, const char *hint,
|
|||||||
print_stack_unless_memory_error (stream);
|
print_stack_unless_memory_error (stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
}
|
||||||
else if (replacement)
|
else if (replacement)
|
||||||
{
|
{
|
||||||
@ -364,80 +355,84 @@ print_string_repr (PyObject *printer, const char *hint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IS_PY3K
|
#ifndef IS_PY3K
|
||||||
static void
|
|
||||||
py_restore_tstate (void *p)
|
|
||||||
{
|
|
||||||
PyFrameObject *frame = (PyFrameObject *) p;
|
|
||||||
PyThreadState *tstate = PyThreadState_GET ();
|
|
||||||
|
|
||||||
tstate->frame = frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a dummy PyFrameObject, needed to work around
|
/* Create a dummy PyFrameObject, needed to work around
|
||||||
a Python-2.4 bug with generators. */
|
a Python-2.4 bug with generators. */
|
||||||
static PyObject *
|
class dummy_python_frame
|
||||||
push_dummy_python_frame (void)
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
dummy_python_frame ();
|
||||||
|
|
||||||
|
~dummy_python_frame ()
|
||||||
|
{
|
||||||
|
if (m_valid)
|
||||||
|
m_tstate->frame = m_saved_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool failed () const
|
||||||
|
{
|
||||||
|
return !m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
|
PyFrameObject *m_saved_frame;
|
||||||
|
gdbpy_ref m_frame;
|
||||||
|
PyThreadState *m_tstate;
|
||||||
|
};
|
||||||
|
|
||||||
|
dummy_python_frame::dummy_python_frame ()
|
||||||
|
: m_valid (false),
|
||||||
|
m_saved_frame (NULL),
|
||||||
|
m_tstate (NULL)
|
||||||
{
|
{
|
||||||
PyObject *empty_string, *null_tuple, *globals;
|
|
||||||
PyCodeObject *code;
|
PyCodeObject *code;
|
||||||
PyFrameObject *frame;
|
PyFrameObject *frame;
|
||||||
PyThreadState *tstate;
|
|
||||||
|
|
||||||
empty_string = PyString_FromString ("");
|
gdbpy_ref empty_string (PyString_FromString (""));
|
||||||
if (!empty_string)
|
if (empty_string == NULL)
|
||||||
return NULL;
|
return;
|
||||||
|
|
||||||
null_tuple = PyTuple_New (0);
|
gdbpy_ref null_tuple (PyTuple_New (0));
|
||||||
if (!null_tuple)
|
if (null_tuple == NULL)
|
||||||
{
|
return;
|
||||||
Py_DECREF (empty_string);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
code = PyCode_New (0, /* argcount */
|
code = PyCode_New (0, /* argcount */
|
||||||
0, /* nlocals */
|
0, /* locals */
|
||||||
0, /* stacksize */
|
0, /* stacksize */
|
||||||
0, /* flags */
|
0, /* flags */
|
||||||
empty_string, /* code */
|
empty_string.get (), /* code */
|
||||||
null_tuple, /* consts */
|
null_tuple.get (), /* consts */
|
||||||
null_tuple, /* names */
|
null_tuple.get (), /* names */
|
||||||
null_tuple, /* varnames */
|
null_tuple.get (), /* varnames */
|
||||||
#if PYTHON_API_VERSION >= 1010
|
#if PYTHON_API_VERSION >= 1010
|
||||||
null_tuple, /* freevars */
|
null_tuple.get (), /* freevars */
|
||||||
null_tuple, /* cellvars */
|
null_tuple.get (), /* cellvars */
|
||||||
#endif
|
#endif
|
||||||
empty_string, /* filename */
|
empty_string.get (), /* filename */
|
||||||
empty_string, /* name */
|
empty_string.get (), /* name */
|
||||||
1, /* firstlineno */
|
1, /* firstlineno */
|
||||||
empty_string /* lnotab */
|
empty_string.get () /* lnotab */
|
||||||
);
|
);
|
||||||
|
if (code == NULL)
|
||||||
|
return;
|
||||||
|
gdbpy_ref code_holder ((PyObject *) code);
|
||||||
|
|
||||||
Py_DECREF (empty_string);
|
gdbpy_ref globals (PyDict_New ());
|
||||||
Py_DECREF (null_tuple);
|
if (globals == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!code)
|
m_tstate = PyThreadState_GET ();
|
||||||
return NULL;
|
frame = PyFrame_New (m_tstate, code, globals.get (), NULL);
|
||||||
|
if (frame == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
globals = PyDict_New ();
|
m_frame.reset ((PyObject *) frame);
|
||||||
if (!globals)
|
m_tstate->frame = frame;
|
||||||
{
|
m_saved_frame = frame->f_back;
|
||||||
Py_DECREF (code);
|
m_valid = true;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tstate = PyThreadState_GET ();
|
|
||||||
|
|
||||||
frame = PyFrame_New (tstate, code, globals, NULL);
|
|
||||||
|
|
||||||
Py_DECREF (globals);
|
|
||||||
Py_DECREF (code);
|
|
||||||
|
|
||||||
if (!frame)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tstate->frame = frame;
|
|
||||||
make_cleanup (py_restore_tstate, frame->f_back);
|
|
||||||
return (PyObject *) frame;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -453,11 +448,6 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
{
|
{
|
||||||
int is_map, is_array, done_flag, pretty;
|
int is_map, is_array, done_flag, pretty;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
PyObject *children, *iter;
|
|
||||||
#ifndef IS_PY3K
|
|
||||||
PyObject *frame;
|
|
||||||
#endif
|
|
||||||
struct cleanup *cleanups;
|
|
||||||
|
|
||||||
if (! PyObject_HasAttr (printer, gdbpy_children_cst))
|
if (! PyObject_HasAttr (printer, gdbpy_children_cst))
|
||||||
return;
|
return;
|
||||||
@ -467,23 +457,20 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
is_map = hint && ! strcmp (hint, "map");
|
is_map = hint && ! strcmp (hint, "map");
|
||||||
is_array = hint && ! strcmp (hint, "array");
|
is_array = hint && ! strcmp (hint, "array");
|
||||||
|
|
||||||
children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
|
gdbpy_ref children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
|
||||||
NULL);
|
NULL));
|
||||||
if (! children)
|
if (children == NULL)
|
||||||
{
|
{
|
||||||
print_stack_unless_memory_error (stream);
|
print_stack_unless_memory_error (stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanups = make_cleanup_py_decref (children);
|
gdbpy_ref iter (PyObject_GetIter (children.get ()));
|
||||||
|
if (iter == NULL)
|
||||||
iter = PyObject_GetIter (children);
|
|
||||||
if (!iter)
|
|
||||||
{
|
{
|
||||||
print_stack_unless_memory_error (stream);
|
print_stack_unless_memory_error (stream);
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
make_cleanup_py_decref (iter);
|
|
||||||
|
|
||||||
/* Use the prettyformat_arrays option if we are printing an array,
|
/* Use the prettyformat_arrays option if we are printing an array,
|
||||||
and the pretty option otherwise. */
|
and the pretty option otherwise. */
|
||||||
@ -501,23 +488,22 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
where it insists on having a non-NULL tstate->frame when
|
where it insists on having a non-NULL tstate->frame when
|
||||||
a generator is called. */
|
a generator is called. */
|
||||||
#ifndef IS_PY3K
|
#ifndef IS_PY3K
|
||||||
frame = push_dummy_python_frame ();
|
dummy_python_frame frame;
|
||||||
if (!frame)
|
if (frame.failed ())
|
||||||
{
|
{
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
make_cleanup_py_decref (frame);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
done_flag = 0;
|
done_flag = 0;
|
||||||
for (i = 0; i < options->print_max; ++i)
|
for (i = 0; i < options->print_max; ++i)
|
||||||
{
|
{
|
||||||
PyObject *py_v, *item = PyIter_Next (iter);
|
PyObject *py_v;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct cleanup *inner_cleanup;
|
|
||||||
|
|
||||||
if (! item)
|
gdbpy_ref item (PyIter_Next (iter.get ()));
|
||||||
|
if (item == NULL)
|
||||||
{
|
{
|
||||||
if (PyErr_Occurred ())
|
if (PyErr_Occurred ())
|
||||||
print_stack_unless_memory_error (stream);
|
print_stack_unless_memory_error (stream);
|
||||||
@ -528,16 +514,15 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! PyTuple_Check (item) || PyTuple_Size (item) != 2)
|
if (! PyTuple_Check (item.get ()) || PyTuple_Size (item.get ()) != 2)
|
||||||
{
|
{
|
||||||
PyErr_SetString (PyExc_TypeError,
|
PyErr_SetString (PyExc_TypeError,
|
||||||
_("Result of children iterator not a tuple"
|
_("Result of children iterator not a tuple"
|
||||||
" of two elements."));
|
" of two elements."));
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
Py_DECREF (item);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (! PyArg_ParseTuple (item, "sO", &name, &py_v))
|
if (! PyArg_ParseTuple (item.get (), "sO", &name, &py_v))
|
||||||
{
|
{
|
||||||
/* The user won't necessarily get a stack trace here, so provide
|
/* The user won't necessarily get a stack trace here, so provide
|
||||||
more context. */
|
more context. */
|
||||||
@ -545,10 +530,8 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
fprintf_unfiltered (gdb_stderr,
|
fprintf_unfiltered (gdb_stderr,
|
||||||
_("Bad result from children iterator.\n"));
|
_("Bad result from children iterator.\n"));
|
||||||
gdbpy_print_stack ();
|
gdbpy_print_stack ();
|
||||||
Py_DECREF (item);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inner_cleanup = make_cleanup_py_decref (item);
|
|
||||||
|
|
||||||
/* Print initial "{". For other elements, there are three
|
/* Print initial "{". For other elements, there are three
|
||||||
cases:
|
cases:
|
||||||
@ -643,8 +626,6 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
|
|
||||||
if (is_map && i % 2 == 0)
|
if (is_map && i % 2 == 0)
|
||||||
fputs_filtered ("] = ", stream);
|
fputs_filtered ("] = ", stream);
|
||||||
|
|
||||||
do_cleanups (inner_cleanup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
@ -665,9 +646,6 @@ print_children (PyObject *printer, const char *hint,
|
|||||||
}
|
}
|
||||||
fputs_filtered ("}", stream);
|
fputs_filtered ("}", stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
do_cleanups (cleanups);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ext_lang_rc
|
enum ext_lang_rc
|
||||||
|
Reference in New Issue
Block a user