X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-prettyprint.c;h=ac0506f3e11eeb56be9252dd8ca481778d264bb8;hb=5c329e6ab4c7bba9b83155571b150756210001df;hp=fb3d9b1f14af6ebd237820cb72614368136b59ab;hpb=1eba63835ea23cbae6059c076db985a47e39ce24;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index fb3d9b1f14..ac0506f3e1 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -1,6 +1,6 @@ /* Python pretty-printing - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -45,7 +45,7 @@ enum string_repr_result will return None. On error, it will set the Python error and return NULL. */ -static PyObject * +static gdbpy_ref<> search_pp_list (PyObject *list, PyObject *value) { Py_ssize_t pp_list_size, list_index; @@ -60,7 +60,7 @@ search_pp_list (PyObject *list, PyObject *value) /* Skip if disabled. */ if (PyObject_HasAttr (function, gdbpy_enabled_cst)) { - gdbpy_ref attr (PyObject_GetAttr (function, gdbpy_enabled_cst)); + gdbpy_ref<> attr (PyObject_GetAttr (function, gdbpy_enabled_cst)); int cmp; if (attr == NULL) @@ -73,14 +73,15 @@ search_pp_list (PyObject *list, PyObject *value) continue; } - gdbpy_ref printer (PyObject_CallFunctionObjArgs (function, value, NULL)); + gdbpy_ref<> printer (PyObject_CallFunctionObjArgs (function, value, + NULL)); if (printer == NULL) return NULL; else if (printer != Py_None) - return printer.release (); + return printer; } - Py_RETURN_NONE; + return gdbpy_ref<>::new_reference (Py_None); } /* Subroutine of find_pretty_printer to simplify it. @@ -96,16 +97,16 @@ find_pretty_printer_from_objfiles (PyObject *value) ALL_OBJFILES (obj) { - PyObject *objf = objfile_to_objfile_object (obj); - if (!objf) + gdbpy_ref<> objf = objfile_to_objfile_object (obj); + if (objf == NULL) { /* Ignore the error and continue. */ PyErr_Clear (); continue; } - gdbpy_ref pp_list (objfpy_get_printers (objf, NULL)); - gdbpy_ref function (search_pp_list (pp_list.get (), value)); + gdbpy_ref<> pp_list (objfpy_get_printers (objf.get (), NULL)); + gdbpy_ref<> function (search_pp_list (pp_list.get (), value)); /* If there is an error in any objfile list, abort the search and exit. */ if (function == NULL) @@ -124,14 +125,14 @@ find_pretty_printer_from_objfiles (PyObject *value) The result is Py_None, suitably inc-ref'd, if no pretty-printer was found. Otherwise the result is the pretty-printer function, suitably inc-ref'd. */ -static PyObject * +static gdbpy_ref<> find_pretty_printer_from_progspace (PyObject *value) { - PyObject *obj = pspace_to_pspace_object (current_program_space); + gdbpy_ref<> obj = pspace_to_pspace_object (current_program_space); - if (!obj) + if (obj == NULL) return NULL; - gdbpy_ref pp_list (pspy_get_printers (obj, NULL)); + gdbpy_ref<> pp_list (pspy_get_printers (obj.get (), NULL)); return search_pp_list (pp_list.get (), value); } @@ -141,17 +142,17 @@ find_pretty_printer_from_progspace (PyObject *value) The result is Py_None, suitably inc-ref'd, if no pretty-printer was found. Otherwise the result is the pretty-printer function, suitably inc-ref'd. */ -static PyObject * +static gdbpy_ref<> find_pretty_printer_from_gdb (PyObject *value) { /* Fetch the global pretty printer list. */ if (gdb_python_module == NULL || ! PyObject_HasAttrString (gdb_python_module, "pretty_printers")) - Py_RETURN_NONE; - gdbpy_ref pp_list (PyObject_GetAttrString (gdb_python_module, - "pretty_printers")); + return gdbpy_ref<>::new_reference (Py_None); + gdbpy_ref<> pp_list (PyObject_GetAttrString (gdb_python_module, + "pretty_printers")); if (pp_list == NULL || ! PyList_Check (pp_list.get ())) - Py_RETURN_NONE; + return gdbpy_ref<>::new_reference (Py_None); return search_pp_list (pp_list.get (), value); } @@ -160,19 +161,19 @@ find_pretty_printer_from_gdb (PyObject *value) pretty-printer exists, return None. If one exists, return a new reference. On error, set the Python error and return NULL. */ -static PyObject * +static gdbpy_ref<> find_pretty_printer (PyObject *value) { /* Look at the pretty-printer list for each objfile in the current program-space. */ - gdbpy_ref function (find_pretty_printer_from_objfiles (value)); + gdbpy_ref<> function (find_pretty_printer_from_objfiles (value)); if (function == NULL || function != Py_None) - return function.release (); + return function; /* Look at the pretty-printer list for the current program-space. */ - function.reset (find_pretty_printer_from_progspace (value)); + function = find_pretty_printer_from_progspace (value); if (function == NULL || function != Py_None) - return function.release (); + return function; /* Look at the pretty-printer list in the gdb module. */ return find_pretty_printer_from_gdb (value); @@ -186,25 +187,31 @@ find_pretty_printer (PyObject *value) is returned. On error, *OUT_VALUE is set to NULL, NULL is returned, with a python exception set. */ -static PyObject * +static gdbpy_ref<> pretty_print_one_value (PyObject *printer, struct value **out_value) { - PyObject *result = NULL; + gdbpy_ref<> result; *out_value = NULL; TRY { - result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL); - if (result) + if (!PyObject_HasAttr (printer, gdbpy_to_string_cst)) + result = gdbpy_ref<>::new_reference (Py_None); + else { - if (! gdbpy_is_string (result) && ! gdbpy_is_lazy_string (result) - && result != Py_None) + result.reset (PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, + NULL)); + if (result != NULL) { - *out_value = convert_value_from_python (result); - if (PyErr_Occurred ()) - *out_value = NULL; - Py_DECREF (result); - result = NULL; + if (! gdbpy_is_string (result.get ()) + && ! gdbpy_is_lazy_string (result.get ()) + && result != Py_None) + { + *out_value = convert_value_from_python (result.get ()); + if (PyErr_Occurred ()) + *out_value = NULL; + result = NULL; + } } } } @@ -228,8 +235,8 @@ gdbpy_get_display_hint (PyObject *printer) if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst)) return NULL; - gdbpy_ref hint (PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst, - NULL)); + gdbpy_ref<> hint (PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst, + NULL)); if (hint != NULL) { if (gdbpy_is_string (hint.get ())) @@ -252,24 +259,14 @@ print_stack_unless_memory_error (struct ui_file *stream) { if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { - struct cleanup *cleanup; - PyObject *type, *value, *trace; - - PyErr_Fetch (&type, &value, &trace); - cleanup = make_cleanup_py_decref (type); - make_cleanup_py_decref (value); - make_cleanup_py_decref (trace); - - gdb::unique_xmalloc_ptr - msg (gdbpy_exception_to_string (type, value)); + gdbpy_err_fetch fetched_error; + gdb::unique_xmalloc_ptr msg = fetched_error.to_string (); if (msg == NULL || *msg == '\0') fprintf_filtered (stream, _("")); else fprintf_filtered (stream, _(""), msg.get ()); - - do_cleanups (cleanup); } else gdbpy_print_stack (); @@ -286,17 +283,14 @@ print_string_repr (PyObject *printer, const char *hint, struct gdbarch *gdbarch) { struct value *replacement = NULL; - PyObject *py_str = NULL; enum string_repr_result result = string_repr_ok; - py_str = pretty_print_one_value (printer, &replacement); - if (py_str) + gdbpy_ref<> py_str = pretty_print_one_value (printer, &replacement); + if (py_str != NULL) { - struct cleanup *cleanup = make_cleanup_py_decref (py_str); - if (py_str == Py_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; long length; @@ -304,7 +298,7 @@ print_string_repr (PyObject *printer, const char *hint, gdb::unique_xmalloc_ptr encoding; 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); local_opts.addressprint = 0; @@ -313,22 +307,20 @@ print_string_repr (PyObject *printer, const char *hint, } else { - PyObject *string; - - string = python_string_to_target_python_string (py_str); - if (string) + gdbpy_ref<> string + = python_string_to_target_python_string (py_str.get ()); + if (string != NULL) { char *output; long length; struct type *type; - make_cleanup_py_decref (string); #ifdef IS_PY3K - output = PyBytes_AS_STRING (string); - length = PyBytes_GET_SIZE (string); + output = PyBytes_AS_STRING (string.get ()); + length = PyBytes_GET_SIZE (string.get ()); #else - output = PyString_AsString (string); - length = PyString_Size (string); + output = PyString_AsString (string.get ()); + length = PyString_Size (string.get ()); #endif type = builtin_type (gdbarch)->builtin_char; @@ -344,8 +336,6 @@ print_string_repr (PyObject *printer, const char *hint, print_stack_unless_memory_error (stream); } } - - do_cleanups (cleanup); } else if (replacement) { @@ -364,80 +354,84 @@ print_string_repr (PyObject *printer, const char *hint, } #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 a Python-2.4 bug with generators. */ -static PyObject * -push_dummy_python_frame (void) +class dummy_python_frame { - PyObject *empty_string, *null_tuple, *globals; - PyCodeObject *code; - PyFrameObject *frame; - PyThreadState *tstate; + public: - empty_string = PyString_FromString (""); - if (!empty_string) - return NULL; + dummy_python_frame (); - null_tuple = PyTuple_New (0); - if (!null_tuple) - { - Py_DECREF (empty_string); - return NULL; - } + ~dummy_python_frame () + { + if (m_valid) + m_tstate->frame = m_saved_frame; + } - code = PyCode_New (0, /* argcount */ - 0, /* nlocals */ - 0, /* stacksize */ - 0, /* flags */ - empty_string, /* code */ - null_tuple, /* consts */ - null_tuple, /* names */ - null_tuple, /* varnames */ -#if PYTHON_API_VERSION >= 1010 - null_tuple, /* freevars */ - null_tuple, /* cellvars */ -#endif - empty_string, /* filename */ - empty_string, /* name */ - 1, /* firstlineno */ - empty_string /* lnotab */ - ); + bool failed () const + { + return !m_valid; + } - Py_DECREF (empty_string); - Py_DECREF (null_tuple); + private: - if (!code) - return NULL; + bool m_valid; + PyFrameObject *m_saved_frame; + gdbpy_ref<> m_frame; + PyThreadState *m_tstate; +}; - globals = PyDict_New (); - if (!globals) - { - Py_DECREF (code); - return NULL; - } +dummy_python_frame::dummy_python_frame () +: m_valid (false), + m_saved_frame (NULL), + m_tstate (NULL) +{ + PyCodeObject *code; + PyFrameObject *frame; - tstate = PyThreadState_GET (); + gdbpy_ref<> empty_string (PyString_FromString ("")); + if (empty_string == NULL) + return; - frame = PyFrame_New (tstate, code, globals, NULL); + gdbpy_ref<> null_tuple (PyTuple_New (0)); + if (null_tuple == NULL) + return; - Py_DECREF (globals); - Py_DECREF (code); + code = PyCode_New (0, /* argcount */ + 0, /* locals */ + 0, /* stacksize */ + 0, /* flags */ + empty_string.get (), /* code */ + null_tuple.get (), /* consts */ + null_tuple.get (), /* names */ + null_tuple.get (), /* varnames */ +#if PYTHON_API_VERSION >= 1010 + null_tuple.get (), /* freevars */ + null_tuple.get (), /* cellvars */ +#endif + empty_string.get (), /* filename */ + empty_string.get (), /* name */ + 1, /* firstlineno */ + empty_string.get () /* lnotab */ + ); + if (code == NULL) + return; + gdbpy_ref<> code_holder ((PyObject *) code); - if (!frame) - return NULL; + gdbpy_ref<> globals (PyDict_New ()); + if (globals == NULL) + return; + + m_tstate = PyThreadState_GET (); + frame = PyFrame_New (m_tstate, code, globals.get (), NULL); + if (frame == NULL) + return; - tstate->frame = frame; - make_cleanup (py_restore_tstate, frame->f_back); - return (PyObject *) frame; + m_frame.reset ((PyObject *) frame); + m_tstate->frame = frame; + m_saved_frame = frame->f_back; + m_valid = true; } #endif @@ -453,11 +447,6 @@ print_children (PyObject *printer, const char *hint, { int is_map, is_array, done_flag, pretty; unsigned int i; - PyObject *children, *iter; -#ifndef IS_PY3K - PyObject *frame; -#endif - struct cleanup *cleanups; if (! PyObject_HasAttr (printer, gdbpy_children_cst)) return; @@ -467,23 +456,20 @@ print_children (PyObject *printer, const char *hint, is_map = hint && ! strcmp (hint, "map"); is_array = hint && ! strcmp (hint, "array"); - children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst, - NULL); - if (! children) + gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst, + NULL)); + if (children == NULL) { print_stack_unless_memory_error (stream); return; } - cleanups = make_cleanup_py_decref (children); - - iter = PyObject_GetIter (children); - if (!iter) + gdbpy_ref<> iter (PyObject_GetIter (children.get ())); + if (iter == NULL) { 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, and the pretty option otherwise. */ @@ -501,23 +487,22 @@ print_children (PyObject *printer, const char *hint, where it insists on having a non-NULL tstate->frame when a generator is called. */ #ifndef IS_PY3K - frame = push_dummy_python_frame (); - if (!frame) + dummy_python_frame frame; + if (frame.failed ()) { gdbpy_print_stack (); - goto done; + return; } - make_cleanup_py_decref (frame); #endif done_flag = 0; for (i = 0; i < options->print_max; ++i) { - PyObject *py_v, *item = PyIter_Next (iter); + PyObject *py_v; const char *name; - struct cleanup *inner_cleanup; - if (! item) + gdbpy_ref<> item (PyIter_Next (iter.get ())); + if (item == NULL) { if (PyErr_Occurred ()) print_stack_unless_memory_error (stream); @@ -528,16 +513,15 @@ print_children (PyObject *printer, const char *hint, break; } - if (! PyTuple_Check (item) || PyTuple_Size (item) != 2) + if (! PyTuple_Check (item.get ()) || PyTuple_Size (item.get ()) != 2) { PyErr_SetString (PyExc_TypeError, _("Result of children iterator not a tuple" " of two elements.")); gdbpy_print_stack (); - Py_DECREF (item); 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 more context. */ @@ -545,10 +529,8 @@ print_children (PyObject *printer, const char *hint, fprintf_unfiltered (gdb_stderr, _("Bad result from children iterator.\n")); gdbpy_print_stack (); - Py_DECREF (item); continue; } - inner_cleanup = make_cleanup_py_decref (item); /* Print initial "{". For other elements, there are three cases: @@ -643,8 +625,6 @@ print_children (PyObject *printer, const char *hint, if (is_map && i % 2 == 0) fputs_filtered ("] = ", stream); - - do_cleanups (inner_cleanup); } if (i) @@ -665,9 +645,6 @@ print_children (PyObject *printer, const char *hint, } fputs_filtered ("}", stream); } - - done: - do_cleanups (cleanups); } enum ext_lang_rc @@ -682,7 +659,9 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, struct gdbarch *gdbarch = get_type_arch (type); struct value *value; enum string_repr_result print_result; - const gdb_byte *valaddr = value_contents_for_printing (val); + + if (value_lazy (val)) + value_fetch_lazy (val); /* No pretty-printer support for unavailable values. */ if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) @@ -696,7 +675,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, /* Instantiate the printer. */ value = value_from_component (val, type, embedded_offset); - gdbpy_ref val_obj (value_to_value_object (value)); + gdbpy_ref<> val_obj (value_to_value_object (value)); if (val_obj == NULL) { print_stack_unless_memory_error (stream); @@ -704,7 +683,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, } /* Find the constructor. */ - gdbpy_ref printer (find_pretty_printer (val_obj.get ())); + gdbpy_ref<> printer (find_pretty_printer (val_obj.get ())); if (printer == NULL) { print_stack_unless_memory_error (stream); @@ -739,15 +718,13 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, set to the replacement value and this function returns NULL. On error, *REPLACEMENT is set to NULL and this function also returns NULL. */ -PyObject * +gdbpy_ref<> apply_varobj_pretty_printer (PyObject *printer_obj, struct value **replacement, struct ui_file *stream) { - PyObject *py_str = NULL; - *replacement = NULL; - py_str = pretty_print_one_value (printer_obj, replacement); + gdbpy_ref<> py_str = pretty_print_one_value (printer_obj, replacement); if (*replacement == NULL && py_str == NULL) print_stack_unless_memory_error (stream); @@ -759,7 +736,7 @@ apply_varobj_pretty_printer (PyObject *printer_obj, reference to the object if successful; returns NULL if not. VALUE is the value for which a printer tests to determine if it can pretty-print the value. */ -PyObject * +gdbpy_ref<> gdbpy_get_varobj_pretty_printer (struct value *value) { TRY @@ -772,7 +749,7 @@ gdbpy_get_varobj_pretty_printer (struct value *value) } END_CATCH - gdbpy_ref val_obj (value_to_value_object (value)); + gdbpy_ref<> val_obj (value_to_value_object (value)); if (val_obj == NULL) return NULL; @@ -787,7 +764,6 @@ PyObject * gdbpy_default_visualizer (PyObject *self, PyObject *args) { PyObject *val_obj; - PyObject *cons; struct value *value; if (! PyArg_ParseTuple (args, "O", &val_obj)) @@ -800,6 +776,5 @@ gdbpy_default_visualizer (PyObject *self, PyObject *args) return NULL; } - cons = find_pretty_printer (val_obj); - return cons; + return find_pretty_printer (val_obj).release (); }