Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Patch: Handle relative paths in .debug_line
@ 2004-07-22 23:31 Bryce McKinlay
  2004-07-23 21:13 ` Jim Blandy
  0 siblings, 1 reply; 15+ messages in thread
From: Bryce McKinlay @ 2004-07-22 23:31 UTC (permalink / raw)
  To: gdb-patches

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

When debugging mainline gcc, GDB has a problem locating source for files 
which are only referenced from .debug_line. For example: debugging gcj, 
and trying to put a breakpoint on the parse.y file, I get the following:

Breakpoint 1, lookup_method_invoke (lc=1, cl=0xf6dee5f0, class=0xf6def244,
    name=0xf6dee550, arg_list=0xf6e574b0) at parse.y:10956
10956   parse.y: No such file or directory.
        in parse.y
(gdb) info source
Current source file is parse.y
Compilation directory is ../../gcc/java
Source language is c.
Compiled with unknown debugging format.
Does not include preprocessor macro info.

This is because the contents of the directory table in .debug_line can 
be paths relative to the DW_AT_comp_dir:


 The Directory Table:
  ../../gcc/java
  java
  /usr/include/bits
  .
  ../../gcc
  ../../gcc/../libcpp/include
  ../../gcc/config/i386
  ../../gcc/../include
  /local/gcc-clean/lib/gcc/i686-pc-linux-gnu/3.5.0/include
  /usr/include

 The File Name Table:
  Entry    Dir    Time    Size    Name
  1    1    0    0    keyword.h
  2    1    0    0    lex.c
  3    2    0    0    parse.c
  4    1    0    0    parse.y
... etc...

     DW_AT_comp_dir    : (indirect string, offset: 0x658c): 
/home/mckinlay/cvs/gcc-really-clean/build/gcc   

This patch fixes the problem by appending the path from the directory 
table, if it is not absolute already, to the DW_AT_comp_dir path when 
creating subfiles from the .debug_line info.

OK to commit?

Bryce



[-- Attachment #2: gdb-subfile-compdir.patch --]
[-- Type: text/x-patch, Size: 4315 bytes --]

2004-07-22  Bryce McKinlay  <mckinlay@redhat.com>

	* dwarf2read.c (dwarf_decode_lines): Pass comp_dir to
	dwarf2_start_subfile.
	(dwarf2_start_subfile): New comp_dir parameter.	Handle relative paths
	in .debug_line by appending them to comp_dir. Use make_cleanup to
	free strings used in directory concatenation.
	
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.156
diff -u -r1.156 dwarf2read.c
--- dwarf2read.c	6 Jul 2004 19:29:30 -0000	1.156
+++ dwarf2read.c	22 Jul 2004 23:07:41 -0000
@@ -762,7 +762,7 @@
 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 *);
@@ -5951,12 +5951,10 @@
 	     directory and file name numbers in the statement program
 	     are 1-based.  */
           struct file_entry *fe = &lh->file_names[file - 1];
-          char *dir;
+          char *dir = NULL;
           if (fe->dir_index)
             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. */
@@ -6044,17 +6042,15 @@
                    but the directory and file name numbers in the
                    statement program are 1-based.  */
                 struct file_entry *fe;
-                char *dir;
+                char *dir = NULL;
                 file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                 line_ptr += bytes_read;
                 fe = &lh->file_names[file - 1];
                 fe->included_p = 1;
                 if (fe->dir_index)
                   dir = lh->include_dirs[fe->dir_index - 1];
-                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:
@@ -6112,7 +6108,8 @@
 
 /* Start a subfile for DWARF.  FILENAME is the name of the file and
    DIRNAME the name of the source directory which contains FILENAME
-   or NULL if not known.
+   or NULL if not known.  COMP_DIR is the value of DW_AT_comp_dir.  If
+   DIRNAME specifies a relative path, it is appended to COMP_DIR.
    This routine tries to keep line numbers from identical absolute and
    relative file names in a common subfile.
 
@@ -6131,28 +6128,44 @@
    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)
 {
+  char *fullname;
+  struct subfile *subfile;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+
+  /* If we have a relative dirname, append comp_dir to it.  */
+  if (dirname != NULL && !IS_ABSOLUTE_PATH (dirname))
+    {
+      dirname = concat (comp_dir, "/", dirname, NULL);
+      make_cleanup (xfree, dirname);
+    }
+  else if (dirname == NULL)
+    dirname = comp_dir;
+
   /* If the filename isn't absolute, try to match an existing subfile
      with the full pathname.  */
 
-  if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
+  if (!IS_ABSOLUTE_PATH (filename))
     {
-      struct subfile *subfile;
-      char *fullname = concat (dirname, "/", filename, NULL);
+      fullname = concat (dirname, "/", filename, NULL);
+      make_cleanup (xfree, fullname);
+    }
+  else
+    fullname = filename;
 
-      for (subfile = subfiles; subfile; subfile = subfile->next)
+  for (subfile = subfiles; subfile; subfile = subfile->next)
+    {
+      if (FILENAME_CMP (subfile->name, fullname) == 0)
 	{
-	  if (FILENAME_CMP (subfile->name, fullname) == 0)
-	    {
-	      current_subfile = subfile;
-	      xfree (fullname);
-	      return;
-	    }
+	  current_subfile = subfile;
+	  do_cleanups (back_to);
+	  return;
 	}
-      xfree (fullname);
     }
+
   start_subfile (filename, dirname);
+  do_cleanups (back_to);
 }
 
 static void

^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: Patch: Handle relative paths in .debug_line
@ 2004-09-30  0:40 Garrison
  2004-09-30  0:49 ` Garrison
  0 siblings, 1 reply; 15+ messages in thread
