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:
Tom Tromey
2016-11-12 12:07:16 -07:00
parent 3b4e0e01f8
commit 2bd5759dcb
2 changed files with 102 additions and 115 deletions

View File

@ -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.

View File

@ -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