From ae778caf097e08497f2e9218cf68b254b8da38f1 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 15 Sep 2018 01:09:22 -0600 Subject: [PATCH] Allow setting a parameter to raise gdb.GdbError A convention in the Python layer is that raising a gdb.GdbError will not print the Python stack -- instead the exception is treated as any other gdb exception. PR python/18852 asks that this treatment be extended the the get_set_value method of gdb.Parameter. This makes sense, because it lets Python-created parameters act like gdb parameters. 2018-09-23 Tom Tromey PR python/18852: * python/py-param.c (get_set_value): Use gdbpy_handle_exception. gdb/doc/ChangeLog 2018-09-23 Tom Tromey PR python/18852: * python.texi (Parameters In Python): Document exception behavior of get_set_string. gdb/testsuite/ChangeLog 2018-09-23 Tom Tromey PR python/18852: * gdb.python/py-parameter.exp: Add test for parameter that throws on "set". --- gdb/ChangeLog | 5 +++++ gdb/doc/ChangeLog | 6 ++++++ gdb/doc/python.texi | 24 +++++++++++++++++++++++ gdb/python/py-param.c | 5 +---- gdb/testsuite/ChangeLog | 6 ++++++ gdb/testsuite/gdb.python/py-parameter.exp | 15 ++++++++++++++ 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cbbd146fc9..e8005c0255 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2018-09-23 Tom Tromey + + PR python/18852: + * python/py-param.c (get_set_value): Use gdbpy_handle_exception. + 2018-09-23 Tom Tromey * python/py-function.c (fnpy_call): Use gdbpy_handle_exception. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 6d12553a28..4285a4d8bb 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2018-09-23 Tom Tromey + + PR python/18852: + * python.texi (Parameters In Python): Document exception behavior + of get_set_string. + 2018-09-18 John Baldwin * gdb.texinfo (info proc): Remove "running". diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index e98178a121..1035be33f0 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -3828,6 +3828,30 @@ example, @kbd{set foo off}). The @code{value} attribute has already been populated with the new value and may be used in output. This method must return a string. If the returned string is not empty, @value{GDBN} will present it to the user. + +If this method raises the @code{gdb.GdbError} exception +(@pxref{Exception Handling}), then @value{GDBN} will print the +exception's string and the @code{set} command will fail. Note, +however, that the @code{value} attribute will not be reset in this +case. So, if your parameter must validate values, it should store the +old value internally and reset the exposed value, like so: + +@smallexample +class ExampleParam (gdb.Parameter): + def __init__ (self, name): + super (ExampleParam, self).__init__ (name, + gdb.COMMAND_DATA, + gdb.PARAM_BOOLEAN) + self.value = True + self.saved_value = True + def validate(self): + return False + def get_set_string (self): + if not self.validate(): + self.value = self.saved_value + raise gdb.GdbError('Failed to validate') + self.saved_value = self.value +@end smallexample @end defun @defun Parameter.get_show_string (self, svalue) diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index 0f0214befe..bff5d60fc2 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -396,10 +396,7 @@ get_set_value (const char *args, int from_tty, { set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL); if (! set_doc_string) - { - gdbpy_print_stack (); - return; - } + gdbpy_handle_exception (); } const char *str = set_doc_string.get (); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4a624ddd66..877edc0cb5 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-09-23 Tom Tromey + + PR python/18852: + * gdb.python/py-parameter.exp: Add test for parameter that throws + on "set". + 2018-09-23 Tom Tromey PR python/17284: diff --git a/gdb/testsuite/gdb.python/py-parameter.exp b/gdb/testsuite/gdb.python/py-parameter.exp index 0508544f9d..9a36e6372d 100644 --- a/gdb/testsuite/gdb.python/py-parameter.exp +++ b/gdb/testsuite/gdb.python/py-parameter.exp @@ -203,3 +203,18 @@ foreach kind {PARAM_ZUINTEGER PARAM_ZUINTEGER_UNLIMITED} { "check that PARAM_ZUINTEGER value is -1 after setting" } } + +gdb_py_test_multiple "Throwing gdb parameter" \ + "python" "" \ + "class TestThrowParam (gdb.Parameter):" "" \ + " def __init__ (self, name):" "" \ + " super (TestThrowParam, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_STRING)" "" \ + " self.value = True" "" \ + " def get_set_string (self):" "" \ + " raise gdb.GdbError('Ordinary gdb error')" "" \ + "test_throw_param = TestThrowParam ('print test-throw-param')" ""\ + "end" + +gdb_test "set print test-throw-param whoops" \ + "Ordinary gdb error" \ + "gdb.GdbError does not show Python stack" -- 2.34.1