* 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.
This commit is contained in:
Tom Tromey 2010-11-12 20:49:43 +00:00
parent f1b9e6e7ee
commit 621c83642d
14 changed files with 223 additions and 58 deletions

View File

@ -1,3 +1,29 @@
2010-11-12 Tom Tromey <tromey@redhat.com>
* 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.
2010-11-12 Marc Khouzam <marc.khouzam@ericsson.com> 2010-11-12 Marc Khouzam <marc.khouzam@ericsson.com>
* mi/mi-main.c (mi_cmd_target_detach): Accept new * mi/mi-main.c (mi_cmd_target_detach): Accept new

View File

@ -35,6 +35,7 @@
#include "cp-support.h" #include "cp-support.h"
#include "gdb_obstack.h" #include "gdb_obstack.h"
#include <ctype.h> #include <ctype.h>
#include "exceptions.h"
extern void _initialize_c_language (void); extern void _initialize_c_language (void);
@ -698,13 +699,19 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
} }
else else
{ {
err = read_string (value_as_address (value), *length, width, fetchlimit, CORE_ADDR addr = value_as_address (value);
byte_order, buffer, length);
err = read_string (addr, *length, width, fetchlimit,
byte_order, buffer, length);
if (err) if (err)
{ {
xfree (*buffer); xfree (*buffer);
error (_("Error reading string from inferior: %s"), if (err == EIO)
safe_strerror (err)); throw_error (MEMORY_ERROR, "Address %s out of bounds",
paddress (get_type_arch (type), addr));
else
error (_("Error reading string from inferior: %s"),
safe_strerror (err));
} }
} }

View File

@ -1,3 +1,10 @@
2010-11-12 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Basic Python): Update. Add xref.
(Exception Handling): Document new exception classes.
(Types In Python): Update.
(Frames In Python): Update.
2010-11-11 Phil Muldoon <pmuldoon@redhat.com> 2010-11-11 Phil Muldoon <pmuldoon@redhat.com>
* gdb.texinfo (Breakpoints In Python): Document "internal" * gdb.texinfo (Breakpoints In Python): Document "internal"

View File

@ -20729,8 +20729,9 @@ spaces if the parameter has a multi-part name. For example,
@samp{print object} is a valid parameter name. @samp{print object} is a valid parameter name.
If the named parameter does not exist, this function throws a If the named parameter does not exist, this function throws a
@code{RuntimeError}. Otherwise, the parameter's value is converted to @code{gdb.error} (@pxref{Exception Handling}). Otherwise, the
a Python value of the appropriate type, and returned. parameter's value is converted to a Python value of the appropriate
type, and returned.
@end defun @end defun
@findex gdb.history @findex gdb.history
@ -20741,7 +20742,7 @@ If @var{number} is negative, then @value{GDBN} will take its absolute value
and count backward from the last element (i.e., the most recent element) to and count backward from the last element (i.e., the most recent element) to
find the value to return. If @var{number} is zero, then @value{GDBN} will find the value to return. If @var{number} is zero, then @value{GDBN} will
return the most recent element. If the element specified by @var{number} return the most recent element. If the element specified by @var{number}
doesn't exist in the value history, a @code{RuntimeError} exception will be doesn't exist in the value history, a @code{gdb.error} exception will be
raised. raised.
If no exception is raised, the return value is always an instance of If no exception is raised, the return value is always an instance of
@ -20869,15 +20870,31 @@ Traceback (most recent call last):
NameError: name 'foo' is not defined NameError: name 'foo' is not defined
@end smallexample @end smallexample
@value{GDBN} errors that happen in @value{GDBN} commands invoked by Python @value{GDBN} errors that happen in @value{GDBN} commands invoked by
code are converted to Python @code{RuntimeError} exceptions. User Python code are converted to Python exceptions. The type of the
interrupt (via @kbd{C-c} or by typing @kbd{q} at a pagination Python exception depends on the error.
prompt) is translated to a Python @code{KeyboardInterrupt}
exception. If you catch these exceptions in your Python code, your @ftable @code
exception handler will see @code{RuntimeError} or @item gdb.error
@code{KeyboardInterrupt} as the exception type, the @value{GDBN} error This is the base class for most exceptions generated by @value{GDBN}.
message as its value, and the Python call stack backtrace at the It is derived from @code{RuntimeError}, for compatibility with earlier
Python statement closest to where the @value{GDBN} error occured as the versions of @value{GDBN}.
If an error occurring in @value{GDBN} does not fit into some more
specific category, then the generated exception will have this type.
@item gdb.MemoryError
This is a subclass of @code{gdb.error} which is thrown when an
operation tried to access invalid memory in the inferior.
@item KeyboardInterrupt
User interrupt (via @kbd{C-c} or by typing @kbd{q} at a pagination
prompt) is translated to a Python @code{KeyboardInterrupt} exception.
@end ftable
In all cases, your exception handler will see the @value{GDBN} error
message as its value and the Python call stack backtrace at the Python
statement closest to where the @value{GDBN} error occured as the
traceback. traceback.
@findex gdb.GdbError @findex gdb.GdbError
@ -21242,7 +21259,7 @@ variant of this type. That is, the result is neither @code{const} nor
Return a Python @code{Tuple} object that contains two elements: the Return a Python @code{Tuple} object that contains two elements: the
low bound of the argument type and the high bound of that type. If low bound of the argument type and the high bound of that type. If
the type does not have a range, @value{GDBN} will raise a the type does not have a range, @value{GDBN} will raise a
@code{RuntimeError} exception. @code{gdb.error} exception (@pxref{Exception Handling}).
@end defmethod @end defmethod
@defmethod Type reference @defmethod Type reference
@ -22433,8 +22450,8 @@ When the debugged program stops, @value{GDBN} is able to analyze its call
stack (@pxref{Frames,,Stack frames}). The @code{gdb.Frame} class stack (@pxref{Frames,,Stack frames}). The @code{gdb.Frame} class
represents a frame in the stack. A @code{gdb.Frame} object is only valid represents a frame in the stack. A @code{gdb.Frame} object is only valid
while its corresponding frame exists in the inferior's stack. If you try while its corresponding frame exists in the inferior's stack. If you try
to use an invalid frame object, @value{GDBN} will throw a @code{RuntimeError} to use an invalid frame object, @value{GDBN} will throw a @code{gdb.error}
exception. exception (@pxref{Exception Handling}).
Two @code{gdb.Frame} objects can be compared for equality with the @code{==} Two @code{gdb.Frame} objects can be compared for equality with the @code{==}
operator, like: operator, like:

