diff mbox series

gdbhooks: Handle references to vec* in VecPrinter

Message ID ZtH9V6KLPGFxiE/G@arm.com
State New
Headers show
Series gdbhooks: Handle references to vec* in VecPrinter | expand

Commit Message

Alex Coplan Aug. 30, 2024, 5:11 p.m. UTC
Hi,

vec.h has this method:

  template<typename T, typename A>
  inline T *
  vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)

where v is a reference to a pointer to vec.  This matches the regex for
VecPrinter, so gdbhooks.py attempts to print it but chokes on the reference.
I see the following:

  #1  0x0000000002b84b7b in vec_safe_push<edge_def*, va_gc> (v=Traceback (most
  recent call last):
    File "$SRC/gcc/gcc/gdbhooks.py", line 486, in to_string
      return '0x%x' % intptr(self.gdbval)
    File "$SRC/gcc/gcc/gdbhooks.py", line 168, in intptr
      return long(gdbval) if sys.version_info.major == 2 else int(gdbval)
  gdb.error: Cannot convert value to long.

This patch makes VecPrinter handle such references by stripping them
(dereferencing) at the top of the relevant functions.

I thought about trying to make VecPrinter.{to_string,children} robust
against non-pointer values (i.e. actual vec structs) as the current
calls to intptr will fail on those.  However, I then realised that the
current regex only matches pointer types:

  pp.add_printer_for_regex(r'vec<(\S+), (\S+), (\S+)> \*',
                           'vec',
                           VecPrinter)

That is somewhat at odds with the (pre-existing) code in
VecPrinter.children which appears to attempt to handle non-pointer
types.  ISTM either we should drop the handling for non-pointer types
(since the regex requires a pointer) or (perhaps more usefully) relax
the regex to allow matching a plain vec<...> struct and fix the member
functions to handle those properly.

Any thoughts on that, Dave?  Is the current patch OK as an intermediate
step (manually tested by verifying both a vec*& and vec* print OK)?

Thanks,
Alex

gcc/ChangeLog:

	* gdbhooks.py (strip_ref): New. Use it ...
	(VecPrinter.to_string): ... here,
	(VecPrinter.children): ... and here.

Comments

Alex Coplan Sept. 23, 2024, 10:33 a.m. UTC | #1
On 30/08/2024 18:11, Alex Coplan wrote:
> Hi,
> 
> vec.h has this method:
> 
>   template<typename T, typename A>
>   inline T *
>   vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
> 
> where v is a reference to a pointer to vec.  This matches the regex for
> VecPrinter, so gdbhooks.py attempts to print it but chokes on the reference.
> I see the following:
> 
>   #1  0x0000000002b84b7b in vec_safe_push<edge_def*, va_gc> (v=Traceback (most
>   recent call last):
>     File "$SRC/gcc/gcc/gdbhooks.py", line 486, in to_string
>       return '0x%x' % intptr(self.gdbval)
>     File "$SRC/gcc/gcc/gdbhooks.py", line 168, in intptr
>       return long(gdbval) if sys.version_info.major == 2 else int(gdbval)
>   gdb.error: Cannot convert value to long.
> 
> This patch makes VecPrinter handle such references by stripping them
> (dereferencing) at the top of the relevant functions.
> 
> I thought about trying to make VecPrinter.{to_string,children} robust
> against non-pointer values (i.e. actual vec structs) as the current
> calls to intptr will fail on those.  However, I then realised that the
> current regex only matches pointer types:
> 
>   pp.add_printer_for_regex(r'vec<(\S+), (\S+), (\S+)> \*',
>                            'vec',
>                            VecPrinter)
> 
> That is somewhat at odds with the (pre-existing) code in
> VecPrinter.children which appears to attempt to handle non-pointer
> types.  ISTM either we should drop the handling for non-pointer types
> (since the regex requires a pointer) or (perhaps more usefully) relax
> the regex to allow matching a plain vec<...> struct and fix the member
> functions to handle those properly.
> 
> Any thoughts on that, Dave?  Is the current patch OK as an intermediate
> step (manually tested by verifying both a vec*& and vec* print OK)?

Gentle ping on this.

> 
> Thanks,
> Alex
> 
> gcc/ChangeLog:
> 
> 	* gdbhooks.py (strip_ref): New. Use it ...
> 	(VecPrinter.to_string): ... here,
> 	(VecPrinter.children): ... and here.

> diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
> index 904ee28423a..a91e5fd2a83 100644
> --- a/gcc/gdbhooks.py
> +++ b/gcc/gdbhooks.py
> @@ -472,6 +472,11 @@ def get_vec_kind(val):
>      else:
>          assert False, f"unexpected vec kind {kind}"
>  
> +def strip_ref(gdbval):
> +    if gdbval.type.code == gdb.TYPE_CODE_REF:
> +        return gdbval.referenced_value ()
> +    return gdbval
> +
>  class VecPrinter:
>      #    -ex "up" -ex "p bb->preds"
>      def __init__(self, gdbval):
> @@ -483,10 +488,10 @@ class VecPrinter:
>      def to_string (self):
>          # A trivial implementation; prettyprinting the contents is done
>          # by gdb calling the "children" method below.
> -        return '0x%x' % intptr(self.gdbval)
> +        return '0x%x' % intptr(strip_ref(self.gdbval))
>  
>      def children (self):
> -        val = self.gdbval
> +        val = strip_ref(self.gdbval)
>          if intptr(val) != 0 and get_vec_kind(val) == VEC_KIND_PTR:
>              val = val['m_vec']
>
Jeff Law Sept. 29, 2024, 3:35 p.m. UTC | #2
On 9/23/24 4:33 AM, Alex Coplan wrote:
> On 30/08/2024 18:11, Alex Coplan wrote:
>> Hi,
>>
>> vec.h has this method:
>>
>>    template<typename T, typename A>
>>    inline T *
>>    vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
>>
>> where v is a reference to a pointer to vec.  This matches the regex for
>> VecPrinter, so gdbhooks.py attempts to print it but chokes on the reference.
>> I see the following:
>>
>>    #1  0x0000000002b84b7b in vec_safe_push<edge_def*, va_gc> (v=Traceback (most
>>    recent call last):
>>      File "$SRC/gcc/gcc/gdbhooks.py", line 486, in to_string
>>        return '0x%x' % intptr(self.gdbval)
>>      File "$SRC/gcc/gcc/gdbhooks.py", line 168, in intptr
>>        return long(gdbval) if sys.version_info.major == 2 else int(gdbval)
>>    gdb.error: Cannot convert value to long.
>>
>> This patch makes VecPrinter handle such references by stripping them
>> (dereferencing) at the top of the relevant functions.
>>
>> I thought about trying to make VecPrinter.{to_string,children} robust
>> against non-pointer values (i.e. actual vec structs) as the current
>> calls to intptr will fail on those.  However, I then realised that the
>> current regex only matches pointer types:
>>
>>    pp.add_printer_for_regex(r'vec<(\S+), (\S+), (\S+)> \*',
>>                             'vec',
>>                             VecPrinter)
>>
>> That is somewhat at odds with the (pre-existing) code in
>> VecPrinter.children which appears to attempt to handle non-pointer
>> types.  ISTM either we should drop the handling for non-pointer types
>> (since the regex requires a pointer) or (perhaps more usefully) relax
>> the regex to allow matching a plain vec<...> struct and fix the member
>> functions to handle those properly.
>>
>> Any thoughts on that, Dave?  Is the current patch OK as an intermediate
>> step (manually tested by verifying both a vec*& and vec* print OK)?
> 
> Gentle ping on this.
OK

Jeff
diff mbox series

Patch

diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 904ee28423a..a91e5fd2a83 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -472,6 +472,11 @@  def get_vec_kind(val):
     else:
         assert False, f"unexpected vec kind {kind}"
 
+def strip_ref(gdbval):
+    if gdbval.type.code == gdb.TYPE_CODE_REF:
+        return gdbval.referenced_value ()
+    return gdbval
+
 class VecPrinter:
     #    -ex "up" -ex "p bb->preds"
     def __init__(self, gdbval):
@@ -483,10 +488,10 @@  class VecPrinter:
     def to_string (self):
         # A trivial implementation; prettyprinting the contents is done
         # by gdb calling the "children" method below.
-        return '0x%x' % intptr(self.gdbval)
+        return '0x%x' % intptr(strip_ref(self.gdbval))
 
     def children (self):
-        val = self.gdbval
+        val = strip_ref(self.gdbval)
         if intptr(val) != 0 and get_vec_kind(val) == VEC_KIND_PTR:
             val = val['m_vec']