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: [patch] Correct `gcc -D' macros get ignored (PR 9873)


On Tue, 03 Mar 2009 01:54:30 +0100, Joel Brobecker wrote:
>   /* First pass: Find the name of the base filename.
>      This filename is needed in order to process all macros whose
>      definition (or undefinition) comes from the command line.
>      These macros are defined before the first DW_MACINFO_start_file
>      entry, and yet still need to be associated to base file.
> 
>      To determine the base file name, we scan the macro definitions
>      until we reach the first DW_MACINFO_start_file entry.  We then
>      initialize CURRENT_FILE accordingly so that any macro definition
>      found before the first DW_MACINFO_start_file can still be
>      associated to the base file.  */

Sure I find your text better although its first line does not follow the GNU
Coding Style directive `[...] please write complete sentences [...]'.
Used your text.


> | +  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;
> | +	}
> 
> Unfortunately, I'm not sure about the fact that the complaint has
> already been logged during the first pass. The first pass stops
> the scanning as soon as we have found our base file.

Thanks for the catch, fixed.


> | +	    if (at_commandline != (line == 0))
> 
> This is a little too smart for my aging brain :-). I'd rather have
> a clearer expression:
> 
>    if (line == 0 && !at_commandline)

OK although it was catching both inconsistencies so it has to be written as

  if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))


> |      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)"
> | +		}
> 
> Can you update the function documentation, please? Something like:
> 
>   If a macro was defined at the command-line level, ":0" will be
>   appended at the end of the filename where this macro is defined.
> 
> You may dump the comment that you added here, if you'd like.

As I moved the testcase part to:
  http://sourceware.org/ml/gdb-patches/2009-03/msg00104.html

and changed the format of the command-line defined macros rather used now
a simple `gdb_test' call and this `proc info_macro' change was thus dropped.


Thanks,
Jan


gdb/
2009-03-09  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/dwarf2read.c	12 Feb 2009 09:15:06 -0000	1.295
+++ gdb/dwarf2read.c	9 Mar 2009 00:52:01 -0000
@@ -9963,6 +9963,8 @@ 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;
+  int at_commandline;
 
   if (dwarf2_per_objfile->macinfo_buffer == NULL)
     {
@@ -9970,19 +9972,29 @@ dwarf_decode_macros (struct line_header 
       return;
     }
 
+  /* First pass: Find the name of the base filename.
+     This filename is needed in order to process all macros whose definition
+     (or undefinition) comes from the command line.  These macros are defined
+     before the first DW_MACINFO_start_file entry, and yet still need to be
+     associated to base file.
+
+     To determine the base file name, we scan the macro definitions until we
+     reach the first DW_MACINFO_start_file entry.  We then initialize
+     CURRENT_FILE accordingly so that any macro definition found before the
+     first DW_MACINFO_start_file can still be associated to the base file.  */
+
   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;
+	  /* Complaint is printed during the second pass as GDB will probably
+	     stop the first pass earlier upon finding DW_MACINFO_start_file.  */
+	  break;
         }
 
       macinfo_type = read_1_byte (abfd, mac_ptr);
@@ -9993,7 +10005,92 @@ 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);
+
+  /* Second pass: Process all entries.
+
+     Use the AT_COMMAND_LINE flag to determine whether we are still processing
+     command-line macro definitions/undefinitions.  This flag is unset when we
+     reach the first DW_MACINFO_start_file entry.  */
+
+  mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
+
+  /* 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.  */
+
+  at_commandline = 1;
+
+  do
+    {
+      /* Do we at least have room for a macinfo type byte?  */
+      if (mac_ptr >= mac_end)
+	{
+	  dwarf2_macros_too_long_complaint ();
+	  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 +10105,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 ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
 	      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 +10143,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 ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
+	      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 +10212,7 @@ dwarf_decode_macros (struct line_header 
           }
           break;
         }
-    }
+    } while (macinfo_type != 0);
 }
 
 /* Check if the attribute's form is a DW_FORM_block*


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