View File

@ -29,6 +29,18 @@
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
#include "python-internal.h" #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, /* Helper function for find_pretty_printer which iterates over a list,
calls each function and inspects output. This will return a calls each function and inspects output. This will return a
printer object if one recognizes VALUE. If no printer is found, it printer object if one recognizes VALUE. If no printer is found, it
@ -256,12 +268,40 @@ gdbpy_get_display_hint (PyObject *printer)
return result; 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 /* Helper for apply_val_pretty_printer which calls to_string and
formats the result. If the value returnd is Py_None, nothing is formats the result. */
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 enum string_repr_result
*/
static int
print_string_repr (PyObject *printer, const char *hint, print_string_repr (PyObject *printer, const char *hint,
struct ui_file *stream, int recurse, struct ui_file *stream, int recurse,
const struct value_print_options *options, const struct value_print_options *options,
@ -270,7 +310,7 @@ print_string_repr (PyObject *printer, const char *hint,
{ {
struct value *replacement = NULL; struct value *replacement = NULL;
PyObject *py_str = 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); py_str = pretty_print_one_value (printer, &replacement);
if (py_str) if (py_str)
@ -278,7 +318,7 @@ print_string_repr (PyObject *printer, const char *hint,
struct cleanup *cleanup = make_cleanup_py_decref (py_str); struct cleanup *cleanup = make_cleanup_py_decref (py_str);
if (py_str == Py_None) if (py_str == Py_None)
is_py_none = 1; result = string_repr_none;
else if (gdbpy_is_lazy_string (py_str)) else if (gdbpy_is_lazy_string (py_str))
{ {
CORE_ADDR addr; CORE_ADDR addr;
@ -316,7 +356,10 @@ print_string_repr (PyObject *printer, const char *hint,
fputs_filtered (output, stream); fputs_filtered (output, stream);
} }
else else
gdbpy_print_stack (); {
result = string_repr_error;
print_stack_unless_memory_error (stream);
}
} }
do_cleanups (cleanup); do_cleanups (cleanup);
@ -329,9 +372,12 @@ print_string_repr (PyObject *printer, const char *hint,
common_val_print (replacement, stream, recurse, &opts, language); common_val_print (replacement, stream, recurse, &opts, language);
} }
else else
gdbpy_print_stack (); {
result = string_repr_error;
print_stack_unless_memory_error (stream);
}
return is_py_none; return result;
} }
static void static void
@ -437,7 +483,7 @@ print_children (PyObject *printer, const char *hint,
NULL); NULL);
if (! children) if (! children)
{ {
gdbpy_print_stack (); print_stack_unless_memory_error (stream);
return; return;
} }
@ -446,7 +492,7 @@ print_children (PyObject *printer, const char *hint,
iter = PyObject_GetIter (children); iter = PyObject_GetIter (children);
if (!iter) if (!iter)
{ {
gdbpy_print_stack (); print_stack_unless_memory_error (stream);
goto done; goto done;
} }
make_cleanup_py_decref (iter); make_cleanup_py_decref (iter);
@ -476,7 +522,7 @@ print_children (PyObject *printer, const char *hint,
if (! item) if (! item)
{ {
if (PyErr_Occurred ()) if (PyErr_Occurred ())
gdbpy_print_stack (); print_stack_unless_memory_error (stream);
/* Set a flag so we can know whether we printed all the /* Set a flag so we can know whether we printed all the
available elements. */ available elements. */
else else
@ -631,7 +677,7 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
char *hint = NULL; char *hint = NULL;
struct cleanup *cleanups; struct cleanup *cleanups;
int result = 0; int result = 0;
int is_py_none = 0; enum string_repr_result print_result;
cleanups = ensure_python_env (gdbarch, language); cleanups = ensure_python_env (gdbarch, language);
/* Instantiate the printer. */ /* Instantiate the printer. */
@ -666,17 +712,18 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
make_cleanup (free_current_contents, &hint); make_cleanup (free_current_contents, &hint);
/* Print the section */ /* Print the section */
is_py_none = print_string_repr (printer, hint, stream, recurse, print_result = print_string_repr (printer, hint, stream, recurse,
options, language, gdbarch); options, language, gdbarch);
print_children (printer, hint, stream, recurse, options, language, if (print_result != string_repr_error)
is_py_none); print_children (printer, hint, stream, recurse, options, language,
print_result == string_repr_none);
result = 1; result = 1;
done: done:
if (PyErr_Occurred ()) if (PyErr_Occurred ())
gdbpy_print_stack (); print_stack_unless_memory_error (stream);
do_cleanups (cleanups); do_cleanups (cleanups);
return result; return result;
} }
@ -693,7 +740,8 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
NULL. */ NULL. */
PyObject * PyObject *
apply_varobj_pretty_printer (PyObject *printer_obj, apply_varobj_pretty_printer (PyObject *printer_obj,
struct value **replacement) struct value **replacement,
struct ui_file *stream)
{ {
PyObject *py_str = NULL; PyObject *py_str = NULL;
@ -701,7 +749,7 @@ apply_varobj_pretty_printer (PyObject *printer_obj,
py_str = pretty_print_one_value (printer_obj, replacement); py_str = pretty_print_one_value (printer_obj, replacement);
if (*replacement == NULL && py_str == NULL) if (*replacement == NULL && py_str == NULL)
gdbpy_print_stack (); print_stack_unless_memory_error (stream);
return py_str; return py_str;
} }

View File

@ -274,6 +274,25 @@ gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue)
return str; 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. /* Converts OBJ to a CORE_ADDR value.
Returns 1 on success or 0 on failure, with a Python exception set. This Returns 1 on success or 0 on failure, with a Python exception set. This

View File

@ -80,6 +80,8 @@ typedef int Py_ssize_t;
/* Also needed to parse enum var_types. */ /* Also needed to parse enum var_types. */
#include "command.h" #include "command.h"
#include "exceptions.h"
struct block; struct block;
struct value; struct value;
struct language_defn; struct language_defn;
@ -179,9 +181,7 @@ extern const struct language_defn *python_language;
#define GDB_PY_HANDLE_EXCEPTION(Exception) \ #define GDB_PY_HANDLE_EXCEPTION(Exception) \
do { \ do { \
if (Exception.reason < 0) \ if (Exception.reason < 0) \
return PyErr_Format (Exception.reason == RETURN_QUIT \ return gdbpy_convert_exception (Exception); \
? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
"%s", Exception.message); \
} while (0) } while (0)
/* Use this after a TRY_EXCEPT to throw the appropriate Python /* Use this after a TRY_EXCEPT to throw the appropriate Python
@ -190,9 +190,7 @@ extern const struct language_defn *python_language;
do { \ do { \
if (Exception.reason < 0) \ if (Exception.reason < 0) \
{ \ { \
PyErr_Format (Exception.reason == RETURN_QUIT \ gdbpy_convert_exception (Exception); \
? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
"%s", Exception.message); \
return -1; \ return -1; \
} \ } \
} while (0) } 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 /* Note that these are declared here, and not in python.h with the
other pretty-printer functions, because they refer to PyObject. */ other pretty-printer functions, because they refer to PyObject. */
PyObject *apply_varobj_pretty_printer (PyObject *print_obj, 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); PyObject *gdbpy_get_varobj_pretty_printer (struct value *value);
char *gdbpy_get_display_hint (PyObject *printer); char *gdbpy_get_display_hint (PyObject *printer);
PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args); 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_display_hint_cst;
extern PyObject *gdbpy_enabled_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_gdberror_exc;
extern PyObject *gdbpy_convert_exception (struct gdb_exception);
int get_addr_from_python (PyObject *obj, CORE_ADDR *addr); int get_addr_from_python (PyObject *obj, CORE_ADDR *addr);
#endif /* GDB_PYTHON_INTERNAL_H */ #endif /* GDB_PYTHON_INTERNAL_H */

View File

@ -66,6 +66,12 @@ PyObject *gdbpy_enabled_cst;
/* The GdbError exception. */ /* The GdbError exception. */
PyObject *gdbpy_gdberror_exc; 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 /* Architecture and language to be used in callbacks from
the Python interpreter. */ the Python interpreter. */
struct gdbarch *python_gdbarch; struct gdbarch *python_gdbarch;
@ -967,6 +973,13 @@ Enables or disables printing of Python stack traces."),
xfree (gdb_pythondir); 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); gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL);
PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc); PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc);

