* python/py-breakpoint.c (bppy_set_condition): New comment.
	* python/py-cmd.c (cmdpy_function): Call also gdbpy_print_stack for
	failed PyUnicode_Decode.
	(cmdpy_completer): Skip element for failed
	python_string_to_host_string.
	(cmdpy_init): Return -1 on failed python_string_to_host_string.
	* python/py-frame.c (frapy_read_var): Extend the function comment.
	* python/py-function.c (fnpy_init): Return -1 on failed
	python_string_to_host_string.
	* python/py-inferior.c (infpy_read_memory, infpy_write_memory): Extend
	the function comment.
	(infpy_search_memory): Extend the function comment.  Remove the
	PyErr_SetString call on already set error state.
	* python/py-param.c (set_parameter_value): Extend the function
	comment.  Return -1 on failed python_string_to_host_string, twice.
	(set_attr): Extend the function comment.
	(compute_enum_values): Extend the function comment.  New variable
	back_to.  Protect self->enumeration by BACK_TO cleanups.  Return 0 on
	failed python_string_to_host_string.
	(get_doc_string): Call gdbpy_print_stack on failed
	python_string_to_host_string.
	(parmpy_init): Extend the function comment.
	* python/py-prettyprint.c (pretty_print_one_value): Likewise.
	(gdbpy_get_display_hint, print_children): Call gdbpy_print_stack on
	failed python_string_to_host_string.
	* python/py-value.c (valpy_new, valpy_getitem, valpy_call)
	(valpy_binop, valpy_richcompare): Extend the function comment.
	* python/python.c
	(struct python_env) <error_type, error_value, error_traceback>: New
	fields.
	(restore_python_env): Handle PyErr_Occurred.  Call PyErr_Restore.
	(ensure_python_env): Call PyErr_Fetch.
	* varobj.c (update_dynamic_varobj_children): Call gdbpy_print_stack on
	failed convert_value_from_python.
	(value_get_print_value): Call gdbpy_print_stack on failed
	python_string_to_target_python_string.

gdb/testsuite/
	* gdb.python/py-error.exp: New file.
	* gdb.python/py-error.py: New file.
This commit is contained in:
Jan Kratochvil 2010-10-13 13:24:40 +00:00
parent a071456ba8
commit 8dc785338e
14 changed files with 241 additions and 34 deletions

View file

@ -1,3 +1,42 @@
2010-10-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* python/py-breakpoint.c (bppy_set_condition): New comment.
* python/py-cmd.c (cmdpy_function): Call also gdbpy_print_stack for
failed PyUnicode_Decode.
(cmdpy_completer): Skip element for failed
python_string_to_host_string.
(cmdpy_init): Return -1 on failed python_string_to_host_string.
* python/py-frame.c (frapy_read_var): Extend the function comment.
* python/py-function.c (fnpy_init): Return -1 on failed
python_string_to_host_string.
* python/py-inferior.c (infpy_read_memory, infpy_write_memory): Extend
the function comment.
(infpy_search_memory): Extend the function comment. Remove the
PyErr_SetString call on already set error state.
* python/py-param.c (set_parameter_value): Extend the function
comment. Return -1 on failed python_string_to_host_string, twice.
(set_attr): Extend the function comment.
(compute_enum_values): Extend the function comment. New variable
back_to. Protect self->enumeration by BACK_TO cleanups. Return 0 on
failed python_string_to_host_string.
(get_doc_string): Call gdbpy_print_stack on failed
python_string_to_host_string.
(parmpy_init): Extend the function comment.
* python/py-prettyprint.c (pretty_print_one_value): Likewise.
(gdbpy_get_display_hint, print_children): Call gdbpy_print_stack on
failed python_string_to_host_string.
* python/py-value.c (valpy_new, valpy_getitem, valpy_call)
(valpy_binop, valpy_richcompare): Extend the function comment.
* python/python.c
(struct python_env) <error_type, error_value, error_traceback>: New
fields.
(restore_python_env): Handle PyErr_Occurred. Call PyErr_Restore.
(ensure_python_env): Call PyErr_Fetch.
* varobj.c (update_dynamic_varobj_children): Call gdbpy_print_stack on
failed convert_value_from_python.
(value_get_print_value): Call gdbpy_print_stack on failed
python_string_to_target_python_string.
2010-10-12 Tom Tromey <tromey@redhat.com>
* python/py-prettyprint.c (search_pp_list): Fix error checking.

