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
next prev parent 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).