From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4477 invoked by alias); 24 Mar 2015 15:11:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 4468 invoked by uid 89); 24 Mar 2015 15:11:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: usevmg20.ericsson.net Received: from usevmg20.ericsson.net (HELO usevmg20.ericsson.net) (198.24.6.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 24 Mar 2015 15:11:52 +0000 Received: from EUSAAHC005.ericsson.se (Unknown_Domain [147.117.188.87]) by usevmg20.ericsson.net (Symantec Mail Security) with SMTP id F4.B7.12456.AF821155; Tue, 24 Mar 2015 10:06:03 +0100 (CET) Received: from [142.133.110.95] (147.117.188.8) by smtp-am.internal.ericsson.com (147.117.188.89) with Microsoft SMTP Server id 14.3.210.2; Tue, 24 Mar 2015 11:11:49 -0400 Message-ID: <55117EB5.1060008@ericsson.com> Date: Tue, 24 Mar 2015 15:11:00 -0000 From: Antoine Tremblay User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Subject: Re: [PATCH 2/2] Fix source file not found when part of the path does not exist but that a canonicalized path exists. References: <1422994793-9861-1-git-send-email-antoine.tremblay@ericsson.com> <1422994793-9861-2-git-send-email-antoine.tremblay@ericsson.com> In-Reply-To: <1422994793-9861-2-git-send-email-antoine.tremblay@ericsson.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2015-03/txt/msg00793.txt.bz2 ping.. On 02/03/2015 03:19 PM, Antoine Tremblay wrote: > For example if you have an executable with debug symbols with a path that > looks like /build-server/program/build/../file.c and try to insert a > breakpoint by using the CLI "b /build-server/program/file.c" gdb would fail > to find that file. > > This patch makes gdb try to open a source file with its canonical path > even if parts of that path do not exist. > > In this example when trying to open /build-server/program/build/../file.c > we search for /build-server/program/file.c. even if the "build" directory > is not present on the system. > > Also, since in general we do not need the full uncanonicalised path > to be present on the system and that we validate that the file exist > after a call to gdb_realpath with a subsequent call to open, > gdb_realpath was changed to accept that parts of the path or the whole > path be missing from the system. > > This is done using canonicalize_filename_mode (filename, CAN_MISSING); > > To make this behavior easy to adapt to multiple situations inside gdb > in the future, a new option to openp was added : > > OPF_TRY_REALPATH = 0x08 > > This will try the canonicalized path when using the openp function. > As used in find_and_open_source to allow this feature. > > Also added a small test case to verify the issue. > > gdb/ChangeLog: > > PR breakpoints/17497 > * defs.h: Add OPF_TRY_REALPATH. > * source.c (openp): Add OPF_TRY_REALPATH option. > (find_and_open_source): Use OPF_TRY_REALPATH option to find a file. > * utils.c (gdb_realpath): Change canonicalize_file_name > to canonicalize_filename_mode with CAN_MISSING flag. > > gdb/testsuite/ChangeLog: > > PR breakpoints/17497 > * gdb.base/Makefile.in: Add tryrealpath test. > * gdb.base/break-canonical-path.c: New test. > * gdb.base/break-canonical-path.exp: New file. > --- > gdb/defs.h | 7 +- > gdb/source.c | 37 ++++++++-- > gdb/testsuite/gdb.base/Makefile.in | 4 +- > gdb/testsuite/gdb.base/break-canonical-path.c | 22 ++++++ > gdb/testsuite/gdb.base/break-canonical-path.exp | 83 +++++++++++++++++++++++ > gdb/utils.c | 3 +- > 6 files changed, 146 insertions(+), 10 deletions(-) > create mode 100644 gdb/testsuite/gdb.base/break-canonical-path.c > create mode 100644 gdb/testsuite/gdb.base/break-canonical-path.exp > > diff --git a/gdb/defs.h b/gdb/defs.h > index a1cd45f..fac9b2c 100644 > --- a/gdb/defs.h > +++ b/gdb/defs.h > @@ -310,9 +310,10 @@ extern const char *pc_prefix (CORE_ADDR); > /* From source.c */ > > /* See openp function definition for their description. */ > -#define OPF_TRY_CWD_FIRST 0x01 > -#define OPF_SEARCH_IN_PATH 0x02 > -#define OPF_RETURN_REALPATH 0x04 > +#define OPF_TRY_CWD_FIRST 0x01 > +#define OPF_SEARCH_IN_PATH 0x02 > +#define OPF_RETURN_REALPATH 0x04 > +#define OPF_TRY_REALPATH 0x08 > > extern int openp (const char *, int, const char *, int, char **); > > diff --git a/gdb/source.c b/gdb/source.c > index 574d9fa..1a3fbf9 100644 > --- a/gdb/source.c > +++ b/gdb/source.c > @@ -769,8 +769,18 @@ openp (const char *path, int opts, const char *string, > > if (is_regular_file (string)) > { > - filename = alloca (strlen (string) + 1); > - strcpy (filename, string); > + if (opts & OPF_TRY_REALPATH) > + { > + char *real_path = gdb_realpath (string); > + filename = alloca (strlen (real_path) + 1); > + strcpy (filename, real_path); > + xfree (real_path); > + } > + else > + { > + filename = alloca (strlen (string) + 1); > + strcpy (filename, string); > + } > fd = gdb_open_cloexec (filename, mode, 0); > if (fd >= 0) > goto done; > @@ -867,6 +877,25 @@ openp (const char *path, int opts, const char *string, > strcat (filename + len, SLASH_STRING); > strcat (filename, string); > > + /* Try the canonical path. */ > + if (opts & OPF_TRY_REALPATH) > + { > + char *real_path; > + int newlen; > + > + real_path = gdb_realpath (filename); > + > + /* First, realloc the filename buffer if too short. */ > + newlen = len + strlen (real_path) + 1; > + if (newlen > alloclen) > + { > + alloclen = newlen; > + filename = alloca (alloclen); > + } > + strcpy (filename, real_path); > + xfree (real_path); > + } > + > if (is_regular_file (filename)) > { > fd = gdb_open_cloexec (filename, mode, 0); > @@ -1083,8 +1112,8 @@ find_and_open_source (const char *filename, > } > } > > - result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH, filename, > - OPEN_MODE, fullname); > + result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH | > + OPF_TRY_REALPATH, filename, OPEN_MODE, fullname); > if (result < 0) > { > /* Didn't work. Try using just the basename. */ > diff --git a/gdb/testsuite/gdb.base/Makefile.in b/gdb/testsuite/gdb.base/Makefile.in > index dda3169..1c23bbd 100644 > --- a/gdb/testsuite/gdb.base/Makefile.in > +++ b/gdb/testsuite/gdb.base/Makefile.in > @@ -4,8 +4,8 @@ srcdir = @srcdir@ > EXECUTABLES = a2-run advance all-types annota1 annota1-watch_thread_num \ > annota3 anon args arrayidx async attach attach-pie-misread \ > attach2 auxv bang\! bfp-test bigcore bitfields bitfields2 \ > - break break-always break-entry break-interp-test breako2 \ > - breakpoint-shadow break-on-linker-gcd-function \ > + break break-always break-canonical-path break-entry break-interp-test \ > + breako2 breakpoint-shadow break-on-linker-gcd-function \ > call-ar-st call-rt-st call-sc-t* call-signals \ > call-strs callexit callfuncs callfwmall charset checkpoint \ > chng-syms code_elim1 code_elim2 commands compiler completion complex \ > diff --git a/gdb/testsuite/gdb.base/break-canonical-path.c b/gdb/testsuite/gdb.base/break-canonical-path.c > new file mode 100644 > index 0000000..7e362b2 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/break-canonical-path.c > @@ -0,0 +1,22 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2015 Free Software Foundation, Inc. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see . */ > + > +int > +main (void) > +{ > + return 0; > +} > diff --git a/gdb/testsuite/gdb.base/break-canonical-path.exp b/gdb/testsuite/gdb.base/break-canonical-path.exp > new file mode 100644 > index 0000000..511acaa > --- /dev/null > +++ b/gdb/testsuite/gdb.base/break-canonical-path.exp > @@ -0,0 +1,83 @@ > +# Copyright (C) 2015 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see . > + > +# This file tests if we can set a breakpoint provided our path is the > +# canonicalized path of a longer path with some parts that are not > +# present on the fs. > +# See breakpoints/17497 for more information > + > +# main directory for compilation > +set canonical_tmp_dir "break-canonical-path-tmp" > +# this directory will be deleted before putting the breakpoint > +set canonical_relative_dir "tmp" > +set canonical_srcfile_basename "break-canonical-path.c" > + > +standard_testfile $canonical_tmp_dir/$canonical_relative_dir/../$canonical_srcfile_basename > + > +proc canonical_cleanup {rmsrcfile rmreldir rmtmpdir} { > + global subdir > + global canonical_tmp_dir > + global canonical_relative_dir > + global canonical_srcfile_basename > + > + if { $rmsrcfile && [catch { file delete $subdir/$canonical_tmp_dir/$canonical_srcfile_basename }] } { > + print "file delete $subdir/$canonical_tmp_dir/$canonical_srcfile_basename failed" > + } > + if { $rmreldir && [catch { file delete $subdir/$canonical_tmp_dir/$canonical_relative_dir }] } { > + print "file delete $subdir/$canonical_tmp_dir/$canonical_relative_dir failed" > + } > + if { $rmtmpdir && [catch { file delete $subdir/$canonical_tmp_dir }] } { > + print "file delete $subdir/$canonical_tmp_di failed" > + } > +} > + > +if [is_remote host] { > + unsupported "Compiling on a remote host does not support a filename with directory." > + return 0 > +} > + > +if [catch { file mkdir "$subdir/$canonical_tmp_dir/$canonical_relative_dir" }] { > + untested "file mkdir $subdir/$canonical_tmp_dir/$canonical_relative_dir failed" > + canonical_cleanup false true true > + return 0 > +} > + > +if [catch { file copy $srcdir/$subdir/$canonical_srcfile_basename $subdir/$canonical_tmp_dir }] { > + untested "file copy $srcdir/$subdir/$srcfile_basename $subdir/$canonical_tmp_dir failed" > + canonical_cleanup false true true > + return 0 > +} > + > +#compile with the to be deleted directory so that it is in the debug info > +set err [gdb_compile "$subdir/$srcfile" $binfile executable {debug}] > +if { $err != "" } { > + untested "${srcfile} compilation failed" > + canonical_cleanup true true true > + return -1 > +} > + > +#remove the directory so that we can test after that we can break even if it's not there > +#using the canonicalized version of the path > +if [catch { file delete $subdir/$canonical_tmp_dir/$canonical_relative_dir }] { > + untested "rmdir $subdir/$canonical_tmp_dir/$canonical_relative_dir failed" > + canonical_cleanup true true true > + return 0 > +} > + > +clean_restart ${testfile} > + > +gdb_breakpoint $subdir/$canonical_tmp_dir/$canonical_srcfile_basename:[gdb_get_line_number "main" $srcdir/$subdir/$canonical_srcfile_basename] {message} > + > +canonical_cleanup true true true > diff --git a/gdb/utils.c b/gdb/utils.c > index 909476b..c97ead3 100644 > --- a/gdb/utils.c > +++ b/gdb/utils.c > @@ -68,6 +68,7 @@ > #include "gdb_usleep.h" > #include "interps.h" > #include "gdb_regex.h" > +#include "canonicalize.h" > > #if !HAVE_DECL_MALLOC > extern PTR malloc (); /* ARI: PTR */ > @@ -2889,7 +2890,7 @@ gdb_realpath (const char *filename) > } > #else > { > - char *rp = canonicalize_file_name (filename); > + char *rp = canonicalize_filename_mode (filename, CAN_MISSING); > > if (rp != NULL) > return rp; >