diff options
author | Tom Tromey <tromey@redhat.com> | 2010-11-12 20:49:43 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2010-11-12 20:49:43 +0000 |
commit | 621c83642d17cf523c20f55f2ed945a7ec95ea6a (patch) | |
tree | 231cb6bb882e72fb68d6a5eb189060af43bb0dad /gdb/python | |
parent | f1b9e6e7ee6f55dd82194417e8f4d1713783ef39 (diff) | |
download | gdb-621c83642d17cf523c20f55f2ed945a7ec95ea6a.zip gdb-621c83642d17cf523c20f55f2ed945a7ec95ea6a.tar.gz gdb-621c83642d17cf523c20f55f2ed945a7ec95ea6a.tar.bz2 |
gdb
* varobj.c (value_get_print_value): Rearrange. Pass stream to
apply_varobj_pretty_printer.
* c-lang.c: Include exceptions.h.
(c_get_string): Throw MEMORY_ERROR when appropriate.
* python/py-prettyprint.c (enum string_repr_result): New.
(print_stack_unless_memory_error): New function.
(print_string_repr): Change return type. Use
print_stack_unless_memory_error.
(print_children): Use print_stack_unless_memory_error.
(apply_val_pretty_printer): Update. Don't print children if
string representation threw an exception.
(apply_varobj_pretty_printer): Add 'stream' argument. Use
print_stack_unless_memory_error.
* python/python.c (gdbpy_gdb_error, gdbpy_gdb_memory_error): New
globals.
(_initialize_python): Initialize them.
* python/python-internal.h (GDB_PY_HANDLE_EXCEPTION): Use
gdbpy_convert_exception.
(GDB_PY_SET_HANDLE_EXCEPTION): Likewise.
(gdbpy_gdb_error, gdbpy_gdb_memory_error): Declare.
(gdbpy_convert_exception): Declare.
(apply_varobj_pretty_printer): Update.
* python/py-utils.c (gdbpy_convert_exception): New function.
gdb/doc
* gdb.texinfo (Basic Python): Update. Add xref.
(Exception Handling): Document new exception classes.
(Types In Python): Update.
(Frames In Python): Update.
gdb/testsuite
* gdb.python/py-prettyprint.c (main): Add new 'ns2' local.
* gdb.python/py-prettyprint.exp (run_lang_tests): Add test for
MemoryError.
* gdb.python/python.exp (gdb_py_test_multiple): Update exception
type.
* gdb.python/py-value.exp (test_value_in_inferior): Add test for
MemoryError.
(test_subscript_regression): Update exception type.
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-prettyprint.c | 90 | ||||
-rw-r--r-- | gdb/python/py-utils.c | 19 | ||||
-rw-r--r-- | gdb/python/python-internal.h | 18 | ||||
-rw-r--r-- | gdb/python/python.c | 13 |
4 files changed, 112 insertions, 28 deletions
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index afe2b40..7be1409 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -29,6 +29,18 @@ #ifdef HAVE_PYTHON #include "python-internal.h" +/* Return type of print_string_repr. */ + +enum string_repr_result + { + /* The string method returned None. */ + string_repr_none, + /* The string method had an error. */ + string_repr_error, + /* Everything ok. */ + string_repr_ok + }; + /* Helper function for find_pretty_printer which iterates over a list, calls each function and inspects output. This will return a printer object if one recognizes VALUE. If no printer is found, it @@ -256,12 +268,40 @@ gdbpy_get_display_hint (PyObject *printer) return result; } +/* A wrapper for gdbpy_print_stack that ignores MemoryError. */ + +static void +print_stack_unless_memory_error (struct ui_file *stream) +{ + if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) + { + struct cleanup *cleanup; + PyObject *type, *value, *trace; + char *msg; + + PyErr_Fetch (&type, &value, &trace); + cleanup = make_cleanup_py_decref (type); + make_cleanup_py_decref (value); + make_cleanup_py_decref (trace); + + msg = gdbpy_exception_to_string (type, value); + make_cleanup (xfree, msg); + + if (msg == NULL || *msg == '\0') + fprintf_filtered (stream, _("<error reading variable")); + else + fprintf_filtered (stream, _("<error reading variable: %s>"), msg); + + do_cleanups (cleanup); + } + else + gdbpy_print_stack (); +} + /* Helper for apply_val_pretty_printer which calls to_string and - formats the result. If the value returnd is Py_None, nothing is - printed and the function returns a 1; in all other cases data is - printed as given by the pretty printer and the function returns 0. -*/ -static int + formats the result. */ + +static enum string_repr_result print_string_repr (PyObject *printer, const char *hint, struct ui_file *stream, int recurse, const struct value_print_options *options, @@ -270,7 +310,7 @@ print_string_repr (PyObject *printer, const char *hint, { struct value *replacement = NULL; PyObject *py_str = NULL; - int is_py_none = 0; + enum string_repr_result result = string_repr_ok; py_str = pretty_print_one_value (printer, &replacement); if (py_str) @@ -278,7 +318,7 @@ print_string_repr (PyObject *printer, const char *hint, struct cleanup *cleanup = make_cleanup_py_decref (py_str); if (py_str == Py_None) - is_py_none = 1; + result = string_repr_none; else if (gdbpy_is_lazy_string (py_str)) { CORE_ADDR addr; @@ -316,7 +356,10 @@ print_string_repr (PyObject *printer, const char *hint, fputs_filtered (output, stream); } else - gdbpy_print_stack (); + { + result = string_repr_error; + print_stack_unless_memory_error (stream); + } } do_cleanups (cleanup); @@ -329,9 +372,12 @@ print_string_repr (PyObject *printer, const char *hint, common_val_print (replacement, stream, recurse, &opts, language); } else - gdbpy_print_stack (); + { + result = string_repr_error; + print_stack_unless_memory_error (stream); + } - return is_py_none; + return result; } static void @@ -437,7 +483,7 @@ print_children (PyObject *printer, const char *hint, NULL); if (! children) { - gdbpy_print_stack (); + print_stack_unless_memory_error (stream); return; } @@ -446,7 +492,7 @@ print_children (PyObject *printer, const char *hint, iter = PyObject_GetIter (children); if (!iter) { - gdbpy_print_stack (); + print_stack_unless_memory_error (stream); goto done; } make_cleanup_py_decref (iter); @@ -476,7 +522,7 @@ print_children (PyObject *printer, const char *hint, if (! item) { if (PyErr_Occurred ()) - gdbpy_print_stack (); + print_stack_unless_memory_error (stream); /* Set a flag so we can know whether we printed all the available elements. */ else @@ -631,7 +677,7 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, char *hint = NULL; struct cleanup *cleanups; int result = 0; - int is_py_none = 0; + enum string_repr_result print_result; cleanups = ensure_python_env (gdbarch, language); /* Instantiate the printer. */ @@ -666,17 +712,18 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, make_cleanup (free_current_contents, &hint); /* Print the section */ - is_py_none = print_string_repr (printer, hint, stream, recurse, - options, language, gdbarch); - print_children (printer, hint, stream, recurse, options, language, - is_py_none); + print_result = print_string_repr (printer, hint, stream, recurse, + options, language, gdbarch); + if (print_result != string_repr_error) + print_children (printer, hint, stream, recurse, options, language, + print_result == string_repr_none); result = 1; done: if (PyErr_Occurred ()) - gdbpy_print_stack (); + print_stack_unless_memory_error (stream); do_cleanups (cleanups); return result; } @@ -693,7 +740,8 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, NULL. */ PyObject * apply_varobj_pretty_printer (PyObject *printer_obj, - struct value **replacement) + struct value **replacement, + struct ui_file *stream) { PyObject *py_str = NULL; @@ -701,7 +749,7 @@ apply_varobj_pretty_printer (PyObject *printer_obj, py_str = pretty_print_one_value (printer_obj, replacement); if (*replacement == NULL && py_str == NULL) - gdbpy_print_stack (); + print_stack_unless_memory_error (stream); return py_str; } diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c index 90609fa..2f0aac4 100644 --- a/gdb/python/py-utils.c +++ b/gdb/python/py-utils.c @@ -274,6 +274,25 @@ gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue) return str; } +/* Convert a GDB exception to the appropriate Python exception. + + This sets the Python error indicator, and returns NULL. */ + +PyObject * +gdbpy_convert_exception (struct gdb_exception exception) +{ + PyObject *exc_class; + + if (exception.reason == RETURN_QUIT) + exc_class = PyExc_KeyboardInterrupt; + else if (exception.error == MEMORY_ERROR) + exc_class = gdbpy_gdb_memory_error; + else + exc_class = gdbpy_gdb_error; + + return PyErr_Format (exc_class, "%s", exception.message); +} + /* Converts OBJ to a CORE_ADDR value. Returns 1 on success or 0 on failure, with a Python exception set. This diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 67de622..30d7533 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -80,6 +80,8 @@ typedef int Py_ssize_t; /* Also needed to parse enum var_types. */ #include "command.h" +#include "exceptions.h" + struct block; struct value; struct language_defn; @@ -179,9 +181,7 @@ extern const struct language_defn *python_language; #define GDB_PY_HANDLE_EXCEPTION(Exception) \ do { \ if (Exception.reason < 0) \ - return PyErr_Format (Exception.reason == RETURN_QUIT \ - ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ - "%s", Exception.message); \ + return gdbpy_convert_exception (Exception); \ } while (0) /* Use this after a TRY_EXCEPT to throw the appropriate Python @@ -190,9 +190,7 @@ extern const struct language_defn *python_language; do { \ if (Exception.reason < 0) \ { \ - PyErr_Format (Exception.reason == RETURN_QUIT \ - ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \ - "%s", Exception.message); \ + gdbpy_convert_exception (Exception); \ return -1; \ } \ } while (0) @@ -222,7 +220,8 @@ int gdbpy_is_value_object (PyObject *obj); /* Note that these are declared here, and not in python.h with the other pretty-printer functions, because they refer to PyObject. */ PyObject *apply_varobj_pretty_printer (PyObject *print_obj, - struct value **replacement); + struct value **replacement, + struct ui_file *stream); PyObject *gdbpy_get_varobj_pretty_printer (struct value *value); char *gdbpy_get_display_hint (PyObject *printer); PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args); @@ -233,8 +232,13 @@ extern PyObject *gdbpy_to_string_cst; extern PyObject *gdbpy_display_hint_cst; extern PyObject *gdbpy_enabled_cst; +/* Exception types. */ +extern PyObject *gdbpy_gdb_error; +extern PyObject *gdbpy_gdb_memory_error; extern PyObject *gdbpy_gdberror_exc; +extern PyObject *gdbpy_convert_exception (struct gdb_exception); + int get_addr_from_python (PyObject *obj, CORE_ADDR *addr); #endif /* GDB_PYTHON_INTERNAL_H */ diff --git a/gdb/python/python.c b/gdb/python/python.c index d4f8c3d..d009be9 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -66,6 +66,12 @@ PyObject *gdbpy_enabled_cst; /* The GdbError exception. */ PyObject *gdbpy_gdberror_exc; +/* The `gdb.error' base class. */ +PyObject *gdbpy_gdb_error; + +/* The `gdb.MemoryError' exception. */ +PyObject *gdbpy_gdb_memory_error; + /* Architecture and language to be used in callbacks from the Python interpreter. */ struct gdbarch *python_gdbarch; @@ -967,6 +973,13 @@ Enables or disables printing of Python stack traces."), xfree (gdb_pythondir); } + gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL); + PyModule_AddObject (gdb_module, "error", gdbpy_gdb_error); + + gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError", + gdbpy_gdb_error, NULL); + PyModule_AddObject (gdb_module, "MemoryError", gdbpy_gdb_memory_error); + gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL); PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc); |