Bug 26910 - [fortran] Printing dynamic string with DW_AT_string_length of class loclistpr fails
Summary: [fortran] Printing dynamic string with DW_AT_string_length of class loclistpr...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: symtab (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 12.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-11-17 13:37 UTC by Tom de Vries
Modified: 2021-10-28 08:54 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2020-11-17 13:37:06 UTC
Consider test-case gdb.opt/fortran-string.f90, as found here ( https://src.fedoraproject.org/rpms/gdb/blob/master/f/gdb-archer-vla-tests.patch ), but with a print line added to prevent inlining of f:
...
     1    subroutine f(s)
     2    character*(*) s
     3    s = s
     4    print *, s
     5    end
     6
     7    program main
     8    call f ('foo')
     9    end
...

When printing the type of s at line 4:
...
$ gdb.sh -batch ./outputs/gdb.opt/fortran-string/fortran-string \
    -ex "b 4" \
    -ex r \
    -ex "ptype s"
Breakpoint 1 at 0x400734: file fortran-string.f90, line 4.

Breakpoint 1, f (s=..., _s=_s@entry=3) at fortran-string.f90:4
4         print *, s
type = character*1
...
we get "character*1", while we'd like to see string length 3 there.
Comment 1 Tom de Vries 2020-11-17 13:40:36 UTC
The parameter s in function f:
...
 <2><1ed>: Abbrev Number: 13 (DW_TAG_formal_parameter)
    <1ee>   DW_AT_name        : s
    <1f2>   DW_AT_type        : <0x25a>
...
has type:
...
 <1><25a>: Abbrev Number: 17 (DW_TAG_string_type)
    <25b>   DW_AT_string_length: 0xbf (location list)
    <25f>   DW_AT_byte_size   : 4
    <260>   DW_AT_sibling     : <0x26e>
...
matching with location list:
...
    000000bf 0000000000400730 0000000000400764 (DW_OP_reg4 (rsi))
    000000d2 0000000000400764 0000000000400783 (DW_OP_reg6 (rbp))
    000000e5 0000000000400783 0000000000400784 (DW_OP_GNU_entry_value: (DW_OP_reg4 (rsi)); DW_OP_stack_value)
...

Doing a print of pc at the breakpoint:
...
4         print *, s
(gdb) info registers pc
pc             0x400734            0x400734 <f+4>
...
tells us that the string length can be found in register rsi, which contains:
...
(gdb) info registers rsi
rsi            0x3                 3
...

So, the information seems to be there.  Why doesn't gdb use it?

We find the answer by stepping through read_tag_string_type.  We hit:
...
(gdb) 
17837         if (!attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
(gdb) 
17838           length = 1;
...
and that's the reason why the length is one.

So, why don't we manage to convert the attribute to a dynamic prop?

Stepping through attr_to_dynamic_prop shows why:
...
(gdb) 
18590     if (attr->form_is_block ())
(gdb) 
18613     else if (attr->form_is_ref ())
(gdb) 
18676     else if (attr->form_is_constant ())
(gdb) 
18680         dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
(gdb) 
18682         return 0;
...

The actual form is:
...
(gdb) p attr.form
$2 = DW_FORM_sec_offset
...
and that's not handled in attr_to_dynamic_prop.
Comment 2 Tom de Vries 2020-11-17 13:43:34 UTC
Tentative patch:
...
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3c598262913..151ba1faae2 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18675,14 +18675,30 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_in
fo *die,
     }
   else if (attr->form_is_constant ())
     prop->set_const_val (attr->constant_value (0));
-  else
+  else if (attr->form_is_section_offset ())
     {
-      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
-                                            dwarf2_name (die, cu));
-      return 0;
+      switch (attr->name)
+       {
+       case DW_AT_string_length:
+         baton = XOBNEW (obstack, struct dwarf2_property_baton);
+         baton->property_type = default_type;
+         fill_in_loclist_baton (cu, &baton->loclist, attr);
+         prop->set_loclist (baton);
+         gdb_assert (prop->baton () != NULL);
+         break;
+       default:
+         goto invalid;
+       }
     }
+  else
+    goto invalid;
 
   return 1;
+
+ invalid:
+  dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
+                                        dwarf2_name (die, cu));
+  return 0;
 }
 
 /* See read.h.  */
...

and we have:
...
$ gdb -batch ./outputs/gdb.opt/fortran-string/fortran-string \
    -ex "b 4" \
    -ex r \
    -ex "ptype s"
Breakpoint 1 at 0x400734: file fortran-string.f90, line 4.

Breakpoint 1, f (s=..., _s=_s@entry=3) at fortran-string.f90:4
4         print *, s
type = character (3)
...