From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 638 invoked by alias); 14 Jun 2011 03:49:08 -0000 Received: (qmail 629 invoked by uid 22791); 14 Jun 2011 03:49:07 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,TW_DB,TW_SM X-Spam-Check-By: sourceware.org Received: from mail-pw0-f41.google.com (HELO mail-pw0-f41.google.com) (209.85.160.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 14 Jun 2011 03:48:50 +0000 Received: by pwi12 with SMTP id 12so2900900pwi.0 for ; Mon, 13 Jun 2011 20:48:50 -0700 (PDT) Received: by 10.142.1.21 with SMTP id 21mr1004379wfa.430.1308023329898; Mon, 13 Jun 2011 20:48:49 -0700 (PDT) Received: from [210.32.139.52] ([210.32.139.52]) by mx.google.com with ESMTPS id t15sm6657744wfh.16.2011.06.13.20.48.46 (version=SSLv3 cipher=OTHER); Mon, 13 Jun 2011 20:48:48 -0700 (PDT) Message-ID: <4DF6D94A.7080408@gmail.com> Date: Tue, 14 Jun 2011 03:49:00 -0000 From: Asm warrior User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.19) Gecko/20081209 Thunderbird/2.0.0.19 Mnenhy/0.7.6.0 MIME-Version: 1.0 To: Eli Zaretskii CC: gdb@sourceware.org Subject: Re: setting a breakpoint on a dll, relative path or absolute path issue References: <4DF31EB0.6080006@gmail.com> <4DF37ADA.3070905@users.sourceforge.net> <4DF4513A.3090902__7466.60719528354$1307866544$gmane$org@gmail.com> <4DF5AE48.9050202@gmail.com> <83ips9acr7.fsf@gnu.org> <4DF6D123.6000201@gmail.com> In-Reply-To: <4DF6D123.6000201@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00100.txt.bz2 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 >>> > CC: "John E. / TDM", Eli Zaretskii, >>> > 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