+2013-08-28 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.
+
2013-08-28 Will Newton <will.newton@linaro.org>
* common/linux-ptrace.c: Include stdint.h unconditionally.
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;
/* 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 **);
exec_bfd_mtime = 0;
remove_target_sections (&exec_bfd);
+
+ xfree (exec_filename);
+ exec_filename = NULL;
}
}
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__)
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);
}
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)
{
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
#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. */
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");
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)
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;
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);
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");
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
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. */
/* 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);
+ }
}
}
+2013-08-28 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR gdb/15415
+ * gdb.base/argv0-symlink.c: New file.
+ * gdb.base/argv0-symlink.exp: New file.
+
2013-08-28 Tom Tromey <tromey@redhat.com>
* gdb.dwarf2/gdb-index.exp (add_gdb_index): Use explicit test name
--- /dev/null
+/* 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;
+}
--- /dev/null
+# 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