From: Garrison @ 2004-09-30  0:40 UTC (permalink / raw)
  To: jimb; +Cc: cagney, gdb-patches

Hi!

I've taken a look at dwarf standard, and I have a question (possibly
already answered elsewhere): it is specified that relative paths in list
are related to compilation directory, so why not make the substitution
while parsing the list? If it's OK please take a look at attached patch
(sorry if it wraps this time). It's against current CVS HEAD.

I'm not sure I got those make_cleanup() calls right, if so please correct
me.

--- dwarf2read.c.original       2004-09-27 23:28:12.000000000 +0400
+++ dwarf2read.c        2004-09-30 04:05:52.999436680 +0400
@@ -822,7 +822,7 @@

  static struct line_header *(dwarf_decode_line_header
                              (unsigned int offset,
-                             bfd *abfd, struct dwarf2_cu *cu));
+                             bfd *abfd, struct dwarf2_cu *cu, const char* comp_dir));

  static void dwarf_decode_lines (struct line_header *, char *, bfd *,
                                 struct dwarf2_cu *, struct partial_symtab *);
@@ -1359,7 +1359,7 @@
    bfd *abfd = objfile->obfd;
    struct line_header *lh;

-  lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu);
+  lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu, pst->dirname);
    if (lh == NULL)
      return;  /* No linetable, so no includes.  */

@@ -2652,7 +2652,7 @@
    if (attr)
      {
        unsigned int line_offset = DW_UNSND (attr);
-      line_header = dwarf_decode_line_header (line_offset, abfd, cu);
+      line_header = dwarf_decode_line_header (line_offset, abfd, cu, comp_dir);
        if (line_header)
          {
            make_cleanup ((make_cleanup_ftype *) free_line_header,
@@ -6013,6 +6013,23 @@
      return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
  }

+/* Create full path name from absolute and relative parts.
+   The result string should be freed by caller when necessary. */
+static char*
+make_full_path (const char *full_part, const char *rel_part)
+{
+  char *result;
+
+  int dir_len = strlen(full_part);
+
+  result = xmalloc(dir_len + 1 + strlen(rel_part) + 1);
+  strcpy (result, full_part);
+  result[dir_len] = '/';
+  strcpy (result + dir_len + 1, rel_part);
+
+  return result;
+}
+
  /* Free the line_header structure *LH, and any arrays and strings it
     refers to.  */
  static void
@@ -6026,18 +6043,19 @@
    if (lh->file_names)
      xfree (lh->file_names);

-  /* Similarly for the include directory names.  */
+  /* Similarly for the include directory names - they will be freed independently.  */
    if (lh->include_dirs)
      xfree (lh->include_dirs);

    xfree (lh);
  }

-
  /* Add an entry to LH's include directory table.  */
  static void
-add_include_dir (struct line_header *lh, char *include_dir)
+add_include_dir (struct line_header *lh, char *include_dir, const char *comp_dir)
  {
+  char* real_dir;
+
    /* Grow the array if necessary.  */
    if (lh->include_dirs_size == 0)
      {
@@ -6053,9 +6071,19 @@
                                      * sizeof (*lh->include_dirs)));
      }

-  lh->include_dirs[lh->num_include_dirs++] = include_dir;
+  if (!IS_ABSOLUTE_PATH(include_dir) && comp_dir != NULL)
+    {
+      real_dir = make_full_path(comp_dir, include_dir);
+      make_cleanup(xfree, real_dir);
+    }
+  else
+    {
+      real_dir = include_dir;
+    }
+
+  lh->include_dirs[lh->num_include_dirs++] = real_dir;
  }
-
+

  /* Add an entry to LH's file name table.  */
  static void
@@ -6100,7 +6128,7 @@
     freed.  */
  static struct line_header *
  dwarf_decode_line_header (unsigned int offset, bfd *abfd,
-                         struct dwarf2_cu *cu)
+                         struct dwarf2_cu *cu, const char* comp_dir)
  {
    struct cleanup *back_to;
    struct line_header *lh;
@@ -6168,7 +6196,7 @@
    while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
      {
        line_ptr += bytes_read;
-      add_include_dir (lh, cur_dir);
+      add_include_dir (lh, cur_dir, comp_dir);
      }
    line_ptr += bytes_read;

@@ -8669,12 +8697,7 @@

        if (dir)
          {
-          dir_len = strlen (dir);
-          full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
-          strcpy (full_name, dir);
-          full_name[dir_len] = '/';
-          strcpy (full_name + dir_len + 1, fe->name);
-          return full_name;
+          return make_full_path(dir, fe->name);
          }
        else
          return xstrdup (fe->name);
-----------
Kind regards,
Igor V. Kovalenko


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2004-10-01 18:23 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-22 23:31 Patch: Handle relative paths in .debug_line Bryce McKinlay
2004-07-23 21:13 ` Jim Blandy
2004-07-23 23:54   ` Bryce McKinlay
2004-07-29 20:19     ` Jim Blandy
2004-07-29 20:54       ` Bryce McKinlay
2004-07-31  4:16         ` Jim Blandy
2004-07-31 19:23           ` Bryce McKinlay
2004-07-31 20:51             ` Andrew Cagney
2004-08-01  0:24               ` Michael Chastain
2004-09-14 19:53           ` Andrew Cagney
2004-09-14 20:09             ` Bryce McKinlay
2004-09-24 19:12               ` Andrew Cagney
2004-09-30  0:40 Garrison
2004-09-30  0:49 ` Garrison
2004-10-01 18:23   ` Igor Kovalenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox