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]

[patch] Correct `gcc -D' macros get ignored (PR 9873)


Hi,

http://sourceware.org/bugzilla/show_bug.cgi?id=9873

There is a GCC patch to fix DWARF macros defined from gcc command line
	http://sourceware.org/bugzilla/attachment.cgi?id=3753&action=view

but current GDB starts to ignore such macros.  Thus the GDB HEAD acceptance is
a prerequisite for the GCC HEAD change.

Command line macros should be defined _before_ first DW_MACINFO_start_file:

Regression tested on x86_64-unknown-linux-gnu.


current GCC:
Contents of the .debug_macinfo section:
 DW_MACINFO_start_file - lineno: 0 filenum: 1
 DW_MACINFO_define - lineno : 0 macro : __STDC__ 1
 DW_MACINFO_define - lineno : 0 macro : __STDC_HOSTED__ 1

patched GCC:
Contents of the .debug_macinfo section:
 DW_MACINFO_define - lineno : 0 macro : __STDC__ 1
 DW_MACINFO_define - lineno : 0 macro : __STDC_HOSTED__ 1

http://dwarf.freestandards.org/Dwarf3.pdf
6.3.3 Macinfo Entries for Command Line Options
[..]
All such DW_MACINFO_define and DW_MACINFO_undef entries representing
compilation options should appear before the first DW_MACINFO_start_file entry
for that compilation unit and should encode the value 0 in their line number
operands.

current GCC + current GDB:
patched GCC + patched GDB:
(gdb) info macro __STDC__
Defined at ../.././gdb/testsuite/gdb.base/macscp1.c:0
#define __STDC__ 1

patched GCC + current GDB:
During symbol reading, debug info gives macro definition outside of any file: __STDC__ 1.
During symbol reading, debug info gives macro definition outside of any file: __STDC_HOSTED__ 1.
(gdb) info macro __STDC__
The symbol `__STDC__' has no definition as a C/C++ preprocessor macro
at gdb.base/macscp1.c:102

current GCC + patched GDB:
During symbol reading, debug info gives in-file macro definition with zero line 0: __STDC__ 1.
During symbol reading, debug info gives in-file macro definition with zero line 0: __STDC_HOSTED__ 1.
(gdb) info macro __STDC__
Defined at ../.././gdb/testsuite/gdb.base/macscp1.c:0
#define __STDC__ 1


Thanks,
Jan

gdb/
2009-02-19  Jan Kratochvil  <jan.kratochvil@redhat.com>

	PR gdb/9873:
	* dwarf2read.c (dwarf_decode_macros): New variable `at_commandline'.
	Move the variable `macinfo_type' out of the loop.  Create a new
	processing pass before the current one to pre-create `current_file'.
	New complaint on misplaced zero/non-zero definitions/includes.
	Skip first DW_MACINFO_start_file with `at_commandline' set.

gdb/testsuite/
2009-02-19  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/macscp.exp: New option `-DFROM_COMMANDLINE'.  New workaround
	of a ccache bug.
	(info_macro): Suffix the filename for command line macros.
	(info macro FROM_COMMANDLINE after `list main'): New test.

