summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2013-08-28 17:55:55 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2013-08-28 17:55:55 +0000
commit56884ea59ba02949951cf9a59261f0b2e7f39c26 (patch)
tree284625c202ddc022e76520fe3d47c34383090cba
parent91437b5d55f09bba0b0851b8608b3782fde0bb29 (diff)
downloadgdb-56884ea59ba02949951cf9a59261f0b2e7f39c26.tar.gz
PR gdb/15415
gdb/ 2013-08-27 Jan Kratochvil <jan.kratochvil@redhat.com> PR gdb/15415 * corefile.c (get_exec_file): Use exec_filename. * defs.h (OPF_DISABLE_REALPATH): New definition. Add new comment. * exec.c (exec_close): Free EXEC_FILENAME. (exec_file_attach): New variable canonical_pathname. Use OPF_DISABLE_REALPATH. Call gdb_realpath explicitly. Set EXEC_FILENAME. * exec.h (exec_filename): New. * inferior.c (print_inferior, inferior_command): Use PSPACE_EXEC_FILENAME. * mi/mi-main.c (print_one_inferior): Likewise. * progspace.c (clone_program_space, print_program_space): Likewise. * progspace.h (struct program_space): New field pspace_exec_filename. * source.c (openp): Describe OPF_DISABLE_REALPATH. New variable realpath_fptr, initialize it from OPF_DISABLE_REALPATH, use it. gdb/testsuite/ 2013-08-27 Jan Kratochvil <jan.kratochvil@redhat.com> PR gdb/15415 * gdb.base/argv0-symlink.c: New file. * gdb.base/argv0-symlink.exp: New file.
-rw-r--r--gdb/corefile.c4
-rw-r--r--gdb/defs.h2
-rw-r--r--gdb/exec.c24
-rw-r--r--gdb/exec.h1
-rw-r--r--gdb/inferior.c9
-rw-r--r--gdb/mi/mi-main.c4
-rw-r--r--gdb/progspace.c9
-rw-r--r--gdb/progspace.h4
-rw-r--r--gdb/source.c31
-rw-r--r--gdb/testsuite/gdb.base/argv0-symlink.c22
-rw-r--r--gdb/testsuite/gdb.base/argv0-symlink.exp62
11 files changed, 144 insertions, 28 deletions
diff --git a/gdb/corefile.c b/gdb/corefile.c
index 9c795b85580..f1956940122 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -182,8 +182,8 @@ validate_files (void)
char *
get_exec_file (int err)
{
- if (exec_bfd)
- return bfd_get_filename (exec_bfd);
+ if (exec_filename)
+ return exec_filename;
if (!err)
return NULL;
diff --git a/gdb/defs.h b/gdb/defs.h
index d8a1adb0cee..e157d6b9732 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -345,8 +345,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_DISABLE_REALPATH 0x04
extern int openp (const char *, int, const char *, int, char **);
diff --git a/gdb/exec.c b/gdb/exec.c
index 221e67952d8..92c44f303f5 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -108,6 +108,9 @@ exec_close (void)
exec_bfd_mtime = 0;
remove_target_sections (&exec_bfd, abfd);
+
+ xfree (exec_filename);
+ exec_filename = NULL;
}
}
@@ -202,12 +205,13 @@ exec_file_attach (char *filename, int from_tty)
else
{
struct cleanup *cleanups;
- char *scratch_pathname;
+ char *scratch_pathname, *canonical_pathname;
int scratch_chan;
struct target_section *sections = NULL, *sections_end = NULL;
char **matching;
- scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
+ scratch_chan = openp (getenv ("PATH"),
+ OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH, filename,
write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
&scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
@@ -216,7 +220,9 @@ exec_file_attach (char *filename, int from_tty)
char *exename = alloca (strlen (filename) + 5);
strcat (strcpy (exename, filename), ".exe");
- scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
+ scratch_chan = openp (getenv ("PATH"),
+ OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH,
+ exename,
write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
&scratch_pathname);
}
@@ -226,11 +232,16 @@ exec_file_attach (char *filename, int from_tty)
cleanups = make_cleanup (xfree, scratch_pathname);
+ /* gdb_bfd_open (and its variants) prefers canonicalized pathname for
+ better BFD caching. */
+ canonical_pathname = gdb_realpath (scratch_pathname);
+ make_cleanup (xfree, canonical_pathname);
+
if (write_files)
- exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget,
+ exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
FOPEN_RUB, scratch_chan);
else
- exec_bfd = gdb_bfd_open (scratch_pathname, gnutarget, scratch_chan);
+ exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);
if (!exec_bfd)
{
@@ -238,6 +249,9 @@ exec_file_attach (char *filename, int from_tty)
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
+ gdb_assert (exec_filename == NULL);
+ exec_filename = xstrdup (scratch_pathname);
+
if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
{
/* Make sure to close exec_bfd, or else "run" might try to use
diff --git a/gdb/exec.h b/gdb/exec.h
index f5a4077ab30..39d3730aabf 100644
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -32,6 +32,7 @@ extern struct target_ops exec_ops;
#define exec_bfd current_program_space->ebfd
#define exec_bfd_mtime current_program_space->ebfd_mtime
+#define exec_filename current_program_space->pspace_exec_filename
/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
Returns 0 if OK, 1 on error. */
diff --git a/gdb/inferior.c b/gdb/inferior.c
index ed6b6260b33..eb8629cdb6a 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -587,9 +587,8 @@ print_inferior (struct ui_out *uiout, char *requested_inferiors)
ui_out_field_string (uiout, "target-id",
inferior_pid_to_str (inf->pid));
- if (inf->pspace->ebfd)
- ui_out_field_string (uiout, "exec",
- bfd_get_filename (inf->pspace->ebfd));
+ if (inf->pspace->pspace_exec_filename != NULL)
+ ui_out_field_string (uiout, "exec", inf->pspace->pspace_exec_filename);
else
ui_out_field_skip (uiout, "exec");
@@ -703,8 +702,8 @@ inferior_command (char *args, int from_tty)
printf_filtered (_("[Switching to inferior %d [%s] (%s)]\n"),
inf->num,
inferior_pid_to_str (inf->pid),
- (inf->pspace->ebfd
- ? bfd_get_filename (inf->pspace->ebfd)
+ (inf->pspace->pspace_exec_filename != NULL
+ ? inf->pspace->pspace_exec_filename
: _("<noexec>")));
if (inf->pid != 0)
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 20777a3933c..57821aa0e3a 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -570,10 +570,10 @@ print_one_inferior (struct inferior *inferior, void *xdata)
if (inferior->pid != 0)
ui_out_field_int (uiout, "pid", inferior->pid);
- if (inferior->pspace->ebfd)
+ if (inferior->pspace->pspace_exec_filename != NULL)
{
ui_out_field_string (uiout, "executable",
- bfd_get_filename (inferior->pspace->ebfd));
+ inferior->pspace->pspace_exec_filename);
}
data.cores = 0;
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 590ea9b6927..52460ab84f8 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -196,8 +196,8 @@ clone_program_space (struct program_space *dest, struct program_space *src)
set_current_program_space (dest);
- if (src->ebfd != NULL)
- exec_file_attach (bfd_get_filename (src->ebfd), 0);
+ if (src->pspace_exec_filename != NULL)
+ exec_file_attach (src->pspace_exec_filename, 0);
if (src->symfile_object_file != NULL)
symbol_file_add_main (src->symfile_object_file->name, 0);
@@ -336,9 +336,8 @@ print_program_space (struct ui_out *uiout, int requested)
ui_out_field_int (uiout, "id", pspace->num);
- if (pspace->ebfd)
- ui_out_field_string (uiout, "exec",
- bfd_get_filename (pspace->ebfd));
+ if (pspace->pspace_exec_filename)
+ ui_out_field_string (uiout, "exec", pspace->pspace_exec_filename);
else
ui_out_field_skip (uiout, "exec");
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 9d98baff359..f24a5697d3d 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -148,6 +148,10 @@ struct program_space
bfd *ebfd;
/* The last-modified time, from when the exec was brought in. */
long ebfd_mtime;
+ /* Similar to bfd_get_filename (exec_bfd) but in original form given
+ by user, without symbolic links and pathname resolved.
+ It needs to be freed by xfree. It is not NULL iff EBFD is not NULL. */
+ char *pspace_exec_filename;
/* The address space attached to this program space. More than one
program space may be bound to the same address space. In the
diff --git a/gdb/source.c b/gdb/source.c
index 03c5253ba13..a34a78ed140 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -690,6 +690,11 @@ is_regular_file (const char *name)
and the file, sigh! Emacs gets confuzzed by this when we print the
source file name!!!
+ If OPTS does not have OPF_DISABLE_REALPATH set return FILENAME_OPENED
+ resolved by gdb_realpath. Even with OPF_DISABLE_REALPATH this function
+ still returns filename starting with "/". If FILENAME_OPENED is NULL
+ this option has no effect.
+
If a file is found, return the descriptor.
Otherwise, return -1, with errno set for the last name we tried to open. */
@@ -849,19 +854,27 @@ done:
/* If a file was opened, canonicalize its filename. */
if (fd < 0)
*filename_opened = NULL;
- else if (IS_ABSOLUTE_PATH (filename))
- *filename_opened = gdb_realpath (filename);
else
{
- /* Beware the // my son, the Emacs barfs, the botch that catch... */
+ char *(*realpath_fptr) (const char *);
+
+ realpath_fptr = ((opts & OPF_DISABLE_REALPATH) != 0
+ ? xstrdup : gdb_realpath);
+
+ if (IS_ABSOLUTE_PATH (filename))
+ *filename_opened = realpath_fptr (filename);
+ else
+ {
+ /* Beware the // my son, the Emacs barfs, the botch that catch... */
- char *f = concat (current_directory,
- IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
- ? "" : SLASH_STRING,
- filename, (char *)NULL);
+ char *f = concat (current_directory,
+ IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+ ? "" : SLASH_STRING,
+ filename, (char *)NULL);
- *filename_opened = gdb_realpath (f);
- xfree (f);
+ *filename_opened = realpath_fptr (f);
+ xfree (f);
+ }
}
}
diff --git a/gdb/testsuite/gdb.base/argv0-symlink.c b/gdb/testsuite/gdb.base/argv0-symlink.c
new file mode 100644
index 00000000000..5be12fb6c5e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/argv0-symlink.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 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 <http://www.gnu.org/licenses/>. */
+
+int
+main (int argc, char **argv)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/argv0-symlink.exp b/gdb/testsuite/gdb.base/argv0-symlink.exp
new file mode 100644
index 00000000000..dc11f740e71
--- /dev/null
+++ b/gdb/testsuite/gdb.base/argv0-symlink.exp
@@ -0,0 +1,62 @@
+# Copyright 2013 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 <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [build_executable ${testfile}.exp ${testfile} ${srcfile}] == -1 } {
+ return -1
+}
+
+set test "kept file symbolic link name"
+set filelink "${testfile}-filelink"
+
+remote_file host delete [standard_output_file $filelink]
+set status [remote_exec host "ln -sf ${testfile} [standard_output_file $filelink]"]
+if {[lindex $status 0] != 0} {
+ unsupported "$test (host does not support symbolic links)"
+ return 0
+}
+
+clean_restart "$filelink"
+
+if ![runto_main] {
+ untested "could not run to main"
+ return -1
+}
+
+gdb_test {print argv[0]} "/$filelink\"" $test
+
+
+set test "kept directory symbolic link name"
+set dirlink "${testfile}-dirlink"
+
+# 'ln -sf' does not overwrite symbol link to a directory.
+# 'remote_file host delete' uses stat (not lstat), therefore it refuses to
+# delete a directory.
+remote_exec host "rm -f [standard_output_file $dirlink]"
+set status [remote_exec host "ln -sf . [standard_output_file $dirlink]"]
+if {[lindex $status 0] != 0} {
+ unsupported "$test (host does not support symbolic links)"
+ return 0
+}
+
+clean_restart "$dirlink/$filelink"
+
+if ![runto_main] {
+ untested "could not run to main"
+ return -1
+}
+
+gdb_test {print argv[0]} "/$dirlink/$filelink\"" $test