This is the mail archive of the gdb-patches@sources.redhat.com 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]

[rfa/dwarf] Fix a line table bug


I have a file whose line table looks like this (excerpted):

  Extended opcode 2: set Address to 0x10399b
  Advance Line by 405 to 406
  Copy
  ...
  Extended opcode 1: End of Sequence

  ...
  Special opcode 232: advance Address by 16 to 0x41bd9 and Line by 3 to 307
  Advance Line by -23 to 284
  Special opcode 201: advance Address by 14 to 0x41be7 and Line by 0 to 284
  Set File Name to entry 19 in the File Name Table
  Advance Line by 33 to 317
  Special opcode 75: advance Address by 5 to 0x41bec and Line by 0 to 317
  Set File Name to entry 1 in the File Name Table
  Advance Line by -27 to 290
  Advance PC by 37 to 41c11
  Copy

The highlights are that it covers two distinct address ranges, and that in
the lower range it has an include file with a line in it.  The line table
for the outer file looks OK.  For the include file, we get only one line
record - {line 317, pc 0x41bec}.

The problem comes when we try to find the line for an intermediate PC, say
0x60000, which does not have debug information.  We find this symtab as the
best match, because it's the smallest symtab including the desired address.
We look through the line table.  We fail to find a line in the main line
table, because it's got an appropriate End Of Sequence for this exact
reason.  We search the next symtab with the same blockvector, and we find a
match.

Conceptually, that series of lines ends at the next line in .debug_line,
here at 0x41c11.  If we fill in end-of-sequence markers every time we change
out of a subfile, then the right thing happens.  This seems like a logical
behavior to me.

OK?  I promise to write a test case once we figure out how to test bugs that
require specific dwarf2 input.

-- 
Daniel Jacobowitz

2004-09-23  Daniel Jacobowitz  <dan@debian.org>

	* dwarf2read.c (dwarf_decode_lines): When leaving a file, mark
	the end of the current line.

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.163
diff -u -p -r1.163 dwarf2read.c
--- dwarf2read.c	21 Sep 2004 15:04:41 -0000	1.163
+++ dwarf2read.c	22 Sep 2004 23:22:56 -0000
@@ -6274,6 +6274,7 @@ dwarf_decode_lines (struct line_header *
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->objfile;
   const int decode_for_pst_p = (pst != NULL);
+  struct subfile *last_subfile = NULL;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -6322,6 +6323,12 @@ dwarf_decode_lines (struct line_header *
               lh->file_names[file - 1].included_p = 1;
               if (!decode_for_pst_p)
                 {
+		  if (last_subfile != current_subfile)
+		    {
+		      if (last_subfile)
+			record_line (last_subfile, 0, address);
+		      last_subfile = current_subfile;
+		    }
 	          /* append row to matrix using current values */
 	          record_line (current_subfile, line, 
 	                       check_cu_functions (address, cu));
@@ -6376,8 +6383,16 @@ dwarf_decode_lines (struct line_header *
 	    case DW_LNS_copy:
               lh->file_names[file - 1].included_p = 1;
               if (!decode_for_pst_p)
-	        record_line (current_subfile, line, 
-	                     check_cu_functions (address, cu));
+		{
+		  if (last_subfile != current_subfile)
+		    {
+		      if (last_subfile)
+			record_line (last_subfile, 0, address);
+		      last_subfile = current_subfile;
+		    }
+		  record_line (current_subfile, line, 
+			       check_cu_functions (address, cu));
+		}
 	      basic_block = 0;
 	      break;
 	    case DW_LNS_advance_pc:
@@ -6404,7 +6419,10 @@ dwarf_decode_lines (struct line_header *
                 else
                   dir = comp_dir;
                 if (!decode_for_pst_p)
-                  dwarf2_start_subfile (fe->name, dir);
+		  {
+		    last_subfile = current_subfile;
+		    dwarf2_start_subfile (fe->name, dir);
+		  }
               }
 	      break;
 	    case DW_LNS_set_column:


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