--- gdb/dwarf2read.c	12 Feb 2009 09:15:06 -0000	1.295
+++ gdb/dwarf2read.c	19 Feb 2009 21:05:11 -0000
@@ -9963,6 +9963,17 @@ dwarf_decode_macros (struct line_header 
 {
   gdb_byte *mac_ptr, *mac_end;
   struct macro_source_file *current_file = 0;
+  enum dwarf_macinfo_record_type macinfo_type;
+
+  /* Flag is in use by the second pass and determines if GDB is still before
+     first DW_MACINFO_start_file.  If true GDB is still reading the definitions
+     from command line.  First DW_MACINFO_start_file will need to be ignored as
+     it was already executed to create CURRENT_FILE for the main source holding
+     also the command line definitions.  On first met DW_MACINFO_start_file
+     this flag is reset to normally execute all the remaining
+     DW_MACINFO_start_file macinfos.  */
+
+  int at_commandline;
 
   if (dwarf2_per_objfile->macinfo_buffer == NULL)
     {
@@ -9970,19 +9981,24 @@ dwarf_decode_macros (struct line_header 
       return;
     }
 
+  /* Start the first pass to find ahead the main source file name.  GDB has to
+     create CURRENT_FILE where to place the macros given to the compiler
+     from the command line.  Such command line macros are present before first
+     DW_MACINFO_start_file but still those macros are associated to the
+     compilation unit.  The compilation unit GDB identifies by its main source
+     file name.  */
+
   mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
   mac_end = dwarf2_per_objfile->macinfo_buffer
     + dwarf2_per_objfile->macinfo_size;
 
-  for (;;)
+  do
     {
-      enum dwarf_macinfo_record_type macinfo_type;
-
       /* Do we at least have room for a macinfo type byte?  */
       if (mac_ptr >= mac_end)
         {
 	  dwarf2_macros_too_long_complaint ();
-          return;
+	  break;
         }
 
       macinfo_type = read_1_byte (abfd, mac_ptr);
@@ -9993,7 +10009,81 @@ dwarf_decode_macros (struct line_header 
           /* A zero macinfo type indicates the end of the macro
              information.  */
         case 0:
-          return;
+	  break;
+
+	case DW_MACINFO_define:
+	case DW_MACINFO_undef:
+	  /* Only skip the data by MAC_PTR.  */
+	  {
+	    unsigned int bytes_read;
+
+	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	    read_string (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	  }
+	  break;
+
+	case DW_MACINFO_start_file:
+	  {
+	    unsigned int bytes_read;
+	    int line, file;
+
+	    line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	    file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+
+	    current_file = macro_start_file (file, line, current_file, comp_dir,
+					     lh, cu->objfile);
+	  }
+	  break;
+
+	case DW_MACINFO_end_file:
+	  /* No data to skip by MAC_PTR.  */
+	  break;
+
+	case DW_MACINFO_vendor_ext:
+	  /* Only skip the data by MAC_PTR.  */
+	  {
+	    unsigned int bytes_read;
+
+	    read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	    read_string (abfd, mac_ptr, &bytes_read);
+	    mac_ptr += bytes_read;
+	  }
+	  break;
+
+	default:
+	  break;
+	}
+    } while (macinfo_type != 0 && current_file == NULL);
+
+  /* Here is the second pass to read in the macros starting from the ones
+     defined at the command line.  */
+
+  mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
+  at_commandline = 1;
+
+  do
+    {
+      /* Do we at least have room for a macinfo type byte?  */
+      if (mac_ptr >= mac_end)
+	{
+	  /* Complaint is in the first pass above.  */
+	  break;
+	}
+
+      macinfo_type = read_1_byte (abfd, mac_ptr);
+      mac_ptr++;
+
+      switch (macinfo_type)
+	{
+	  /* A zero macinfo type indicates the end of the macro
+	     information.  */
+	case 0:
+	  break;
 
         case DW_MACINFO_define:
         case DW_MACINFO_undef:
@@ -10008,19 +10098,31 @@ dwarf_decode_macros (struct line_header 
             mac_ptr += bytes_read;
 
             if (! current_file)
+	      {
+		/* DWARF violation as no main source is present.  */
+		complaint (&symfile_complaints,
+			   _("debug info with no main source gives macro %s "
+			     "on line %d: %s"),
+			   macinfo_type ==
+			   DW_MACINFO_define ? _("definition") : macinfo_type ==
+			   DW_MACINFO_undef ? _("undefinition") :
+			   "something-or-other", line, body);
+		break;
+	      }
+	    if (at_commandline != (line == 0))
 	      complaint (&symfile_complaints,
-			 _("debug info gives macro %s outside of any file: %s"),
+			 _("debug info gives %s macro %s with %s line %d: %s"),
+			 at_commandline ? _("command-line") : _("in-file"),
 			 macinfo_type ==
-			 DW_MACINFO_define ? "definition" : macinfo_type ==
-			 DW_MACINFO_undef ? "undefinition" :
-			 "something-or-other", body);
-            else
-              {
-                if (macinfo_type == DW_MACINFO_define)
-                  parse_macro_definition (current_file, line, body);
-                else if (macinfo_type == DW_MACINFO_undef)
-                  macro_undef (current_file, line, body);
-              }
+			 DW_MACINFO_define ? _("definition") : macinfo_type ==
+			 DW_MACINFO_undef ? _("undefinition") :
+			 "something-or-other",
+			 line == 0 ? _("zero") : _("non-zero"), line, body);
+
+	    if (macinfo_type == DW_MACINFO_define)
+	      parse_macro_definition (current_file, line, body);
+	    else if (macinfo_type == DW_MACINFO_undef)
+	      macro_undef (current_file, line, body);
           }
           break;
 
@@ -10034,9 +10136,22 @@ dwarf_decode_macros (struct line_header 
             file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
             mac_ptr += bytes_read;
 
-            current_file = macro_start_file (file, line,
-                                             current_file, comp_dir,
-                                             lh, cu->objfile);
+	    if (at_commandline != (line == 0))
+	      complaint (&symfile_complaints,
+			 _("debug info gives source %d included "
+			   "from %s at %s line %d"),
+			 file, at_commandline ? _("command-line") : _("file"),
+			 line == 0 ? _("zero") : _("non-zero"), line);
+
+	    if (at_commandline)
+	      {
+		/* This DW_MACINFO_start_file was executed in the pass one.  */
+		at_commandline = 0;
+	      }
+	    else
+	      current_file = macro_start_file (file, line,
+					       current_file, comp_dir,
+					       lh, cu->objfile);
           }
           break;
 
@@ -10090,7 +10205,7 @@ dwarf_decode_macros (struct line_header 
           }
           break;
         }
-    }
+    } while (macinfo_type != 0);
 }
 
 /* Check if the attribute's form is a DW_FORM_block*
--- gdb/testsuite/gdb.base/macscp.exp	18 Feb 2009 22:24:37 -0000	1.20
+++ gdb/testsuite/gdb.base/macscp.exp	19 Feb 2009 21:05:11 -0000
@@ -26,13 +26,21 @@ set testfile "macscp"
 set objfile ${objdir}/${subdir}/${testfile}.o
 set binfile ${objdir}/${subdir}/${testfile}
 
-set options { debug }
+set options { debug additional_flags=-DFROM_COMMANDLINE=ARG}
 
 get_compiler_info ${binfile}
 if [test_compiler_info gcc*] {
     lappend options additional_flags=-g3
 }
 
+# Workaround ccache making lineno non-zero for command-line definitions.
+if {[find_gcc] == "gcc" && [file executable "/usr/bin/gcc"]} {
+    set result [catch "exec which gcc" output]
+    if {$result == 0 && [string first "/ccache/" $output] >= -1} {
+	lappend options "compiler=/usr/bin/gcc"
+    }
+}
+
 # Generate the intermediate object file.  This is required by Darwin to
 # have access to the .debug_macinfo section.
 if  {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \
@@ -79,11 +87,15 @@ proc info_macro {macro} {
 
     if {$debug_me} {exp_internal 1}
     gdb_expect {
-        -re "Defined at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+        -re "Defined at \[^\r\n\]*(${filepat}):(${decimal})\[\r\n\]" {
             # `location' and `definition' should be empty when we see
             # this message.
             if {[llength $location] == 0 && [llength $definition] == 0} {
                 set location $expect_out(1,string)
+		# Definitions from gcc command-line get suffixed by the lineno.
+		if {$expect_out(2,string) == "0" } {
+		    set location "$location:$expect_out(2,string)"
+		}
                 exp_continue
             } else {
                 # Exit this expect loop, with a result indicating failure.
@@ -198,6 +210,8 @@ proc list_and_check_macro {func macro ex
 }
 
 
+list_and_check_macro main FROM_COMMANDLINE "macscp1.c:0 ARG"
+
 if {[list_and_check_macro main WHERE {macscp1.c {before macscp1_3}}]} {
     return 0
 }


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