[PATCHv2] gdb/python: don't use the 'p' format for parsing args

Simon Marchi simon.marchi@polymtl.ca
Tue Nov 30 15:02:57 GMT 2021



On 2021-11-30 09:38, Andrew Burgess wrote:
> * Simon Marchi <simon.marchi@polymtl.ca> [2021-11-30 07:40:27 -0500]:
> 
>> On 2021-11-29 10:21, Andrew Burgess via Gdb-patches wrote:
>>> When running the gdb.python/py-arch.exp tests on a GDB built
>>> against Python 2 I ran into some errors.  The problem is that this
>>> test script exercises the gdb.Architecture.integer_type method, and
>>> this method uses 'p' as an argument format specifier in a call to
>>> gdb_PyArg_ParseTupleAndKeywords.
>>>
>>> Unfortunately this specified was only added in Python 3.3, so will
>>> cause an error for earlier versions of Python.
>>>
>>> This commit switches to using the 'i' specifier which should be good
>>> enough.
>>>
>>> There should be no user visible changes after this commit.
>>
>> I don't know if it's important, but there is user visible change.
>> Basically if the user passed any object other than an int, expecting it
>> to be converted to bool:
>>
>> Before:
>>
>>     >>> gdb.selected_inferior().architecture().integer_type(32, None)
>>     <gdb.Type object at 0x7f1ce94086c0>
>>     >>> gdb.selected_inferior().architecture().integer_type(32, "foo")
>>     <gdb.Type object at 0x7f1ce95f7750>
>>
>> After:
>>
>>     >>> gdb.selected_inferior().architecture().integer_type(32, None)
>>     Traceback (most recent call last):
>>       File "<stdin>", line 1, in <module>
>>     TypeError: an integer is required (got type NoneType)
>>     >>> gdb.selected_inferior().architecture().integer_type(32, "foo")
>>     Traceback (most recent call last):
>>       File "<stdin>", line 1, in <module>
>>     TypeError: an integer is required (got type str)
>>
>> I would suggest capturing the argument as an object (specifier 'O') and
>> using PyObject_IsTrue to convert it to bool.  That should work
>> everywhere.
> 
> Thanks for the feedback.  An updated version of the patch is included
> below.
> 
> Andrew
> 
> ---
> 
> commit 6bc532d238825893baf465cb0ac49fd6681224ff
> Author: Andrew Burgess <aburgess@redhat.com>
> Date:   Mon Nov 29 13:53:06 2021 +0000
> 
>     gdb/python: don't use the 'p' format for parsing args
>     
>     When running the gdb.python/py-arch.exp tests on a GDB built
>     against Python 2 I ran into some errors.  The problem is that this
>     test script exercises the gdb.Architecture.integer_type method, and
>     this method uses 'p' as an argument format specifier in a call to
>     gdb_PyArg_ParseTupleAndKeywords.
>     
>     Unfortunately this specified was only added in Python 3.3, so will
>     cause an error for earlier versions of Python.
>     
>     This commit switches to use the 'O' specifier to collect a PyObject,
>     and then uses PyObject_IsTrue to convert the object to a boolean.
>     
>     An earlier version of this patch incorrectly switched from using 'p'
>     to use 'i', however, it was pointed out during review that this would
>     cause some changes in behaviour, for example both of these will work
>     with 'p', but not with 'i':
>     
>       gdb.selected_inferior().architecture().integer_type(32, None)
>       gdb.selected_inferior().architecture().integer_type(32, "foo")
>     
>     The new approach of using 'O' works fine with these cases.  I've added
>     some new tests to cover both of the above.
>     
>     There should be no user visible changes after this commit.
> 
> diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
> index aa9a652ef26..824ad0bfeab 100644
> --- a/gdb/python/py-arch.c
> +++ b/gdb/python/py-arch.c
> @@ -276,12 +276,17 @@ static PyObject *
>  archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
>  {
>    static const char *keywords[] = { "size", "signed", NULL };
> -  int size, is_signed = 1;
> +  int size;
> +  PyObject *is_signed_obj = nullptr;
>  
> -  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|p", keywords,
> -					&size, &is_signed))
> +  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|O", keywords,
> +					&size, &is_signed_obj))
>      return nullptr;
>  
> +  /* Assume signed by default.  */
> +  bool is_signed = (is_signed_obj == nullptr
> +		    || PyObject_IsTrue (is_signed_obj));
> +
>    struct gdbarch *gdbarch;
>    ARCHPY_REQUIRE_VALID (self, gdbarch);
>  
> diff --git a/gdb/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp
> index f3bf01d2828..14dc1bf85ee 100644
> --- a/gdb/testsuite/gdb.python/py-arch.exp
> +++ b/gdb/testsuite/gdb.python/py-arch.exp
> @@ -64,7 +64,7 @@ if { ![is_address_zero_readable] } {
>  }
>  
>  foreach size {0 1 2 3 4 8 16} {
> -    foreach sign {"" ", True" ", False"} {
> +    foreach sign {"" ", True" ", False" ", None" ", \"blah\""} {
>  	set fullsize [expr 8 * $size]
>  	gdb_test_no_output "python t = arch.integer_type($fullsize$sign)" \
>  	    "get integer type for $size$sign"
> 

LGTM, thanks.

Simon


More information about the Gdb-patches mailing list