Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Aleksandar Ristovski <ARistovski@qnx.com>
To: Daniel Jacobowitz <drow@false.org>
Cc: gdb@sourceware.org, Ryan Mansfield <RMansfield@qnx.com>
Subject: RE: gdb_realpath: dealing with ./ and ../
Date: Fri, 04 Jan 2008 17:04:00 -0000	[thread overview]
Message-ID: <2F6320727174C448A52CEB63D85D11F40A4A@nova.ott.qnx.com> (raw)

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

> On Thu, Jan 03, 2008 at 01:25:55PM -0500, Aleksandar Ristovski wrote:
> > 1. Problem one - relative NAME and absolute subfile->name case not
> covered:
> 
> I think you're right, but I can't tell for sure.

I am pretty sure this is real problem as this is what I am seeing with our
case (the instrumentation I posted proves it). This is easy and I think
straight forward to fix. (please see the attachement buildsym.c.patch1).

BUT...
This does not solve all my problems. In fact, when debugging on linux a
binary cross-compiled on windows, it won't work:

IS_ABSOLUTE_PATH macro will differ depending on the configured gdb host. The
problem with this is when one is debugging binary cross-compiled on windows,
on a unix host, IS_ABSOLUTE_PATH will return 0 on "C:.." style paths which
is not correct. Looking at the code, in many places we concatenate directory
and file name if IS_ABSOLUTE_PATH returns zero so in case of cross-compiled
binary I suspect there will be many issues.

> 
> > 2. Problem two - one physical file is specified with two pathnames.
> 
> The specific case that's important here is associating the main file
> from a dwarf2 CU DIE with the right lines from .debug_line.  When we
> go to create that subfile we haven't created the other subfiles yet.
> So what we need, I think, is to handle this in dwarf2read.c by walking
> through the filename / directory table.

dwarf2read.c calls start_subfile or start_symtab which in turn calls
start_subfile. I think we should let our readers deal with "compiled" paths
(i.e. as found in the binary), without conversion. In start_subfile,
however, we can do something with paths. Currently, we do not try to
substitute-path on paths coming from the binary, even though they are
clearly our source paths and should be dealt with the same as with any other
source path. 

My attempt would be patch2 attached (start_subfile.patch). Please take a
look. This should solve both problems.

Note: IS_ABSOLUTE_PATH issue will still exist since we deal with compiled
paths throughout gdb code. Wherever IS_ABSOLUTE_PATH is used on a windows
style path (and gdb was configured for *ix) it will return 0 leading to
problems.

Note2: for some reason, my post to gdb-patches didn't go through even after
two attempts. There I submitted only source.c change dealing with rewriting
source path in case when NAME is an absolute path and at the same time
DIRNAME is not NULL (which can happen).
 

Aleksandar Ristovski
QNX Software Systems