View File

@ -1,3 +1,14 @@
2010-11-12 Tom Tromey <tromey@redhat.com>
* 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.
2010-11-11 Phil Muldoon <pmuldoon@redhat.com> 2010-11-11 Phil Muldoon <pmuldoon@redhat.com>
* gdb.python/py-breakpoint.exp: Add internal watchpoint and * gdb.python/py-breakpoint.exp: Add internal watchpoint and

View File

@ -213,7 +213,7 @@ main ()
/* Clearing by being `static' could invoke an other GDB C++ bug. */ /* Clearing by being `static' could invoke an other GDB C++ bug. */
struct nullstr nullstr; struct nullstr nullstr;
nostring_type nstype; nostring_type nstype;
struct ns ns; struct ns ns, ns2;
struct lazystring estring, estring2; struct lazystring estring, estring2;
nstype.elements = narray; nstype.elements = narray;
@ -231,6 +231,10 @@ main ()
ns.null_str = "embedded\0null\0string"; ns.null_str = "embedded\0null\0string";
ns.length = 20; ns.length = 20;
/* Make a "corrupted" string. */
ns2.null_str = NULL;
ns2.length = 20;
estring.lazy_str = "embedded x\201\202\203\204" ; estring.lazy_str = "embedded x\201\202\203\204" ;
/* Incomplete UTF-8, but ok Latin-1. */ /* Incomplete UTF-8, but ok Latin-1. */