View file

@ -420,6 +420,9 @@ bppy_get_condition (PyObject *self, void *closure)
return PyString_Decode (str, strlen (str), host_charset (), NULL);
}
/* Returns 0 on success. Returns -1 on error, with a python exception set.
*/
static int
bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
{

View file

@ -139,7 +139,10 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
args = "";
argobj = PyUnicode_Decode (args, strlen (args), host_charset (), NULL);
if (! argobj)
error (_("Could not convert arguments to Python string."));
{
gdbpy_print_stack ();
error (_("Could not convert arguments to Python string."));
}
ttyobj = from_tty ? Py_True : Py_False;
Py_INCREF (ttyobj);
@ -256,6 +259,12 @@ cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
continue;
}
result[out] = python_string_to_host_string (elt);
if (result[out] == NULL)
{
/* Skip problem elements. */
PyErr_Clear ();
continue;
}
++out;
}
result[out] = NULL;
@ -466,7 +475,15 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
PyObject *ds_obj = PyObject_GetAttr (self, gdbpy_doc_cst);
if (ds_obj && gdbpy_is_string (ds_obj))
docstring = python_string_to_host_string (ds_obj);
{
docstring = python_string_to_host_string (ds_obj);
if (docstring == NULL)
{
xfree (cmd_name);
xfree (pfx_name);
return -1;
}
}
}
if (! docstring)
docstring = xstrdup (_("This command is not documented."));

View file

@ -385,7 +385,8 @@ frapy_find_sal (PyObject *self, PyObject *args)
start the search from that block, otherwise search from the frame's
current block (determined by examining the resume address of the
frame). The variable argument must be a string or an instance of a
gdb.Symbol. The block argument must be an instance of gdb.Block. */
gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
NULL on error, with a python exception set. */
static PyObject *
frapy_read_var (PyObject *self, PyObject *args)
{

View file

@ -113,7 +113,14 @@ fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__");
if (ds_obj && gdbpy_is_string (ds_obj))
docstring = python_string_to_host_string (ds_obj);
{
docstring = python_string_to_host_string (ds_obj);
if (docstring == NULL)
{
Py_DECREF (self);
return -1;
}
}
}
if (! docstring)
docstring = xstrdup (_("This function is not documented."));

View file

