public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Asm warrior <asmwarrior@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: gdb@sourceware.org
Subject: Re: setting a breakpoint on a dll, relative path or absolute path issue
Date: Tue, 14 Jun 2011 03:49:00 -0000	[thread overview]
Message-ID: <4DF6D94A.7080408@gmail.com> (raw)
In-Reply-To: <4DF6D123.6000201@gmail.com>

On 2011-6-14 11:10, Asm warrior wrote:
> On 2011-6-14 0:59, Eli Zaretskii wrote:
>>> Date: Mon, 13 Jun 2011 14:29:28 +0800
>>> > From: Asm warrior<asmwarrior@gmail.com>
>>> > CC: "John E. / TDM"<tdragon@tdragon.net>, Eli Zaretskii<eliz@gnu.org>,
>>> > jan.kratochvil@redhat.com,keiths@redhat.com
>>> >
>>> > When loop on the symbols. I found that at one loop, I get
>>> >
>>> > s->filename = "../../src/common/string.cpp"
>>> > s->dirname = "D:\code\wxWidgets-2.8.12\build\msw"
>>> >
>>> > But too badly, the result
>>> > s->fullname =
>>> > "D:\code\wxWidgets-2.8.12\build\msw/../../src/common/string.cpp"
>>> >
>>> > This is the reason about the issue, if the result is:
>>> > "D:\code\wxWidgets-2.8.12/src/common/string.cpp"
>>> > Then, this problem can be fixed.
>>> >
>>> > I'm not sure why gdb does not give a cannical filename, but still
>>> leaves
>>> > the "../../" in the result.
>> Because the function that canonicalizes the file name does not support
>> backslashes correctly?
>>
>
> By reading the gdb source, mostly in file: source.c and symtab.c
>
> I found that in the function:
>
> char *
> symtab_to_fullname (struct symtab *s)
> {
> int r;
>
> if (!s)
> return NULL;
>
> /* Don't check s->fullname here, the file could have been
> deleted/moved/..., look for it again. */
> r = find_and_open_source (s->filename, s->dirname, &s->fullname);
>
> if (r >= 0)
> {
> close (r);
> return s->fullname;
> }
>
> return NULL;
> }
>
> This function try to check if the file exists.
>
> The lucky thing is: The function call:
>
> open("D:\code\wxWidgets-2.8.12\build\msw/../../src/common/string.cpp") ;
>
> works OK.
>
> Though the file path is not satisfied by me, but it just satisfied by
> open() function, Yeah, the open() function can internally do a path
> canonization on its parameter, and gdb knows that this file exists and
> can be opened.
>
> As I know, GDB does not do a canonization on any returned file names. (I
> can't find any code snippet doing this kind of work).
>
> Well, the proposed method can be: (see below)
> char *
> symtab_to_fullname (struct symtab *s)
> {
> int r;
>
> if (!s)
> return NULL;
>
> /* Don't check s->fullname here, the file could have been
> deleted/moved/..., look for it again. */
> r = find_and_open_source (s->filename, s->dirname, &s->fullname);
>
> if (r >= 0)
> {
> close (r);
> *******
> DoSomePathCanonization(&s->fullname);
> *******
> return s->fullname;
> }
>
> return NULL;
> }
>
> This way, the returned string can be:
> "D:/code/wxWidgets-2.8.12/src/common/string.cpp"
>
> BTW:Did you thing that Any one would like to set a breakpoint by using
> name containing many "../../"?
>
> I can hardly think one would like to set a break point by entering this
> command:
>
> b "D:\code\wxWidgets-2.8.12\build\msw/../../src/common/string.cpp:165"
>
> I personally think this is too ugly.
>
> Any ideas?
>
> Asmwarrior
> ollydbg from codeblocks' forum
>

Ok, now I try to implement this, I found the is a function do the 
canonicalize filepath.

under gdb\utils.c

char *
gdb_realpath (const char *filename)
{
   /* Method 1: The system has a compile time upper bound on a filename
      path.  Use that and realpath() to canonicalize the name.  This is
      the most common case.  Note that, if there isn't a compile time
      upper bound, you want to avoid realpath() at all costs.  */
#if defined(HAVE_REALPATH)
   {
# if defined (PATH_MAX)
     char buf[PATH_MAX];
#  define USE_REALPATH
# elif defined (MAXPATHLEN)
     char buf[MAXPATHLEN];
#  define USE_REALPATH
# endif
# if defined (USE_REALPATH)
     const char *rp = realpath (filename, buf);

     if (rp == NULL)
       rp = filename;
     return xstrdup (rp);
# endif
   }
#endif /* HAVE_REALPATH */

   /* Method 2: The host system (i.e., GNU) has the function
      canonicalize_file_name() which malloc's a chunk of memory and
      returns that, use that.  */
#if defined(HAVE_CANONICALIZE_FILE_NAME)
   {
     char *rp = canonicalize_file_name (filename);

     if (rp == NULL)
       return xstrdup (filename);
     else
       return rp;
   }
#endif

   /* FIXME: cagney/2002-11-13:

      Method 2a: Use realpath() with a NULL buffer.  Some systems, due
      to the problems described in method 3, have modified their
      realpath() implementation so that it will allocate a buffer when
      NULL is passed in.  Before this can be used, though, some sort of
      configure time test would need to be added.  Otherwize the code
      will likely core dump.  */

   /* Method 3: Now we're getting desperate!  The system doesn't have a
      compile time buffer size and no alternative function.  Query the
      OS, using pathconf(), for the buffer limit.  Care is needed
      though, some systems do not limit PATH_MAX (return -1 for
      pathconf()) making it impossible to pass a correctly sized buffer
      to realpath() (it could always overflow).  On those systems, we
      skip this.  */
#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && 
defined(HAVE_ALLOCA)
   {
     /* Find out the max path size.  */
     long path_max = pathconf ("/", _PC_PATH_MAX);

     if (path_max > 0)
       {
	/* PATH_MAX is bounded.  */
	char *buf = alloca (path_max);
	char *rp = realpath (filename, buf);

	return xstrdup (rp ? rp : filename);
       }
   }
#endif

   /* This system is a lost cause, just dup the buffer.  */
   return xstrdup (filename);
}


But I found another function in:
gdb\libiberty\lrealpath.c

char *
lrealpath (const char *filename)
{
   /* Method 1: The system has a compile time upper bound on a filename
      path.  Use that and realpath() to canonicalize the name.  This is
      the most common case.  Note that, if there isn't a compile time
      upper bound, you want to avoid realpath() at all costs.  */
#if defined(REALPATH_LIMIT)
   {
     char buf[REALPATH_LIMIT];
     const char *rp = realpath (filename, buf);
     if (rp == NULL)
       rp = filename;
     return strdup (rp);
   }
#endif /* REALPATH_LIMIT */

   /* Method 2: The host system (i.e., GNU) has the function
      canonicalize_file_name() which malloc's a chunk of memory and
      returns that, use that.  */
#if defined(HAVE_CANONICALIZE_FILE_NAME)
   {
     char *rp = canonicalize_file_name (filename);
     if (rp == NULL)
       return strdup (filename);
     else
       return rp;
   }
#endif

   /* Method 3: Now we're getting desperate!  The system doesn't have a
      compile time buffer size and no alternative function.  Query the
      OS, using pathconf(), for the buffer limit.  Care is needed
      though, some systems do not limit PATH_MAX (return -1 for
      pathconf()) making it impossible to pass a correctly sized buffer
      to realpath() (it could always overflow).  On those systems, we
      skip this.  */
#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H)
   {
     /* Find out the max path size.  */
     long path_max = pathconf ("/", _PC_PATH_MAX);
     if (path_max > 0)
       {
	/* PATH_MAX is bounded.  */
	char *buf, *rp, *ret;
	buf = (char *) malloc (path_max);
	if (buf == NULL)
	  return NULL;
	rp = realpath (filename, buf);
	ret = strdup (rp ? rp : filename);
	free (buf);
	return ret;
       }
   }
#endif

   /* The MS Windows method.  If we don't have realpath, we assume we
      don't have symlinks and just canonicalize to a Windows absolute
      path.  GetFullPath converts ../ and ./ in relative paths to
      absolute paths, filling in current drive if one is not given
      or using the current directory of a specified drive (eg, "E:foo").
      It also converts all forward slashes to back slashes.  */
#if defined (_WIN32)
   {
     char buf[MAX_PATH];
     char* basename;
     DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename);
     if (len == 0 || len > MAX_PATH - 1)
       return strdup (filename);
     else
       {
	/* The file system is case-preserving but case-insensitive,
	   Canonicalize to lowercase, using the codepage associated
	   with the process locale.  */
         CharLowerBuff (buf, len);
         return strdup (buf);
       }
   }
#endif

   /* This system is a lost cause, just duplicate the filename.  */
   return strdup (filename);
}

-------------------------------------------------------

Did you think we should add the "MS Windows method." in 
gdb\libiberty\lrealpath.c to the char * gdb_realpath (const char 
*filename) function body?

As currently, it just do a strdup(filename) under MinGW32 (Windows).


asmwarrior
ollydbg from codeblocks' forum




  reply	other threads:[~2011-06-14  3:49 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-11  7:49 asmwarrior
2011-06-11 17:56 ` Keith Seitz
2011-06-12  3:56   ` asmwarrior
2011-06-12  7:45     ` asmwarrior
2011-06-12  7:56       ` Jan Kratochvil
2011-06-12  8:06         ` asmwarrior
2011-06-12 16:22           ` [Mingw-users] " Earnie
2011-06-12 16:51         ` Eli Zaretskii
2011-06-12 16:54           ` Jan Kratochvil
     [not found] ` <4DF37ADA.3070905@users.sourceforge.net>
2011-06-12  8:15   ` asmwarrior
     [not found]   ` <4DF4513A.3090902__7466.60719528354$1307866544$gmane$org@gmail.com>
2011-06-13  6:33     ` Asm warrior
2011-06-13 17:02       ` Eli Zaretskii
2011-06-14  3:14         ` Asm warrior
2011-06-14  3:49           ` Asm warrior [this message]
2011-06-14  4:22             ` Jeffrey Walton
2011-06-14  5:27         ` setting a breakpoint on a dll, relative path or absolute path issue[solved with a patch] asmwarrior

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=4DF6D94A.7080408@gmail.com \
    --to=asmwarrior@gmail.com \
    --cc=eliz@gnu.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).