This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Show padding in ptype/o output


On Thursday, May 17 2018, Tom Tromey wrote:

>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
>
> Tom> I was recently using ptype/o to look at the layout of some objects in
> Tom> gdb.  I noticed that trailing padding was not shown -- but I wanted to
> Tom> be able to look at that, too.
>
> Tom> This patch changes ptype/o to also print trailing holes.

Hm, I don't remember why I didn't implement this.  Maybe I was too
frustrated trying to figure out how to deal with bitfields...  Though I
seem to remember having a bit of a trouble with holes at the end of
objects.  But I don't really know, and if you ran the testcase and
everything passed, then I'd say it's good to go.

Thanks for implementing it.

> Oops, I forgot to squash those commits and only sent the test suite
> change.
>
> Here's the real patch.
>
> Tom
>
> commit f4c9741648a991f4591b290000214a9dbaf8099a
> Author: Tom Tromey <tom@tromey.com>
> Date:   Sat May 12 17:04:50 2018 -0600
>
>     Show padding in ptype/o output
>     
>     I was recently using ptype/o to look at the layout of some objects in
>     gdb.  I noticed that trailing padding was not shown -- but I wanted to
>     be able to look at that, too.
>     
>     This patch changes ptype/o to also print trailing holes.
>     
>     Tested on x86-64 Fedora 26.
>     
>     gdb/ChangeLog
>     2018-05-17  Tom Tromey  <tom@tromey.com>
>     
>             * c-typeprint.c (maybe_print_hole): New function.
>             (c_print_type_struct_field_offset): Update.
>             (c_type_print_base_struct_union): Call maybe_print_hole.
>     
>     gdb/testsuite/ChangeLog
>     2018-05-17  Tom Tromey  <tom@tromey.com>
>     
>             * gdb.base/ptype-offsets.exp: Update.
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 4ae46c1ae4..759ce08577 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,5 +1,11 @@
>  2018-05-17  Tom Tromey  <tom@tromey.com>
>  
> +	* c-typeprint.c (maybe_print_hole): New function.
> +	(c_print_type_struct_field_offset): Update.
> +	(c_type_print_base_struct_union): Call maybe_print_hole.
> +
> +2018-05-17  Tom Tromey  <tom@tromey.com>
> +
>  	* extension.h (struct ext_lang_type_printers) <py_type_printers>:
>  	Initialize.
>  
> diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
> index 1a8af78669..cb793f0770 100644
> --- a/gdb/c-typeprint.c
> +++ b/gdb/c-typeprint.c
> @@ -937,6 +937,42 @@ c_print_type_union_field_offset (struct type *type, unsigned int field_idx,
>    fprintf_filtered (stream, "/*              %4u */", TYPE_LENGTH (ftype));
>  }
>  
> +/* Helper function for ptype/o implementation that prints information
> +   about a hole, if necessary.  STREAM is where to print.  BITPOS is
> +   the bitpos of the current field.  PODATA is the offset-printing
> +   state.  FOR_WHAT is a string describing the purpose of the
> +   hole.  */
> +
> +static void
> +maybe_print_hole (struct ui_file *stream, unsigned int bitpos,
> +		  struct print_offset_data *podata, const char *for_what)
> +{
> +  /* We check for PODATA->END_BITPOS > 0 because there is a specific
> +     scenario when PODATA->END_BITPOS can be zero and BITPOS can be >
> +     0: when we are dealing with a struct/class with a virtual method.
> +     Because of the vtable, the first field of the struct/class will
> +     have an offset of sizeof (void *) (the size of the vtable).  If
> +     we do not check for PODATA->END_BITPOS > 0 here, GDB will report
> +     a hole before the first field, which is not accurate.  */
> +  if (podata->end_bitpos > 0 && podata->end_bitpos < bitpos)
> +    {
> +      /* If PODATA->END_BITPOS is smaller than the current type's
> +	 bitpos, it means there's a hole in the struct, so we report
> +	 it here.  */
> +      unsigned int hole = bitpos - podata->end_bitpos;
> +      unsigned int hole_byte = hole / TARGET_CHAR_BIT;
> +      unsigned int hole_bit = hole % TARGET_CHAR_BIT;
> +
> +      if (hole_bit > 0)
> +	fprintf_filtered (stream, "/* XXX %2u-bit %s  */\n", hole_bit,
> +			  for_what);
> +
> +      if (hole_byte > 0)
> +	fprintf_filtered (stream, "/* XXX %2u-byte %s */\n", hole_byte,
> +			  for_what);
> +    }
> +}
> +
>  /* Print information about field at index FIELD_IDX of the struct type
>     TYPE.
>  
> @@ -963,28 +999,7 @@ c_print_type_struct_field_offset (struct type *type, unsigned int field_idx,
>    unsigned int fieldsize_byte = TYPE_LENGTH (ftype);
>    unsigned int fieldsize_bit = fieldsize_byte * TARGET_CHAR_BIT;
>  
> -  /* We check for PODATA->END_BITPOS > 0 because there is a specific
> -     scenario when PODATA->END_BITPOS can be zero and BITPOS can be >
> -     0: when we are dealing with a struct/class with a virtual method.
> -     Because of the vtable, the first field of the struct/class will
> -     have an offset of sizeof (void *) (the size of the vtable).  If
> -     we do not check for PODATA->END_BITPOS > 0 here, GDB will report
> -     a hole before the first field, which is not accurate.  */
> -  if (podata->end_bitpos > 0 && podata->end_bitpos < bitpos)
> -    {
> -      /* If PODATA->END_BITPOS is smaller than the current type's
> -	 bitpos, it means there's a hole in the struct, so we report
> -	 it here.  */
> -      unsigned int hole = bitpos - podata->end_bitpos;
> -      unsigned int hole_byte = hole / TARGET_CHAR_BIT;
> -      unsigned int hole_bit = hole % TARGET_CHAR_BIT;
> -
> -      if (hole_bit > 0)
> -	fprintf_filtered (stream, "/* XXX %2u-bit hole   */\n", hole_bit);
> -
> -      if (hole_byte > 0)
> -	fprintf_filtered (stream, "/* XXX %2u-byte hole  */\n", hole_byte);
> -    }
> +  maybe_print_hole (stream, bitpos, podata, "hole");
>  
>    if (TYPE_FIELD_PACKED (type, field_idx))
>      {
> @@ -1508,6 +1523,9 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream,
>  	{
>  	  if (show > 0)
>  	    {
> +	      unsigned int bitpos = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
> +	      maybe_print_hole (stream, bitpos, podata, "padding");
> +
>  	      fputs_filtered ("\n", stream);
>  	      print_spaces_filtered_with_print_options (level + 4,
>  							stream,
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index b18d4b6743..03fd99bf41 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,7 @@
> +2018-05-17  Tom Tromey  <tom@tromey.com>
> +
> +	* gdb.base/ptype-offsets.exp: Update.
> +
>  2018-05-15  Maciej W. Rozycki  <macro@mips.com>
>  
>  	* gdb.server/server-kill.exp: Verify whether `server_pid' exists
> diff --git a/gdb/testsuite/gdb.base/ptype-offsets.exp b/gdb/testsuite/gdb.base/ptype-offsets.exp
> index 003e294a74..d8718d581b 100644
> --- a/gdb/testsuite/gdb.base/ptype-offsets.exp
> +++ b/gdb/testsuite/gdb.base/ptype-offsets.exp
> @@ -52,6 +52,7 @@ gdb_test "ptype /o struct abc" \
>  {                               /\* total size \(bytes\):    8 \*/} \
>  {                           \} field8;} \
>  {/\*   48      |     4 \*/    my_int_type field9;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                           /\* total size \(bytes\):   56 \*/} \
>  {                         \}}]
> @@ -81,6 +82,7 @@ gdb_test "ptype /oTM struct abc" \
>  {                           ~abc\(\);} \
>  {} \
>  {                           typedef int my_int_type;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                           /\* total size \(bytes\):   56 \*/} \
>  {                         \}}]
> @@ -105,6 +107,7 @@ gdb_test "ptype /TMo struct abc" \
>  {                               /\* total size \(bytes\):    8 \*/} \
>  {                           \} field8;} \
>  {/\*   48      |     4 \*/    my_int_type field9;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                           /\* total size \(bytes\):   56 \*/} \
>  {                         \}}]
> @@ -133,6 +136,7 @@ gdb_test "ptype /o struct pqr" \
>  {                           \} ff2;} \
>  {/\* XXX 28-byte hole  \*/} \
>  {/\*   72      |     1 \*/    signed char ff3;} \
> +{/\* XXX  7-byte padding \*/} \
>  {} \
>  {                           /\* total size \(bytes\):   56 \*/} \
>  {                         \}}]
> @@ -148,6 +152,7 @@ gdb_test "ptype /o union qwe" \
>  {/\* XXX  4-byte hole  \*/} \
>  {/\*    8      |     8 \*/        signed char \*a2;} \
>  {/\*   16      |     4 \*/        int a3;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                               /\* total size \(bytes\):   24 \*/} \
>  {                           \} fff1;} \
> @@ -161,6 +166,7 @@ gdb_test "ptype /o union qwe" \
>  {/\* XXX  4-byte hole  \*/} \
>  {/\*   24      |     8 \*/            signed char \*a2;} \
>  {/\*   32      |     4 \*/            int a3;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                                   /\* total size \(bytes\):   24 \*/} \
>  {                               \} f4;} \
> @@ -184,6 +190,7 @@ gdb_test "ptype /o struct poi" \
>  {/\* XXX  4-byte hole  \*/} \
>  {/\*   16      |     8 \*/            signed char \*a2;} \
>  {/\*   24      |     4 \*/            int a3;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                                   /\* total size \(bytes\):   24 \*/} \
>  {                               \} fff1;} \
> @@ -197,9 +204,11 @@ gdb_test "ptype /o struct poi" \
>  {/\* XXX  4-byte hole  \*/} \
>  {/\*   32      |     8 \*/                signed char \*a2;} \
>  {/\*   40      |     4 \*/                int a3;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                                       /\* total size \(bytes\):   24 \*/} \
>  {                                   \} f4;} \
> +{/\* XXX  32-byte padding \*/} \
>  {} \
>  {                                   /\* total size \(bytes\):   40 \*/} \
>  {                               \} fff2;} \
> @@ -221,6 +230,7 @@ gdb_test "ptype /o struct poi" \
>  {/\* XXX  4-byte hole  \*/} \
>  {/\*  112      |     8 \*/                signed char \*a2;} \
>  {/\*  120      |     4 \*/                int a3;} \
> +{/\* XXX  4-byte padding \*/} \
>  {} \
>  {                                       /\* total size \(bytes\):   24 \*/} \
>  {                                   \} f4;} \
> @@ -228,6 +238,7 @@ gdb_test "ptype /o struct poi" \
>  {                                   /\* total size \(bytes\):   40 \*/} \
>  {                               \} ff2;} \
>  {/\*  152      |     1 \*/        signed char ff3;} \
> +{/\* XXX  7-byte padding \*/} \
>  {} \
>  {                               /\* total size \(bytes\):   56 \*/} \
>  {                           \} f4;} \
> @@ -262,6 +273,7 @@ gdb_test "ptype /o struct tyu" \
>  {/\*    8      |     8 \*/    int64_t a5;} \
>  {/\*   16:27   |     4 \*/    int a6 : 5;} \
>  {/\*   16:56   |     8 \*/    int64_t a7 : 3;} \
> +{/\* XXX  7-byte padding \*/} \
>  {} \
>  {                           /\* total size \(bytes\):   24 \*/} \
>  {                         \}}]

-- 
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF  31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]