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]

[RFC] Don't loose compilation directory in Dwarf2 line-tables


Hello,

The handing of relative paths in GDB has already been discussed (see
http://sourceware.org/ml/gdb-patches/2005-10/msg00039.html for the
latest thread). I don't believe there has been an agreement on a
solution.
I'd like to propose a little modification that makes things work for me
in the Dwarf2 case.
In fact, my starting point wasn't the general issue of relative paths,
but I saw GDB unable to find the include files of a program structured
like that:

 /project/
        include/
               header.h
        src/
           main.c  /* Includes header.h */
        main.o
        myprog

If GDB isn't launched from the root of the build tree, it is unable to
find header.h, whereas it can find main.c from anywhere. In the dwarf2
debug info, we get:

   DW_AT_name:          src/main.c
   DW_AT_comp_dir:      /project/
   files.files[0].name: header.h
   files.files[0].dir:  include/
   files.files[1].name: main.c
   files.files[1].dir:  src/

So if the build-tree stays at the same place, the debugger has all the
information available to be able to locate header.h, wherever the binary
really is and whatever $cwd is.

The main symtab will be built using DW_AT_name and DW_AT_comp_dir.
That's why GDB can find the main.c sourcefile without trouble. The
symtab for the header.h file is built using the line info dirname and
the line info filename. Which means it looses the comp_dir information.
I believe that the information in the line-tables related to a Dwarf2
compilation unit should be interpreted relatively to the compilation
unit comp_dir.

The attached patch implements something like that. When the line
information doesn't reference an absolute file, it uses comp_dir as the
subfile directory and concat(file.dir, "/", file.name) as filename.
If the build tree hasn't moved, then we've got all the information to
find the sources. If comp_dir doesn't exist anymore, then
find_and_open_source will basically do the same thing as with the old
information (it will split the basename if it can't find the full name).
I think that this also has the nice side-effect of making relative
include paths working with the 'dir' command as the full relative path
will get tested against each directory.
Note that the include psymtab building code a in dwarf_decode_lines does
a similar thing.
This seems also more consistent with find_and_open_source where $cdir
will get replaced by what we put in the symtab's dirname (implying that
we should always put the comp_dir in a symtab's dirname).

I've regression tested it on i686-pc-linux-gnu with gcc4.0. I wonder if
this could break things in some cases, maybe with other compilers than
GCC. Comments ?

Regards,
Fred.

--- dwarf2read.c.orig	2006-04-13 11:17:40.000000000 +0200
+++ dwarf2read.c	2006-04-13 11:25:48.000000000 +0200
@@ -846,7 +846,7 @@ static struct line_header *(dwarf_decode
 static void dwarf_decode_lines (struct line_header *, char *, bfd *,
 				struct dwarf2_cu *, struct partial_symtab *);
 
-static void dwarf2_start_subfile (char *, char *);
+static void dwarf2_start_subfile (char *, char *, char *);
 
 static struct symbol *new_symbol (struct die_info *, struct type *,
 				  struct dwarf2_cu *);
@@ -6535,7 +6535,7 @@ dwarf_decode_lines (struct line_header *
             dir = lh->include_dirs[fe->dir_index - 1];
           else
             dir = comp_dir;
-	  dwarf2_start_subfile (fe->name, dir);
+	  dwarf2_start_subfile (fe->name, dir, comp_dir);
 	}
 
       /* Decode the table.  */
@@ -6637,7 +6637,7 @@ dwarf_decode_lines (struct line_header *
                 else
                   dir = comp_dir;
                 if (!decode_for_pst_p)
-                  dwarf2_start_subfile (fe->name, dir);
+                  dwarf2_start_subfile (fe->name, dir, comp_dir);
               }
 	      break;
 	    case DW_LNS_set_column:
@@ -6736,7 +6736,7 @@ dwarf_decode_lines (struct line_header *
    subfile, so that `break /srcdir/list0.c:1' works as expected.  */
 
 static void
-dwarf2_start_subfile (char *filename, char *dirname)
+dwarf2_start_subfile (char *filename, char *dirname, char *comp_dir)
 {
   /* If the filename isn't absolute, try to match an existing subfile
      with the full pathname.  */
@@ -6744,7 +6744,7 @@ dwarf2_start_subfile (char *filename, ch
   if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
     {
       struct subfile *subfile;
-      char *fullname = concat (dirname, "/", filename, (char *)NULL);
+      char *fullname = concat (dirname, SLASH_STRING, filename, (char *)NULL);
 
       for (subfile = subfiles; subfile; subfile = subfile->next)
 	{
@@ -6755,9 +6755,20 @@ dwarf2_start_subfile (char *filename, ch
 	      return;
 	    }
 	}
+
+      /* Make sure we don't loose the compilation directory
+	 information. */
+      if (dirname != comp_dir) 
+	{
+	  filename = fullname;
+	  dirname = comp_dir;
+	}
+      
+      start_subfile (filename, dirname);
       xfree (fullname);
     }
-  start_subfile (filename, dirname);
+  else
+    start_subfile (filename, dirname);
 }
 
 static void

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