public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* RE: [PING*1] [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
@ 2022-02-02  5:21 Kumar N, Bhuvanendra
  0 siblings, 0 replies; only message in thread
From: Kumar N, Bhuvanendra @ 2022-02-02  5:21 UTC (permalink / raw)
  To: Joel Brobecker, Andrew Burgess
  Cc: gdb-patches, George, Jini Susan, Sharma, Alok Kumar

[AMD Official Use Only]

Hi all,

Gentle [PING*1] for the revised patch .....

Regards,
bhuvan

-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Thursday, January 20, 2022 9:51 PM
To: 'Joel Brobecker' <brobecker@adacore.com>; 'Andrew Burgess' <aburgess@redhat.com>
Cc: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi all,

Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.

Reason for the assert failure when GDB is built with -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the namelist variable type was not populated, it was zero, hence assert was failing in gdbsupport/array-view.h. Now this is fixed and I could test with -D_GLIBCXX_DEBUG=1

Compiler is not emitting the size of the namelist variable type, hence GDB is calculating it. In similar types like DW_TAG_structure_type, DW_AT_byte_size attribute is emitted by compiler and GDB uses it with TYPE_LENGTH. It's not the case with DW_TAG_namelist. Hence size of the namelist variable type is calculated in GDB. Also unlike DW_TAG_structure_type, namelist items are not allocated in continuous memory, they are spread across, hence for each namelist item symbol table lookup is done before printing its value. This way making sure namelist items printing is intact.

Regards,
Bhuvan

PATCH inlined:

From 68d315db5488b17b6e47e052947768a4c8a19fa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 18 Jan 2022 18:12:33 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.

Gfortran supports namelist(a fortran feature); it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and does not support 'print' or 'ptype' commands on namelist variables. An attempt to print namelist variables results in gdb bailing out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 24 +++++++++++++
 gdb/gdbtypes.h                         | 13 +++++++
 gdb/testsuite/gdb.fortran/namelist.exp | 50 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 gdb/value.c                            |  2 +-
 include/dwarf2.def                     |  2 +-
 8 files changed, 159 insertions(+), 9 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..2629a0ff432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && ! die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          /* Typically, DW_TAG_namelist_item are references to namelist items.
+             If so, follow that reference.  */
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15635,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15841,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15886,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21992,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22939,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22964,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..48044d1ab1c 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,8 +295,22 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
+      /* Calculate and set the total size or length of the namelist variable
+         type, which is summation of size of each item in the namelist
+         variable. Please note the namelist items are not allocated in
+         continuous memory unlike other types, hence for each namelist item
+         symbol table lookup is done before printing its value.  */
+      if (type->code () == TYPE_CODE_NAMELIST)
+        {
+          unsigned int total_size = 0;
+          for (index = 0; index < type->num_fields (); index++)
+            total_size += TYPE_LENGTH (type->field (index).type ());
+          TYPE_LENGTH (type) = total_size;
+        }
+
       fprintf_filtered (stream, "( ");
       for (index = 0; index < type->num_fields (); index++)
 	{
@@ -320,6 +334,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol
+	            (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..8da362bddec 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..2e8325c0b1d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify 
+# it under the terms of the GNU General Public License as published by 
+# the Free Software Foundation; either version 3 of the License, or # 
+(at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, # but 
+WITHOUT ANY WARRANTY; without even the implied warranty of # 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the # GNU 
+General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License # 
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed # 
+differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 2021 Free Software Foundation, Inc.
+!
+! This program is free software; you can redistribute it and/or modify 
+! it under the terms of the GNU General Public License as published by 
+! the Free Software Foundation; either version 3 of the License, or ! 
+(at your option) any later version.
+!
+! This program is distributed in the hope that it will be useful, ! but 
+WITHOUT ANY WARRANTY; without even the implied warranty of ! 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ! GNU 
+General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License ! 
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/gdb/value.c b/gdb/value.c
index bb2adae0a51..16be02fb199 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3901,7 +3901,7 @@ value_fetch_lazy_memory (struct value *val)
   CORE_ADDR addr = value_address (val);
   struct type *type = check_typedef (value_enclosing_type (val));
 
-  if (TYPE_LENGTH (type))
+  if (TYPE_LENGTH (type) && (type->code () != TYPE_CODE_NAMELIST))
       read_value_memory (val, 0, value_stack (val),
 			 addr, value_contents_all_raw (val),
 			 type_length_units (type));
diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
--
2.17.1



-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Thursday, December 23, 2021 9:22 PM
To: Joel Brobecker <brobecker@adacore.com>; Andrew Burgess <aburgess@redhat.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi,

I could reproduce the assert that Andrew mentioned with the patch and -D_GLIBCXX_DEBUG=1. I am looking into it.

I had to configure like this as Andrew suggested.

../binutils-gdb/configure  --disable-sim --enable-targets=all CFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1" CXXFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1"

Regards,
Bhuvan

-----Original Message-----
From: Joel Brobecker <brobecker@adacore.com>
Sent: Monday, December 20, 2021 10:43 AM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: Joel Brobecker <brobecker@adacore.com>; gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

Hi Bhuvan,

> Thanks a lot for your comments. I have tried to address all your 
> previous comments. I have attached the revised patch and also inlined.
> Not sure if you see some trailing spaces or indentation issues still, 
> mostly they are due to my email client(MS outlook). Please let me know 
> if you have any comments. Thanks again.

I believe Andrew had some questions (failed assertion).
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fpipermail%2Fgdb-patches%2F2021-December%2F184362.html&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C0e5d2c316a6743220b7908d9c3777633%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637755740127814129%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=7FIqu1y2JDqVzKKGbOpSS0qOBfZQdofAmYvOYM%2BS2Wk%3D&amp;reserved=0

Have you looked into that?

--
Joel

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-02  5:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-02  5:21 [PING*1] [PATCH] Fix ptype and print commands for namelist variables(a fortran feature) Kumar N, Bhuvanendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).