View File

@ -87,6 +87,8 @@ proc run_lang_tests {lang} {
gdb_py_test_silent_cmd "set print elements 200" "" 1 gdb_py_test_silent_cmd "set print elements 200" "" 1
} }
gdb_test "print ns2" ".error reading variable: Address 0x0 out of bounds."
gdb_test "print x" " = \"this is x\"" gdb_test "print x" " = \"this is x\""
gdb_test "print cstring" " = \"const string\"" gdb_test "print cstring" " = \"const string\""

View File

@ -210,6 +210,9 @@ proc test_value_in_inferior {} {
# Test address attribute # Test address attribute
gdb_test "python print 'result =', arg0.address" "= 0x\[\[:xdigit:\]\]+" "Test address attribute" gdb_test "python print 'result =', arg0.address" "= 0x\[\[:xdigit:\]\]+" "Test address attribute"
# Test memory error.
gdb_test "python print gdb.parse_and_eval('*(int*)0')" "gdb.MemoryError: Cannot access memory at address 0x0.*"
# Test string fetches, both partial and whole. # Test string fetches, both partial and whole.
gdb_test "print st" "\"divide et impera\"" gdb_test "print st" "\"divide et impera\""
gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value from history" 1 gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value from history" 1
@ -371,7 +374,7 @@ proc test_subscript_regression {lang} {
# Try to access an int with a subscript. This should fail. # Try to access an int with a subscript. This should fail.
gdb_test "python print intv" "1" "Baseline print of a Python value" gdb_test "python print intv" "1" "Baseline print of a Python value"
gdb_test "python print intv\[0\]" "RuntimeError: Cannot subscript requested type.*" \ gdb_test "python print intv\[0\]" "gdb.error: Cannot subscript requested type.*" \
"Attempt to access an integer with a subscript" "Attempt to access an integer with a subscript"
# Try to access a string with a subscript. This should pass. # Try to access a string with a subscript. This should pass.
@ -386,7 +389,7 @@ proc test_subscript_regression {lang} {
# Try to access a single dimension array with a subscript to the # Try to access a single dimension array with a subscript to the
# result. This should fail. # result. This should fail.
gdb_test "python print pointer\[intv\]\[0\]" "RuntimeError: Cannot subscript requested type.*" \ gdb_test "python print pointer\[intv\]\[0\]" "gdb.error: Cannot subscript requested type.*" \
"Attempt to access an integer with a subscript" "Attempt to access an integer with a subscript"
# Lastly, test subscript access to an array with multiple # Lastly, test subscript access to an array with multiple

View File

@ -160,7 +160,7 @@ runto [gdb_get_line_number "Break to end."]
# Test gdb.decode_line. # Test gdb.decode_line.
gdb_test "python gdb.decode_line(\"main.c:43\")" \ gdb_test "python gdb.decode_line(\"main.c:43\")" \
"RuntimeError: No source file named main.c.*" "test decode_line no source named main" "gdb.error: No source file named main.c.*" "test decode_line no source named main"
gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location" 1 gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location" 1
gdb_test "python print len(symtab)" "2" "Test decode_line current location" gdb_test "python print len(symtab)" "2" "Test decode_line current location"
@ -177,7 +177,7 @@ gdb_test "python print symtab\[1\]\[0\].symtab" "gdb/testsuite/gdb.python/python
gdb_test "python print symtab\[1\]\[0\].line" "26" "Test decode_line python.c:26 line number" gdb_test "python print symtab\[1\]\[0\].line" "26" "Test decode_line python.c:26 line number"
gdb_test "python gdb.decode_line(\"randomfunc\")" \ gdb_test "python gdb.decode_line(\"randomfunc\")" \
"RuntimeError: Function \"randomfunc\" not defined.*" "test decode_line randomfunc" "gdb.error: Function \"randomfunc\" not defined.*" "test decode_line randomfunc"
gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"func1\")" "test decode_line func1()" 1 gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"func1\")" "test decode_line func1()" 1
gdb_test "python print len(symtab)" "2" "Test decode_line func1 length" gdb_test "python print len(symtab)" "2" "Test decode_line func1 length"
gdb_test "python print len(symtab\[1\])" "1" "Test decode_line func1 length" gdb_test "python print len(symtab\[1\])" "1" "Test decode_line func1 length"

View File

@ -2477,7 +2477,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
struct varobj *var) struct varobj *var)
{ {
struct ui_file *stb; struct ui_file *stb;
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); struct cleanup *old_chain;
gdb_byte *thevalue = NULL; gdb_byte *thevalue = NULL;
struct value_print_options opts; struct value_print_options opts;
struct type *type = NULL; struct type *type = NULL;
@ -2491,6 +2491,9 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
if (value == NULL) if (value == NULL)
return NULL; return NULL;
stb = mem_fileopen ();
old_chain = make_cleanup_ui_file_delete (stb);
gdbarch = get_type_arch (value_type (value)); gdbarch = get_type_arch (value_type (value));
#if HAVE_PYTHON #if HAVE_PYTHON
{ {
@ -2503,7 +2506,10 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
/* First check to see if we have any children at all. If so, /* First check to see if we have any children at all. If so,
we simply return {...}. */ we simply return {...}. */
if (dynamic_varobj_has_child_method (var)) if (dynamic_varobj_has_child_method (var))
return xstrdup ("{...}"); {
do_cleanups (old_chain);
return xstrdup ("{...}");
}
if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst)) if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{ {
@ -2520,7 +2526,8 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
} }
output = apply_varobj_pretty_printer (value_formatter, output = apply_varobj_pretty_printer (value_formatter,
&replacement); &replacement,
stb);
if (output) if (output)
{ {
make_cleanup_py_decref (output); make_cleanup_py_decref (output);
@ -2565,9 +2572,6 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
} }
#endif #endif
stb = mem_fileopen ();
make_cleanup_ui_file_delete (stb);
get_formatted_print_options (&opts, format_code[(int) format]); get_formatted_print_options (&opts, format_code[(int) format]);
opts.deref_ref = 0; opts.deref_ref = 0;
opts.raw = 1; opts.raw = 1;