Hi, I have attached the 1/2 patch of this patchset as a bzip2 compressed patch so can it can be posted for review, hope it's ok... Regards, Antoine Tremblay On 02/03/2015 03:28 PM, Antoine Tremblay wrote: > Hi, > Unfortunately the 1/2 patch of this patchset failed because it's > about 1M , and mailman is only accepting < 400k emails... > > The patch is large since I'm replacing canonicalize-lgpl from > binutils with canonicalize and that triggers a few dependencies.. > > Any ideas on how I should proceed ? > > I could send a patch with only the change to the update-gnulib.sh > maybe ? > > Regards, > > Antoine Tremblay > > > 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; >