[-- Attachment #2: buildsym.c.patch1 --]
[-- Type: application/octet-stream, Size: 1745 bytes --]

Index: gdb/buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.59
diff -u -3 -p -r1.59 buildsym.c
--- gdb/buildsym.c	1 Jan 2008 22:53:09 -0000	1.59
+++ gdb/buildsym.c	4 Jan 2008 14:41:44 -0000
@@ -583,6 +583,13 @@ void
 start_subfile (char *name, char *dirname)
 {
   struct subfile *subfile;
+  char *absname; /* Absolute NAME.  */
+
+  if (!IS_ABSOLUTE_PATH (name) 
+      && dirname != NULL)
+    absname = concat (dirname, SLASH_STRING, name, NULL);
+  else
+    absname = name;
 
   /* See if this subfile is already known as a subfile of the current
      main source file.  */
@@ -590,6 +597,7 @@ start_subfile (char *name, char *dirname
   for (subfile = subfiles; subfile; subfile = subfile->next)
     {
       char *subfile_name;
+      char *aname;
 
       /* If NAME is an absolute path, and this subfile is not, then
 	 attempt to create an absolute path to compare.  */
@@ -601,7 +609,13 @@ start_subfile (char *name, char *dirname
       else
 	subfile_name = subfile->name;
 
-      if (FILENAME_CMP (subfile_name, name) == 0)
+      if (!IS_ABSOLUTE_PATH (name)
+	  && IS_ABSOLUTE_PATH (subfile->name))
+	aname = absname;
+      else
+	aname = name;
+
+      if (FILENAME_CMP (subfile_name, aname) == 0)
 	{
 	  current_subfile = subfile;
 	  if (subfile_name != subfile->name)
@@ -612,6 +626,9 @@ start_subfile (char *name, char *dirname
 	xfree (subfile_name);
     }
 
+  if (absname != name)
+    xfree (absname);
+
   /* This subfile is not known.  Add an entry for it. Make an entry
      for this subfile in the list of all subfiles of the current main
      source file.  */

[-- Attachment #3: start_subfile.patch --]
[-- Type: application/octet-stream, Size: 5970 bytes --]

Index: gdb/buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.59
diff -u -3 -p -r1.59 buildsym.c
--- gdb/buildsym.c	1 Jan 2008 22:53:09 -0000	1.59
+++ gdb/buildsym.c	4 Jan 2008 16:28:40 -0000
@@ -44,6 +44,7 @@
 #include "cp-support.h"
 #include "dictionary.h"
 #include "addrmap.h"
+#include "source.h"
 
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define	EXTERN
@@ -574,15 +575,57 @@ make_blockvector (struct objfile *objfil
   return (blockvector);
 }
 \f
+
+/* Workaround for IS_ABSOLUTE_PATH issue. When gdb is configured for
+   *ix, and we are debugging binary cross-compiled on windows, the original
+   IS_ABSOLUTE_PATH will always return 0. This is not good.  */
+#undef IS_ABSOLUTE_PATH
+#undef IS_DIR_SEPARATOR
+
+#define IS_DIR_SEPARATOR(c)	((c) == '/' || (c) == '\\')
+/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is
+   only semi-absolute.  This is because the users of IS_ABSOLUTE_PATH
+   want to know whether to prepend the current working directory to
+   a file name, which should not be done with a name like d:foo.  */
+#define IS_ABSOLUTE_PATH(f)	(IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':')))
+
 /* Start recording information about source code that came from an
    included (or otherwise merged-in) source file with a different
    name.  NAME is the name of the file (cannot be NULL), DIRNAME is
    the directory in which the file was compiled (or NULL if not known).  */
 
 void
-start_subfile (char *name, char *dirname)
+start_subfile (char *name, char *dirname) 
 {
   struct subfile *subfile;
+  char *absname; /* Rewritten absolute NAME.  */
+
+  if (IS_ABSOLUTE_PATH (name))
+    {
+      char *rwname;
+      rwname = rewrite_source_path (name);
+      if (rwname != NULL)
+	{
+	  make_cleanup (xfree, rwname);
+	  name = rwname;
+	}
+      absname = name;
+    }
+  else
+    {
+      if (dirname != NULL)
+	{
+	  char *rwdirname = rewrite_source_path (dirname);
+	  if (rwdirname == NULL)
+	    rwdirname = dirname;
+	  absname = concat (rwdirname, SLASH_STRING, name, NULL);
+	  if (rwdirname != dirname)
+	    xfree (rwdirname);
+	  make_cleanup (xfree, absname);
+	}
+      else
+	absname = name;
+    }
 
   /* See if this subfile is already known as a subfile of the current
      main source file.  */
@@ -590,18 +633,36 @@ start_subfile (char *name, char *dirname
   for (subfile = subfiles; subfile; subfile = subfile->next)
     {
       char *subfile_name;
+      char *aname;
 
       /* If NAME is an absolute path, and this subfile is not, then
 	 attempt to create an absolute path to compare.  */
       if (IS_ABSOLUTE_PATH (name)
 	  && !IS_ABSOLUTE_PATH (subfile->name)
 	  && subfile->dirname != NULL)
-	subfile_name = concat (subfile->dirname, SLASH_STRING,
+	{
+	  char *rwsubfile_dirname = rewrite_source_path (subfile->dirname);
+	  if (rwsubfile_dirname == NULL)
+	    rwsubfile_dirname = subfile->dirname;
+	  subfile_name = concat (rwsubfile_dirname, SLASH_STRING,
 			       subfile->name, NULL);
+	  if (rwsubfile_dirname != subfile->dirname)
+	    xfree (rwsubfile_dirname);
+	}
+      else
+	{
+	  subfile_name = rewrite_source_path (subfile->name);
+	  if (subfile_name == NULL)
+	    subfile_name = subfile->name;
+	}
+
+      if (!IS_ABSOLUTE_PATH (name)
+	  && IS_ABSOLUTE_PATH (subfile->name))
+	aname = absname;
       else
-	subfile_name = subfile->name;
+	aname = name;
 
-      if (FILENAME_CMP (subfile_name, name) == 0)
+      if (FILENAME_CMP (subfile_name, aname) == 0)
 	{
 	  current_subfile = subfile;
 	  if (subfile_name != subfile->name)
Index: gdb/source.c
===================================================================
RCS file: /cvs/src/src/gdb/source.c,v
retrieving revision 1.83
diff -u -3 -p -r1.83 source.c
--- gdb/source.c	1 Jan 2008 22:53:13 -0000	1.83
+++ gdb/source.c	4 Jan 2008 16:28:40 -0000
@@ -895,10 +895,12 @@ get_substitute_path_rule (const char *pa
    Return NULL if no substitution rule was specified by the user,
    or if no rule applied to the given PATH.  */
    
-static char *
+char *
 rewrite_source_path (const char *path)
 {
-  const struct substitute_path_rule *rule = get_substitute_path_rule (path);
+  const struct substitute_path_rule *rule = (path != NULL) ? 
+					get_substitute_path_rule (path):
+					NULL;
   char *new_path;
   int from_len;
   
@@ -999,10 +1001,11 @@ find_and_open_source (struct objfile *ob
 	  strcat (path + len, source_path + len + cdir_len);	/* After $cdir */
 	}
     }
-  else
+  
+  if (IS_ABSOLUTE_PATH (filename))
     {
-      /* If dirname is NULL, chances are the path is embedded in
-         the filename.  Try the source path substitution on it.  */
+      /* If filename is absolute path, try the source path 
+	 substitution on it.  */
       char *rewritten_filename = rewrite_source_path (filename);
 
       if (rewritten_filename != NULL)
Index: gdb/source.h
===================================================================
RCS file: /cvs/src/src/gdb/source.h,v
retrieving revision 1.9
diff -u -3 -p -r1.9 source.h
--- gdb/source.h	1 Jan 2008 22:53:13 -0000	1.9
+++ gdb/source.h	4 Jan 2008 16:28:40 -0000
@@ -66,4 +66,14 @@ extern struct symtab_and_line set_curren
 
 /* Reset any information stored about a default file and line to print. */
 extern void clear_current_source_symtab_and_line (void);
+
+/* If the user specified a source path substitution rule that applies
+   to PATH, then apply it and return the new path.  This new path must
+   be deallocated afterwards.  
+   
+   Return NULL if no substitution rule was specified by the user,
+   or if no rule applied to the given PATH.  */
+   
+extern char *rewrite_source_path (const char *path);
+
 #endif

             reply	other threads:[~2008-01-04 17:04 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-04 17:04 Aleksandar Ristovski [this message]
2008-01-04 17:42 ` Daniel Jacobowitz
2008-01-04 18:25   ` Joel Brobecker
2008-01-04 21:40 ` Doug Evans
2008-01-04 21:48   ` Daniel Jacobowitz
2008-01-04 22:23     ` Doug Evans
  -- strict thread matches above, loose matches on Subject: below --
2008-01-08 19:21 Aleksandar Ristovski
2008-01-08 16:12 Aleksandar Ristovski
2008-01-08 16:40 ` Mark Kettenis
2008-01-04 22:09 Aleksandar Ristovski
2008-01-04 20:16 Aleksandar Ristovski
2008-01-04 19:52 Aleksandar Ristovski
2008-01-04 20:30 ` Doug Evans
2008-01-03 18:30 Aleksandar Ristovski
2008-01-04 12:52 ` Daniel Jacobowitz
2008-01-03 17:07 Aleksandar Ristovski
2008-01-03 17:13 ` Daniel Jacobowitz
2008-01-07 14:33   ` Joel Brobecker
2008-01-07 17:00     ` Doug Evans
2008-01-08  5:46       ` Joel Brobecker
2008-01-08 19:54         ` Doug Evans
2008-01-03 16:39 Aleksandar Ristovski
2008-01-03 16:52 ` Daniel Jacobowitz
2008-01-03 15:25 Aleksandar Ristovski
2008-01-03 16:00 ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2F6320727174C448A52CEB63D85D11F40A4A@nova.ott.qnx.com \
    --to=aristovski@qnx.com \
    --cc=RMansfield@qnx.com \
    --cc=drow@false.org \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox