From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3846 invoked by alias); 19 Mar 2002 17:56:19 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 3485 invoked from network); 19 Mar 2002 17:56:14 -0000 Received: from unknown (HELO dublin.ACT-Europe.FR) (212.157.227.154) by sources.redhat.com with SMTP; 19 Mar 2002 17:56:14 -0000 Received: from berlin.ACT-Europe.FR (berlin.int.act-europe.fr [10.10.0.169]) by dublin.ACT-Europe.FR (Postfix) with ESMTP id 67807229FFF; Tue, 19 Mar 2002 18:56:13 +0100 (MET) Received: by berlin.ACT-Europe.FR (Postfix, from userid 507) id B2AD8969; Tue, 19 Mar 2002 18:56:11 +0100 (CET) Date: Tue, 19 Mar 2002 09:56:00 -0000 From: Joel Brobecker To: Eli Zaretskii , gdb-patches@sources.redhat.com Subject: Re: [RFC] gdb_realpath causes problems with GVD Message-ID: <20020319185611.A17568@act-europe.fr> References: <20020319171236.D6465@act-europe.fr> <20020319123357.A16236@nevyn.them.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="OgqxwSJOaUobr8KG" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20020319123357.A16236@nevyn.them.org>; from drow@mvista.com on Tue, Mar 19, 2002 at 12:33:57PM -0500 X-SW-Source: 2002-03/txt/msg00352.txt.bz2 --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1244 > I believe it will. We'll have a canonical name for each directory a > source file was built out of; if the source file was a link, well, it's > still the name we were given for the source file. Does that seem right > to you? To give an example, I used the following scenario: /build /toplevel /symlink toto.C toto.c -> toto.C /toplevel_link -> toplevel I then went inside /build and compiled toto.c using the following command: % gcc -g -o toto ../toplevel_link/symlinks/toto.c I then retried the same test with GDB (break into break_me and run until the bp is hit, to see the annotation): << (gdb) set annotate 1 (gdb) b break_me Breakpoint 1 at 0x804846b: file ../toplevel_link/symlinks/toto.c, line 4. (gdb) run Starting program: /bonn.a/brobecke/build/hello Breakpoint 1, break_me () at ../toplevel_link/symlinks/toto.c:4 yy/bonn.a/brobecke/toplevel/symlinks/toto.c:4:23:beg:0x804846b >> As you see, the directory name has been expanded, but not the filename. And I also have to appologize. I sent a wrong patch, which is missing one tiny line after the strncpy where I add a missing '\000'. I am attaching the correct one this time. -- Joel --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Description: utils.c.diff Content-Disposition: attachment; filename="utils.c.diff" Content-length: 4495 Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.70 diff -c -3 -p -r1.70 utils.c *** utils.c 2002/03/19 02:51:07 1.70 --- utils.c 2002/03/19 17:53:01 *************** string_to_core_addr (const char *my_stri *** 2531,2558 **** return addr; } - char * - gdb_realpath (const char *filename) - { #if defined(HAVE_REALPATH) # if defined (PATH_MAX) ! char buf[PATH_MAX]; # define USE_REALPATH # elif defined (MAXPATHLEN) ! char buf[MAXPATHLEN]; # define USE_REALPATH # elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) ! char *buf = alloca ((size_t)pathconf ("/", _PC_PATH_MAX)); # define USE_REALPATH # endif #endif /* HAVE_REALPATH */ ! #if defined(USE_REALPATH) ! char *rp = realpath (filename, buf); ! return xstrdup (rp ? rp : filename); ! #elif defined(HAVE_CANONICALIZE_FILE_NAME) ! return canonicalize_file_name (filename); #else return xstrdup (filename); #endif } --- 2531,2641 ---- return addr; } #if defined(HAVE_REALPATH) # if defined (PATH_MAX) ! static const int max_rp_buffer_size = PATH_MAX; # define USE_REALPATH # elif defined (MAXPATHLEN) ! static const int max_rp_buffer_size = MAXPATHLEN; # define USE_REALPATH # elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) ! static const int max_rp_buffer_size = pathconf ("/", _PC_PATH_MAX); # define USE_REALPATH # endif #endif /* HAVE_REALPATH */ + + /* + * gdb_canonicalize_path + * + * Sets RESOLVED_PATH to the canonicalized form of FILENAME, as realpath () + * does. If there is no error, it returns a pointer to the resolved path. + * Otherwise, returns null. + * + * Returns null on platforms where no canonicalization routine (such as + * realpath for instance) are available. + */ + static char * + gdb_canonicalize_path (const char *path, char *resolved_path) + { + #if defined (USE_REALPATH) + return realpath (path, resolved_path); + + #elif defined (HAVE_CANONICALIZE_FILE_NAME) + const char *canonicalized = canonicalize_file_name (path); + + if (!canonicalized) + return null; ! strcpy (resolved_path, canonicalized); ! return resolved_path; ! #else + return null; + + #endif + } + + /* + * gdb_realpath_fallback + * + * This is the fallback version of gdb_realpath when there is no + * canonicalization routine (such as realpath for instance) available. + * In this case, we simply return a copy of FILENAME. + */ + static char * + gdb_realpath_fallback (const char *filename) + { return xstrdup (filename); + } + + /* + * gdb_realpath + * + * Return a copy of FILENAME, with its directory prefix canonicalized, + * as for realpath() (see "man realpath" for more details on what + * this function does), or simply a copy of FILENAME on platforms + * where no canonicalization routine is available. + * + * We don't want to canonicalize the entire FILENAME, because + * the canonicalization routines used to perform the operation also + * expand symbolic links. If FILENAME is itself a link to another file, + * it can lead GDB to translate FILENAME into another filename that GDB + * does not know about. This can confuse graphical front-ends for GDB + * which, like GVD, rely on the filename displayed by GDB to get the + * current file:line location, for example. + */ + char * + gdb_realpath (const char *filename) + { + const char *base_name = lbasename (filename); + char *dir_name; + char *buf; + char *rp = NULL; + + #if !defined (USE_REALPATH) || !defined (HAVE_CANONICALIZE_FILE_NAME) + return gdb_realpath_fallback (filename); #endif + + /* If basename and filename are equal, then there is no path to + canonicalize. Just return a copy of filename */ + if (base_name == filename) + return xstrdup (filename); + + dir_name = alloca ((size_t) (base_name - filename + 1)); + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + + /* Allocate enough space to contain the largest path possible returned + by realpath, plus the SLASH_STRING and the base_name */ + buf = alloca ((size_t) max_rp_buffer_size + + strlen (SLASH_STRING) + strlen (base_name)); + rp = gdb_canonicalize_path (dir_name, buf); + + if (rp == NULL) + return xstrdup (filename); + + strcat (buf, SLASH_STRING); + strcat (buf, base_name); + return xstrdup (buf); } + --OgqxwSJOaUobr8KG--