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.
This commit is contained in:
parent
f1b9e6e7ee
commit
621c83642d
14 changed files with 223 additions and 58 deletions
|
@ -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>
|
||||
|
||||
* mi/mi-main.c (mi_cmd_target_detach): Accept new
|
||||
|
|
15
gdb/c-lang.c
15
gdb/c-lang.c
|
@ -35,6 +35,7 @@
|
|||
#include "cp-support.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include <ctype.h>
|
||||
#include "exceptions.h"
|
||||
|
||||
extern void _initialize_c_language (void);
|
||||
|
||||
|
@ -698,13 +699,19 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
|||
}
|
||||
else
|
||||
{
|
||||
err = read_string (value_as_address (value), *length, width, fetchlimit,
|
||||
byte_order, buffer, length);
|
||||
CORE_ADDR addr = value_as_address (value);
|
||||
|
||||
err = read_string (addr, *length, width, fetchlimit,
|
||||
byte_order, buffer, length);
|
||||
if (err)
|
||||
{
|
||||
xfree (*buffer);
|
||||
error (_("Error reading string from inferior: %s"),
|
||||
safe_strerror (err));
|
||||
if (err == EIO)
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
* gdb.texinfo (Breakpoints In Python): Document "internal"
|
||||
|
|
|
@ -20729,8 +20729,9 @@ spaces if the parameter has a multi-part name. For example,
|
|||
@samp{print object} is a valid parameter name.
|
||||
|
||||
If the named parameter does not exist, this function throws a
|
||||
@code{RuntimeError}. Otherwise, the parameter's value is converted to
|
||||
a Python value of the appropriate type, and returned.
|
||||
@code{gdb.error} (@pxref{Exception Handling}). Otherwise, the
|
||||
parameter's value is converted to a Python value of the appropriate
|
||||
type, and returned.
|
||||
@end defun
|
||||
|
||||
@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
|
||||
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}
|
||||
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.
|
||||
|
||||
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
|
||||
@end smallexample
|
||||
|
||||
@value{GDBN} errors that happen in @value{GDBN} commands invoked by Python
|
||||
code are converted to Python @code{RuntimeError} exceptions. User
|
||||
interrupt (via @kbd{C-c} or by typing @kbd{q} at a pagination
|
||||
prompt) is translated to a Python @code{KeyboardInterrupt}
|
||||
exception. If you catch these exceptions in your Python code, your
|
||||
exception handler will see @code{RuntimeError} or
|
||||
@code{KeyboardInterrupt} as the exception type, 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
|
||||
@value{GDBN} errors that happen in @value{GDBN} commands invoked by
|
||||
Python code are converted to Python exceptions. The type of the
|
||||
Python exception depends on the error.
|
||||
|
||||
@ftable @code
|
||||
@item gdb.error
|
||||
This is the base class for most exceptions generated by @value{GDBN}.
|
||||
It is derived from @code{RuntimeError}, for compatibility with earlier
|
||||
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.
|
||||
|
||||
@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
|
||||
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
|
||||
@code{RuntimeError} exception.
|
||||
@code{gdb.error} exception (@pxref{Exception Handling}).
|
||||
@end defmethod
|
||||
|
||||
@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
|
||||
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
|
||||
to use an invalid frame object, @value{GDBN} will throw a @code{RuntimeError}
|
||||
exception.
|
||||
to use an invalid frame object, @value{GDBN} will throw a @code{gdb.error}
|
||||
exception (@pxref{Exception Handling}).
|
||||
|
||||
Two @code{gdb.Frame} objects can be compared for equality with the @code{==}
|
||||
operator, like:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
* gdb.python/py-breakpoint.exp: Add internal watchpoint and
|
||||
|
|
|
@ -213,7 +213,7 @@ main ()
|
|||
/* Clearing by being `static' could invoke an other GDB C++ bug. */
|
||||
struct nullstr nullstr;
|
||||
nostring_type nstype;
|
||||
struct ns ns;
|
||||
struct ns ns, ns2;
|
||||
struct lazystring estring, estring2;
|
||||
|
||||
nstype.elements = narray;
|
||||
|
@ -231,6 +231,10 @@ main ()
|
|||
ns.null_str = "embedded\0null\0string";
|
||||
ns.length = 20;
|
||||
|
||||
/* Make a "corrupted" string. */
|
||||
ns2.null_str = NULL;
|
||||
ns2.length = 20;
|
||||
|
||||
estring.lazy_str = "embedded x\201\202\203\204" ;
|
||||
|
||||
/* Incomplete UTF-8, but ok Latin-1. */
|
||||
|
|
|
@ -87,6 +87,8 @@ proc run_lang_tests {lang} {
|
|||
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 cstring" " = \"const string\""
|
||||
|
||||
|
|
|
@ -210,6 +210,9 @@ proc test_value_in_inferior {} {
|
|||
# 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.
|
||||
gdb_test "print st" "\"divide et impera\""
|
||||
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.
|
||||
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"
|
||||
|
||||
# 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
|
||||
# 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"
|
||||
|
||||
# Lastly, test subscript access to an array with multiple
|
||||
|
|
|
@ -160,7 +160,7 @@ runto [gdb_get_line_number "Break to end."]
|
|||
|
||||
# Test gdb.decode_line.
|
||||
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_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 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_test "python print len(symtab)" "2" "Test decode_line func1 length"
|
||||
gdb_test "python print len(symtab\[1\])" "1" "Test decode_line func1 length"
|
||||
|
|
16
gdb/varobj.c
16
gdb/varobj.c
|
@ -2477,7 +2477,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
|
|||
struct varobj *var)
|
||||
{
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
||||
struct cleanup *old_chain;
|
||||
gdb_byte *thevalue = NULL;
|
||||
struct value_print_options opts;
|
||||
struct type *type = NULL;
|
||||
|
@ -2491,6 +2491,9 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
|
|||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
gdbarch = get_type_arch (value_type (value));
|
||||
#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,
|
||||
we simply return {...}. */
|
||||
if (dynamic_varobj_has_child_method (var))
|
||||
return xstrdup ("{...}");
|
||||
{
|
||||
do_cleanups (old_chain);
|
||||
return xstrdup ("{...}");
|
||||
}
|
||||
|
||||
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,
|
||||
&replacement);
|
||||
&replacement,
|
||||
stb);
|
||||
if (output)
|
||||
{
|
||||
make_cleanup_py_decref (output);
|
||||
|
@ -2565,9 +2572,6 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
|
|||
}
|
||||
#endif
|
||||
|
||||
stb = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (stb);
|
||||
|
||||
get_formatted_print_options (&opts, format_code[(int) format]);
|
||||
opts.deref_ref = 0;
|
||||
opts.raw = 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue