This is the mail archive of the gdb@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]

Re: setting a breakpoint on a dll, relative path or absolute path issue


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





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