public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* libbacktrace patch committed: Handle missing line number entry
@ 2013-01-17  1:20 Ian Lance Taylor
  0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2013-01-17  1:20 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1291 bytes --]

It turns out that it is possible to construct debug info in which a
compilation unit has a low_pc and a high_pc, and a line number table,
but the line number table does not cover PC values from low_pc up to
some value.  For example, this will happen in an assembler file if you
use a .cfi_startproc with no preceding .loc, and then provide some
instructions, and then use a .loc later in the function before the
.cfi_endproc.

In this admittedly obscure case the backtrace library was returning an
error "inconsistent DWARF line number info."  Since the case can occur
in real files, this is inappropriate.  This patch fixes libbacktrace to
return the main compilation file, if available, with no associated
function or line number.

I have not added a test case because I don't know how to create one
without using assembler code.  I did write a test case myself and
verified that it fixed the problem on my system.

Bootstrapped and ran libbacktrace testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2013-01-16  Ian Lance Taylor  <iant@google.com>

	* dwarf.c (struct unit): Add filename and abs_filename fields.
	(build_address_map): Set new fields when reading unit.
	(dwarf_lookup_pc): If we don't find an entry in the line table,
	just return the main file name.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 3080 bytes --]

Index: dwarf.c
===================================================================
--- dwarf.c	(revision 195256)
+++ dwarf.c	(working copy)
@@ -283,8 +283,12 @@ struct unit
   int addrsize;
   /* Offset into line number information.  */
   off_t lineoff;
+  /* Primary source file.  */
+  const char *filename;
   /* Compilation command working directory.  */
   const char *comp_dir;
+  /* Absolute file name, only set if needed.  */
+  const char *abs_filename;
   /* The abbreviations for this unit.  */
   struct abbrevs abbrevs;
 
@@ -1288,6 +1292,7 @@ build_address_map (struct backtrace_stat
       int have_ranges;
       uint64_t lineoff;
       int have_lineoff;
+      const char *filename;
       const char *comp_dir;
 
       if (info.reported_underflow)
@@ -1346,6 +1351,7 @@ build_address_map (struct backtrace_stat
       have_ranges = 0;
       lineoff = 0;
       have_lineoff = 0;
+      filename = NULL;
       comp_dir = NULL;
       for (i = 0; i < abbrev->num_attrs; ++i)
 	{
@@ -1394,6 +1400,10 @@ build_address_map (struct backtrace_stat
 		  have_lineoff = 1;
 		}
 	      break;
+	    case DW_AT_name:
+	      if (val.encoding == ATTR_VAL_STRING)
+		filename = val.u.string;
+	      break;
 	    case DW_AT_comp_dir:
 	      if (val.encoding == ATTR_VAL_STRING)
 		comp_dir = val.u.string;
@@ -1421,7 +1431,9 @@ build_address_map (struct backtrace_stat
 	  u->version = version;
 	  u->is_dwarf64 = is_dwarf64;
 	  u->addrsize = addrsize;
+	  u->filename = filename;
 	  u->comp_dir = comp_dir;
+	  u->abs_filename = NULL;
 	  u->lineoff = lineoff;
 	  u->abbrevs = abbrevs;
 	  memset (&abbrevs, 0, sizeof abbrevs);
@@ -2701,8 +2713,45 @@ dwarf_lookup_pc (struct backtrace_state
 				sizeof (struct line), line_search);
   if (ln == NULL)
     {
-      error_callback (data, "inconsistent DWARF line number info", 0);
-      return 0;
+      /* The PC is between the low_pc and high_pc attributes of the
+	 compilation unit, but no entry in the line table covers it.
+	 This implies that the start of the compilation unit has no
+	 line number information.  */
+
+      if (entry->u->abs_filename == NULL)
+	{
+	  const char *filename;
+
+	  filename = entry->u->filename;
+	  if (filename != NULL
+	      && !IS_ABSOLUTE_PATH (filename)
+	      && entry->u->comp_dir != NULL)
+	    {
+	      size_t filename_len;
+	      const char *dir;
+	      size_t dir_len;
+	      char *s;
+
+	      filename_len = strlen (filename);
+	      dir = entry->u->comp_dir;
+	      dir_len = strlen (dir);
+	      s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
+					    error_callback, data);
+	      if (s == NULL)
+		{
+		  *found = 0;
+		  return 0;
+		}
+	      memcpy (s, dir, dir_len);
+	      /* FIXME: Should use backslash if DOS file system.  */
+	      s[dir_len] = '/';
+	      memcpy (s + dir_len + 1, filename, filename_len + 1);
+	      filename = s;
+	    }
+	  entry->u->abs_filename = filename;
+	}
+
+      return callback (data, pc, entry->u->abs_filename, 0, NULL);
     }
 
   /* Search for function name within this unit.  */

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

only message in thread, other threads:[~2013-01-17  1:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-17  1:20 libbacktrace patch committed: Handle missing line number entry Ian Lance Taylor

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).