From 4856b6bc835e25ab0f48462104152701c864858c Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 13 Oct 2013 16:11:08 +0000 Subject: [PATCH] Improve Executable displayed path (PR 15415 regression kind #2) gdb/ 2013-10-13 Jan Kratochvil Canonicalize directories for EXEC_FILENAME. * exec.c (exec_file_attach): Use gdb_realpath_keepfile for exec_filename. * utils.c (gdb_realpath_keepfile): New function. * utils.h (gdb_realpath_keepfile): New declaration. gdb/testsuite/ 2013-10-13 Jan Kratochvil Canonicalize directories for EXEC_FILENAME. * gdb.base/argv0-symlink.exp (kept file symbolic link name for info inferiors): New. (kept directory symbolic link name): Setup kfail. (kept directory symbolic link name for info inferiors): New. --- gdb/ChangeLog | 8 +++++ gdb/exec.c | 2 +- gdb/testsuite/ChangeLog | 8 +++++ gdb/testsuite/gdb.base/argv0-symlink.exp | 6 ++++ gdb/utils.c | 46 ++++++++++++++++++++++++ gdb/utils.h | 2 ++ 6 files changed, 71 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 322decc2bf..ef37d1427d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2013-10-13 Jan Kratochvil + + Canonicalize directories for EXEC_FILENAME. + * exec.c (exec_file_attach): Use gdb_realpath_keepfile for + exec_filename. + * utils.c (gdb_realpath_keepfile): New function. + * utils.h (gdb_realpath_keepfile): New declaration. + 2013-10-11 Doug Evans * Makefile.in (GDBFLAGS): New variable. diff --git a/gdb/exec.c b/gdb/exec.c index c7370e3d40..758cdc10ed 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -224,7 +224,7 @@ exec_file_attach (char *filename, int from_tty) } gdb_assert (exec_filename == NULL); - exec_filename = xstrdup (scratch_pathname); + exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6cd8c23d30..a5c678bc38 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-10-13 Jan Kratochvil + + Canonicalize directories for EXEC_FILENAME. + * gdb.base/argv0-symlink.exp + (kept file symbolic link name for info inferiors): New. + (kept directory symbolic link name): Setup kfail. + (kept directory symbolic link name for info inferiors): New. + 2013-10-11 Andreas Arnez * gdb.arch/s390-multiarch.exp: New file. diff --git a/gdb/testsuite/gdb.base/argv0-symlink.exp b/gdb/testsuite/gdb.base/argv0-symlink.exp index dc11f740e7..cf5785c856 100644 --- a/gdb/testsuite/gdb.base/argv0-symlink.exp +++ b/gdb/testsuite/gdb.base/argv0-symlink.exp @@ -37,6 +37,7 @@ if ![runto_main] { } gdb_test {print argv[0]} "/$filelink\"" $test +gdb_test "info inferiors" "/$subdir/$filelink *" "$test for info inferiors" set test "kept directory symbolic link name" @@ -59,4 +60,9 @@ if ![runto_main] { return -1 } +# gdbserver does not have this issue. +if ![is_remote target] { + setup_kfail "*-*-*" gdb/15934 +} gdb_test {print argv[0]} "/$dirlink/$filelink\"" $test +gdb_test "info inferiors" "/$subdir/$filelink *" "$test for info inferiors" diff --git a/gdb/utils.c b/gdb/utils.c index 89c248cc46..47f9dfe321 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -3233,6 +3233,52 @@ gdb_realpath (const char *filename) return xstrdup (filename); } +/* Return a copy of FILENAME, with its directory prefix canonicalized + by gdb_realpath. */ + +char * +gdb_realpath_keepfile (const char *filename) +{ + const char *base_name = lbasename (filename); + char *dir_name; + char *real_path; + char *result; + + /* Extract the basename of filename, and return immediately + a copy of filename if it does not contain any directory prefix. */ + if (base_name == filename) + return xstrdup (filename); + + dir_name = alloca ((size_t) (base_name - filename + 2)); + /* Allocate enough space to store the dir_name + plus one extra + character sometimes needed under Windows (see below), and + then the closing \000 character. */ + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We need to be careful when filename is of the form 'd:foo', which + is equivalent of d:./foo, which is totally different from d:/foo. */ + if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') + { + dir_name[2] = '.'; + dir_name[3] = '\000'; + } +#endif + + /* Canonicalize the directory prefix, and build the resulting + filename. If the dirname realpath already contains an ending + directory separator, avoid doubling it. */ + real_path = gdb_realpath (dir_name); + if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) + result = concat (real_path, base_name, (char *) NULL); + else + result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); + + xfree (real_path); + return result; +} + ULONGEST align_up (ULONGEST v, int n) { diff --git a/gdb/utils.h b/gdb/utils.h index 7ea0ff4205..208251142b 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -128,6 +128,8 @@ extern struct cleanup *make_bpstat_clear_actions_cleanup (void); extern char *gdb_realpath (const char *); +extern char *gdb_realpath_keepfile (const char *); + extern int gdb_filename_fnmatch (const char *pattern, const char *string, int flags);