@ -293,7 +293,8 @@ gdbpy_inferiors (PyObject *unused, PyObject *unused2)
/* Implementation of gdb.read_memory (address, length).
Returns a Python buffer object with LENGTH bytes of the inferior's
memory at ADDRESS. Both arguments are integers. */
memory at ADDRESS. Both arguments are integers. Returns NULL on error,
with a python exception set. */
static PyObject *
infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
{
@ -361,7 +362,8 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
Writes the contents of BUFFER (a Python object supporting the read
buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
bytes from BUFFER, or its entire contents if the argument is not
provided. The function returns nothing. */
provided. The function returns nothing. Returns NULL on error, with
a python exception set. */
static PyObject *
infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
{
@ -473,7 +475,8 @@ get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
search from ADDRESS. PATTERN is the pattern to search for (and
must be a Python object supporting the buffer protocol).
Returns a Python Long object holding the address where the pattern
was located, or if the pattern was not found, returns None. */
was located, or if the pattern was not found, returns None. Returns NULL
on error, with a python exception set. */
static PyObject *
infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
{
@ -511,12 +514,7 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
}
}
else
{
PyErr_SetString (PyExc_RuntimeError,
_("Cannot get search address/range from Python."));
return NULL;
}
return NULL;
if (!PyObject_CheckReadBuffer (pattern))
{

View file

@ -110,8 +110,8 @@ get_attr (PyObject *obj, PyObject *attr_name)
return PyObject_GenericGetAttr (obj, attr_name);
}
/* Set a parameter value from a Python value. Return 0 on success, -1
on failure. */
/* Set a parameter value from a Python value. Return 0 on success. Returns
-1 on error, with a python exception set. */
static int
set_parameter_value (parmpy_object *self, PyObject *value)
{
@ -132,17 +132,25 @@ set_parameter_value (parmpy_object *self, PyObject *value)
return -1;
}
if (self->value.stringval)
xfree (self->value.stringval);
if (value == Py_None)
{
xfree (self->value.stringval);
if (self->type == var_optional_filename)
self->value.stringval = xstrdup ("");
else
self->value.stringval = NULL;
}
else
self->value.stringval = python_string_to_host_string (value);
{
char *string;
string = python_string_to_host_string (value);
if (string == NULL)
return -1;
xfree (self->value.stringval);
self->value.stringval = string;
}
break;
case var_enum:
@ -158,6 +166,8 @@ set_parameter_value (parmpy_object *self, PyObject *value)
}
str = python_string_to_host_string (value);
if (str == NULL)
return -1;
for (i = 0; self->enumeration[i]; ++i)
if (! strcmp (self->enumeration[i], str))
break;
@ -258,7 +268,7 @@ set_parameter_value (parmpy_object *self, PyObject *value)
return 0;
}
/* Set an attribute. */
/* Set an attribute. Returns -1 on error, with a python exception set. */
static int
set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
{
@ -358,12 +368,13 @@ add_setshow_generic (int parmclass, enum command_class cmdclass,
}
}
/* A helper which computes enum values. Returns 1 on success, 0 on
error. */
/* A helper which computes enum values. Returns 1 on success. Returns 0 on
error, with a python exception set. */
static int
compute_enum_values (parmpy_object *self, PyObject *enum_values)
{
Py_ssize_t size, i;
struct cleanup *back_to;
if (! enum_values)
{
@ -390,6 +401,7 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
}
self->enumeration = xmalloc ((size + 1) * sizeof (char *));
back_to = make_cleanup (free_current_contents, &self->enumeration);
memset (self->enumeration, 0, (size + 1) * sizeof (char *));
for (i = 0; i < size; ++i)
@ -397,16 +409,27 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
PyObject *item = PySequence_GetItem (enum_values, i);
if (! item)
return 0;
{
do_cleanups (back_to);
return 0;
}
if (! gdbpy_is_string (item))
{
do_cleanups (back_to);
PyErr_SetString (PyExc_RuntimeError,
_("The enumeration item not a string."));
return 0;
}
self->enumeration[i] = python_string_to_host_string (item);
if (self->enumeration[i] == NULL)
{
do_cleanups (back_to);
return 0;
}
make_cleanup (xfree, (char *) self->enumeration[i]);
}
discard_cleanups (back_to);
return 1;
}
@ -422,7 +445,11 @@ get_doc_string (PyObject *object, PyObject *attr)
PyObject *ds_obj = PyObject_GetAttr (object, attr);
if (ds_obj && gdbpy_is_string (ds_obj))
result = python_string_to_host_string (ds_obj);
{
result = python_string_to_host_string (ds_obj);
if (result == NULL)
gdbpy_print_stack ();
}
}
if (! result)
result = xstrdup (_("This command is not documented."));
@ -449,8 +476,9 @@ get_doc_string (PyObject *object, PyObject *attr)
The documentation for the parameter is taken from the doc string
for the python class.
*/
Returns -1 on error, with a python exception set. */
static int
parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{

View file

@ -196,8 +196,8 @@ find_pretty_printer (PyObject *value)
is returned. If the function returns Py_NONE that means the pretty
printer returned the Python None as a value. Otherwise, if the
function returns a value, *OUT_VALUE is set to the value, and NULL
is returned. On error, *OUT_VALUE is set to NULL, and NULL is
returned. */
is returned. On error, *OUT_VALUE is set to NULL, NULL is
returned, with a python exception set. */
static PyObject *
pretty_print_one_value (PyObject *printer, struct value **out_value)
@ -243,7 +243,11 @@ gdbpy_get_display_hint (PyObject *printer)
if (hint)
{
if (gdbpy_is_string (hint))
result = python_string_to_host_string (hint);
{
result = python_string_to_host_string (hint);
if (result == NULL)
gdbpy_print_stack ();
}
Py_DECREF (hint);
}
else
@ -566,7 +570,10 @@ print_children (PyObject *printer, const char *hint,
else
{
output = python_string_to_host_string (py_v);
fputs_filtered (output, stream);
if (!output)
gdbpy_print_stack ();
else
fputs_filtered (output, stream);
xfree (output);
}
}

View file

@ -119,7 +119,8 @@ note_value (value_object *value_obj)
values_in_python = value_obj;
}
/* Called when a new gdb.Value object needs to be allocated. */
/* Called when a new gdb.Value object needs to be allocated. Returns NULL on
error, with a python exception set. */
static PyObject *
valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
{
@ -438,7 +439,7 @@ valpy_length (PyObject *self)
}
/* Given string name of an element inside structure, return its value
object. */
object. Returns NULL on error, with a python exception set. */
static PyObject *
valpy_getitem (PyObject *self, PyObject *key)
{
@ -499,7 +500,7 @@ valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
}
/* Called by the Python interpreter to perform an inferior function
call on the value. */
call on the value. Returns NULL on error, with a python exception set. */
static PyObject *
valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
{
@ -619,7 +620,8 @@ enum valpy_opcode
((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
/* Returns a value object which is the result of applying the operation
specified by OPCODE to the given arguments. */
specified by OPCODE to the given arguments. Returns NULL on error, with
a python exception set. */
static PyObject *
valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
{
@ -871,7 +873,8 @@ valpy_xor (PyObject *self, PyObject *other)
return valpy_binop (VALPY_BITXOR, self, other);
}
/* Implements comparison operations for value objects. */
/* Implements comparison operations for value objects. Returns NULL on error,
with a python exception set. */
static PyObject *
valpy_richcompare (PyObject *self, PyObject *other, int op)
{

View file

@ -79,6 +79,7 @@ struct python_env
PyGILState_STATE state;
struct gdbarch *gdbarch;
const struct language_defn *language;
PyObject *error_type, *error_value, *error_traceback;
};
static void
@ -86,6 +87,16 @@ restore_python_env (void *p)
{
struct python_env *env = (struct python_env *)p;
/* Leftover Python error is forbidden by Python Exception Handling. */
if (PyErr_Occurred ())
{
/* This order is similar to the one calling error afterwards. */
gdbpy_print_stack ();
warning (_("internal error: Unhandled Python exception"));
}
PyErr_Restore (env->error_type, env->error_value, env->error_traceback);
PyGILState_Release (env->state);
python_gdbarch = env->gdbarch;
python_language = env->language;
@ -108,6 +119,9 @@ ensure_python_env (struct gdbarch *gdbarch,
python_gdbarch = gdbarch;
python_language = language;
/* Save it and ensure ! PyErr_Occurred () afterwards. */
PyErr_Fetch (&env->error_type, &env->error_value, &env->error_traceback);
return make_cleanup (restore_python_env, env);
}

View file

@ -1,3 +1,8 @@
2010-10-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.python/py-error.exp: New file.
* gdb.python/py-error.py: New file.
2010-10-12 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/break-interp.exp (test_ld): Replace gdb_expect by

View file

@ -0,0 +1,56 @@
# Copyright (C) 2010 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Test error while loading *-gdb.py. IBM1047 is chosen as possibly supported
# by glibc but unsupported by Python
set testfile "py-error"
load_lib gdb-python.exp
# Start with a fresh gdb.
gdb_exit
gdb_start
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
set charset "IBM1047"
set test2 "main reached"
set test "set host-charset $charset"
set test_regex [string_to_regexp $test]
gdb_test_multiple $test $test {
-re "^$test_regex\r\n$gdb_prompt $" {
pass $test
}
-re "^$test_regex\r\nUndefined item: \"$charset\"\\.\r\n$gdb_prompt $" {
xfail $test
untested $test2
set test2 ""
}
}
if {$test2 == ""} {
return 0
}
set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
# argc=LookupError: unknown encoding: IBM1047
gdb_test "source $remote_python_file" "Traceback.*ClassName.*\r\nLookupError: unknown encoding: $charset" $test2
gdb_test "p 1" " = 1" "no delayed error"

View file

@ -0,0 +1,25 @@
# Copyright (C) 2010 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import gdb
class ClassName(gdb.Command):
'a'
def __init__(self):
gdb.Command.__init__ (self, "ClassName", gdb.COMMAND_DATA, prefix=True)
def invoke(self, args, from_tty):
print
ClassName()

View file

@ -1052,6 +1052,8 @@ update_dynamic_varobj_children (struct varobj *var,
error (_("Invalid item from the child list"));
v = convert_value_from_python (py_v);
if (v == NULL)
gdbpy_print_stack ();
install_dynamic_child (var, can_mention ? changed : NULL,
can_mention ? new : NULL,
can_mention ? unchanged : NULL,
@ -2540,6 +2542,8 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
type = builtin_type (gdbarch)->builtin_char;
Py_DECREF (py_str);
}
else
gdbpy_print_stack ();
}
Py_DECREF (output);
}