Show padding in ptype/o output
authorTom Tromey <tom@tromey.com>
Sat, 12 May 2018 23:04:50 +0000 (17:04 -0600)
committerTom Tromey <tom@tromey.com>
Fri, 18 May 2018 19:20:39 +0000 (13:20 -0600)
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-18  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-18  Tom Tromey  <tom@tromey.com>

* gdb.base/ptype-offsets.exp: Update.

gdb/ChangeLog
gdb/c-typeprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/ptype-offsets.exp

index 263ce81..d4d00f8 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-18  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  Keith Seitz  <keiths@redhat.com>
 
        * breakpoint.c (build_bpstat_chain): New function, moved from
index 1a8af78..cb793f0 100644 (file)
@@ -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,
index 54fec1c..cdd4ba9 100644 (file)
@@ -1,3 +1,7 @@
+2018-05-18  Tom Tromey  <tom@tromey.com>
+
+       * gdb.base/ptype-offsets.exp: Update.
+
 2018-05-17  Keith Seitz  <keiths@redhat.com>
 
        * gdb.ada/bp_inlined_func.exp: Update inlined frame locations
index 003e294..d8718d5 100644 (file)
@@ -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 \*/} \
 {                         \}}]