diff options
author | Doug Evans <dje@google.com> | 2015-12-10 12:00:33 -0800 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2015-12-10 12:00:33 -0800 |
commit | 99f46b49a70e508b1ef801e0cf85304ffc5bfb43 (patch) | |
tree | 3fe57b4ef2960021ca5825cec0216008141ac713 | |
parent | 6dc3050775f42a9e9877d967aa81cf9af161da85 (diff) | |
download | fsf-binutils-gdb-99f46b49a70e508b1ef801e0cf85304ffc5bfb43.zip fsf-binutils-gdb-99f46b49a70e508b1ef801e0cf85304ffc5bfb43.tar.gz fsf-binutils-gdb-99f46b49a70e508b1ef801e0cf85304ffc5bfb43.tar.bz2 |
patch ../102438704.patch
-rw-r--r-- | README.google | 20 | ||||
-rw-r--r-- | gdb/completer.c | 11 | ||||
-rw-r--r-- | gdb/main.c | 121 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/relocatable.exp | 161 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 66 | ||||
-rw-r--r-- | gdb/top.c | 3 | ||||
-rw-r--r-- | gdb/utils.c | 22 | ||||
-rw-r--r-- | gdb/utils.h | 8 |
9 files changed, 364 insertions, 52 deletions
diff --git a/README.google b/README.google index 6bd979a..6967900 100644 --- a/README.google +++ b/README.google @@ -409,3 +409,23 @@ they are an ongoing maintenance burden. + * gdb.python/py-post-init.c: New file. + * gdb.python/py-post-init.exp: New file. + * gdb.python/py-post-init.py: New file. +--- README.google 2015-09-06 00:43:48.000000000 -0700 ++++ README.google 2015-09-06 00:49:09.000000000 -0700 ++ ++2015-09-05 Doug Evans <dje@google.com> ++ ++ * completer.c (gdb_path_isdir): Move to ... ++ * utils.c (gdb_path_isdir): ... here. ++ (gdb_path_isfile): New function. ++ * utils.h (gdb_path_isdir): Declare. ++ (gdb_path_isfile): Declare. ++ * main.c (relocate_gdb_file): Renamed from relocate_path. ++ Try both make_relative_prefix and make_relative_prefix_ignore_symlinks. ++ All callers updated. ++ (maybe_lrealpath): New function. ++ (relocate_gdb_directory: Try both make_relative_prefix and ++ make_relative_prefix_ignore_symlinks. ++ * top.c (print_gdb_configuration): Print BINDIR. ++ ++ testsuite/ ++ * gdb.base/relocatable.exp: New file. diff --git a/gdb/completer.c b/gdb/completer.c index d55853c..c506aec 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1285,17 +1285,6 @@ gdb_display_match_list_pager (int lines, return 0; } -/* Return non-zero if FILENAME is a directory. - Based on readline/complete.c:path_isdir. */ - -static int -gdb_path_isdir (const char *filename) -{ - struct stat finfo; - - return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode)); -} - /* Return the portion of PATHNAME that should be output when listing possible completions. If we are hacking filename completion, we are only interested in the basename, the portion following the @@ -138,58 +138,97 @@ set_gdb_data_directory (const char *new_datadir) } } -/* Relocate a file or directory. PROGNAME is the name by which gdb - was invoked (i.e., argv[0]). INITIAL is the default value for the - file or directory. FLAG is true if the value is relocatable, false - otherwise. Returns a newly allocated string; this may return NULL - under the same conditions as make_relative_prefix. */ +/* Relocate a file. + INITIAL is the default value of the file. + FLAG is true if the value is relocatable, false otherwise. + Returns a newly allocated string; this may return NULL + under the same conditions as gdb_make_relative_prefix. */ static char * -relocate_path (const char *progname, const char *initial, int flag) +relocate_gdb_file (const char *initial, int flag) { - if (flag) - return make_relative_prefix (progname, BINDIR, initial); + char *path; + + /* Early exit if there's nothing we can do. */ + if (!flag) + return xstrdup (initial); + + /* We have to try both make_relative_prefix and + make_relative_prefix_ignore_links. The first handles a symlink to + gdb where it is installed. The second handles the case where the + installation tree is itself a collection of symlinks to random places. + Alas we can't distinguish a NULL return from make_relative_prefix* + due to lack of memory or due to failure to find a common prefix. + make_relative_prefix is tried first for backward compatibility. Ugh. */ + + path = make_relative_prefix (gdb_program_name, BINDIR, initial); + if (path != NULL && gdb_path_isfile (path)) + return path; + xfree (path); + path = make_relative_prefix_ignore_links (gdb_program_name, BINDIR, initial); + if (path != NULL && gdb_path_isfile (path)) + return path; + xfree (path); return xstrdup (initial); } -/* Like relocate_path, but specifically checks for a directory. - INITIAL is relocated according to the rules of relocate_path. If - the result is a directory, it is used; otherwise, INITIAL is used. - The chosen directory is then canonicalized using lrealpath. This - function always returns a newly-allocated string. */ +/* Return the lrealpath form of PATH. + Space for PATH must have been malloc'd. + PATH is freed if the lrealpath'd form is different. */ -char * -relocate_gdb_directory (const char *initial, int flag) +static char * +maybe_lrealpath (char *path) { - char *dir; + char *canon; - dir = relocate_path (gdb_program_name, initial, flag); - if (dir) - { - struct stat s; + if (*path == '\0') + return path; - if (*dir == '\0' || stat (dir, &s) != 0 || !S_ISDIR (s.st_mode)) - { - xfree (dir); - dir = NULL; - } + canon = lrealpath (path); + if (canon != NULL) + { + xfree (path); + path = canon; } - if (!dir) - dir = xstrdup (initial); - /* Canonicalize the directory. */ - if (*dir) - { - char *canon_sysroot = lrealpath (dir); + return path; +} - if (canon_sysroot) - { - xfree (dir); - dir = canon_sysroot; - } - } +/* Relocate a directory. + INITIAL is the default value of the directory. + FLAG is true if the value is relocatable, false otherwise. + If the result is a directory, it is used; otherwise, INITIAL is used. + The chosen directory is then canonicalized using lrealpath. This + function always returns a newly-allocated string. */ + +char * +relocate_gdb_directory (const char *initial, int flag) +{ + char *dir; - return dir; + /* Early exit if there's nothing we can do. */ + if (initial[0] == '\0') + return xstrdup (""); + if (!flag) + return maybe_lrealpath (xstrdup (initial)); + + /* We have to try both make_relative_prefix and + make_relative_prefix_ignore_links. The first handles a symlink to + gdb where it is installed. The second handles the case where the + installation tree is itself a collection of symlinks to random places. + Alas we can't distinguish a NULL return from make_relative_prefix* + due to lack of memory or due to failure to find a common prefix. Ugh. + make_relative_prefix is tried first for backward compatibility. */ + + dir = make_relative_prefix (gdb_program_name, BINDIR, initial); + if (dir != NULL && gdb_path_isdir (dir)) + return maybe_lrealpath (dir); + xfree (dir); + dir = make_relative_prefix_ignore_links (gdb_program_name, BINDIR, initial); + if (gdb_path_isdir (dir)) + return maybe_lrealpath (dir); + xfree (dir); + return maybe_lrealpath (xstrdup (initial)); } /* Compute the locations of init files that GDB should source and @@ -238,9 +277,9 @@ get_init_files (const char **system_gdbinit, } else { - relocated_sysgdbinit = relocate_path (gdb_program_name, - SYSTEM_GDBINIT, - SYSTEM_GDBINIT_RELOCATABLE); + relocated_sysgdbinit + = relocate_gdb_file (SYSTEM_GDBINIT, + SYSTEM_GDBINIT_RELOCATABLE); } if (relocated_sysgdbinit && stat (relocated_sysgdbinit, &s) == 0) sysgdbinit = relocated_sysgdbinit; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index dd253e3..6312d4c 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -21,6 +21,10 @@ gdb.base/dso2dso-dso1.c, gdb.base/dso2dso-dso1.h, gdb.base/dso2dso.c, gdb.base/dso2dso.exp: New files. +2015-08-12 Patrick Palka <patrick@parcs.ath.cx> + + * lib/gdb.exp (save_vars): New proc. + 2015-08-10 Doug Evans <dje@google.com> Keith Seitz <keiths@redhat.com> diff --git a/gdb/testsuite/gdb.base/relocatable.exp b/gdb/testsuite/gdb.base/relocatable.exp new file mode 100644 index 0000000..263215c --- /dev/null +++ b/gdb/testsuite/gdb.base/relocatable.exp @@ -0,0 +1,161 @@ +# 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 <http://www.gnu.org/licenses/>. + +# Test gdb's handling of relocatability. +# This only works if gdb was configured to be relocatable. +# We can't rebuild gdb just for this test, but we can check whether +# the built gdb is relocatable and if so then run the tests. + +# It's not clear what systems this test will work on. +# For now pick the ones we know will work. +if {![istarget *-*-linux*] + || [is_remote host]} { + return 0 +} + +gdb_exit +gdb_start +set config [capture_command_output "show config" ""] + +regsub "^.*(--bindir=\[\^\r\n\]+).*$" $config "\\1" bindir_text +regsub "^.*(--with-gdb-datadir=\[\^\r\n\]+).*$" $config "\\1" datadir_text + +verbose -log "bindir_text: $bindir_text" +verbose -log "datadir_text: $datadir_text" + +if { [string first " (relocatable)" $datadir_text] < 0 } { + unsupported "gdb not relocatable" + return 0 +} + +regsub "^--bindir=" $bindir_text "" bindir +regsub "^--with-gdb-datadir=" $datadir_text "" datadir +regsub " \\(relocatable\\)" $datadir "" datadir + +verbose -log "bindir: $bindir" +verbose -log "datadir: $datadir" + +set env_program "env" ;# TODO: gdb_find_env +set make_program "make" ;# TODO: gdb_find_make + +# Run "make install" to install gdb in INSTALL_DIR. +# The result is zero for success, non-zero for failure. + +proc make_install { install_dir } { + global env_program + global make_program + + file delete -force -- $install_dir + + # If invoked from make check-parallel, several env vars are set up which + # will confuse this make, so unset them. + set env_options "-u MAKELEVEL -u MAKEFLAGS -u MFLAGS -u MAKEOVERRIDES" + + # We don't need to install the docs or gdbserver, just gdb. + # And we don't want to cause a rebuild of gdb, so use install-only. + set make_options "-C .. install-only SUBDIRS=data-directory DESTDIR=$install_dir" + + set cmd "$env_program $env_options $make_program $make_options" + verbose -log "Executing: $cmd" + set result [catch "exec $cmd" output] + + verbose -log "result is $result" + verbose -log "output is $output" + + set test "make install" + if { $result != 0 } { + fail $test + } else { + pass $test + } + return $result +} + +proc start_and_check_data_dir { gdb_path expected_data_dir } { + global GDB INTERNAL_GDBFLAGS + save_vars { GDB INTERNAL_GDBFLAGS } { + set GDB $gdb_path + # We want this gdb to find its installed data-directory, so don't + # pass it one. + regsub -- "-data-directory \[^ \]+" $INTERNAL_GDBFLAGS "" INTERNAL_GDBFLAGS + gdb_exit + gdb_start + set datadir_in_gdb [capture_command_output "show data-dir" ""] + regsub "^GDB's data directory is \"" $datadir_in_gdb "" datadir_in_gdb + regsub "\".\[\r\n\]+$" $datadir_in_gdb "" datadir_in_gdb + set test "data-dir updated correctly" + if { $datadir_in_gdb == $expected_data_dir } { + pass $test + } else { + fail $test + } + } +} + +# Move all files (and directories) from from_dir to to_dir and leave behind +# symlinks pointing to the new location. + +proc move_and_leave_symlinks { from_dir to_dir } { + file delete -force -- $to_dir + file mkdir $to_dir + set files [glob -tails -directory $from_dir *] + foreach f $files { + file copy -- "${from_dir}/$f" "${to_dir}" + file delete -force -- "${from_dir}/$f" + file link -symbolic "${from_dir}/$f" "${to_dir}/$f" + } +} + +# First test the case where gdb is a symlink to its installed copy. +# This exercises make_relative_prefix (where we need to call lrealname +# on gdb's argv[0] in order to establish our location). + +with_test_prefix "realpath_symlinks" { + set install_dir [standard_output_file make_relative_prefix] + + if { [make_install $install_dir] == 0 } { + set linked_gdb [standard_output_file ${install_dir}/gdb] + file delete -force -- "${linked_gdb}" + file link -symbolic "${linked_gdb}" ".${bindir}/gdb" + + start_and_check_data_dir $linked_gdb "${install_dir}${datadir}" + } +} + +# Second test is having the install tree being a set of symlinks pointing +# to (essentially) random places +# This exercises make_relative_prefix_ignore_links (where calling lrealname on +# gdb's argv[0] is the wrong thing to do). + +with_test_prefix "ignore_symlinks" { + set install_dir [standard_output_file make_relative_prefix_ignore_links] + + if { [make_install $install_dir] == 0 } { + # Now that we've created an install tree, move bindir and datadir to + # "random" places and create symlinks in their place. + + set install_bindir "${install_dir}${bindir}" + set install_datadir "${install_dir}${datadir}" + + set random_bindir "${install_dir}/random1/bindir" + set random_datadir "${install_dir}/random2/datadir" + + move_and_leave_symlinks $install_bindir $random_bindir + move_and_leave_symlinks $install_datadir $random_datadir + + start_and_check_data_dir ${install_bindir}/gdb \ + "${install_dir}${datadir}" + } +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index f74d122..730f878 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -1835,6 +1835,72 @@ proc with_test_prefix { prefix body } { } } +# Run BODY in the context of the caller. After BODY is run, the variables +# listed in VARS will be reset to the values they had before BODY was run. +# +# This is useful for providing a scope in which it is safe to temporarily +# modify global variables, e.g. +# +# global INTERNAL_GDBFLAGS +# global env +# +# set foo GDBHISTSIZE +# +# save_vars { INTERNAL_GDBFLAGS env($foo) env(HOME) } { +# append INTERNAL_GDBFLAGS " -nx" +# unset -nocomplain env(GDBHISTSIZE) +# gdb_start +# gdb_test ... +# } +# +# Here, although INTERNAL_GDBFLAGS, env(GDBHISTSIZE) and env(HOME) may be +# modified inside BODY, this proc guarantees that the modifications will be +# undone after BODY finishes executing. + +proc save_vars { vars body } { + array set saved_scalars { } + array set saved_arrays { } + set unset_vars { } + + foreach var $vars { + # First evaluate VAR in the context of the caller in case the variable + # name may be a not-yet-interpolated string like env($foo) + set var [uplevel 1 list $var] + + if [uplevel 1 [list info exists $var]] { + if [uplevel 1 [list array exists $var]] { + set saved_arrays($var) [uplevel 1 [list array get $var]] + } else { + set saved_scalars($var) [uplevel 1 [list set $var]] + } + } else { + lappend unset_vars $var + } + } + + set code [catch {uplevel 1 $body} result] + + foreach {var value} [array get saved_scalars] { + uplevel 1 [list set $var $value] + } + + foreach {var value} [array get saved_arrays] { + uplevel 1 [list unset $var] + uplevel 1 [list array set $var $value] + } + + foreach var $unset_vars { + uplevel 1 [list unset -nocomplain $var] + } + + if {$code == 1} { + global errorInfo errorCode + return -code $code -errorinfo $errorInfo -errorcode $errorCode $result + } else { + return -code $code $result + } +} + # Run tests in BODY with GDB prompt and variable $gdb_prompt set to # PROMPT. When BODY is finished, restore GDB prompt and variable # $gdb_prompt. @@ -1284,6 +1284,9 @@ This GDB was configured as follows:\n\ configure --host=%s --target=%s\n\ "), host_name, target_name); fprintf_filtered (stream, _("\ + --bindir=%s\n\ +"), BINDIR); + fprintf_filtered (stream, _("\ --with-auto-load-dir=%s\n\ --with-auto-load-safe-path=%s\n\ "), AUTO_LOAD_DIR, AUTO_LOAD_SAFE_PATH); diff --git a/gdb/utils.c b/gdb/utils.c index b25216c..80b009c 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -3057,6 +3057,28 @@ ldirname (const char *filename) return dirname; } +/* See utils.h. + Based on readline/complete.c:path_isdir. */ + +int +gdb_path_isdir (const char *path) +{ + struct stat s; + + return stat (path, &s) == 0 && S_ISDIR (s.st_mode); +} + +/* See utils.h. + Based on readline/complete.c:path_isdir. */ + +int +gdb_path_isfile (const char *path) +{ + struct stat s; + + return stat (path, &s) == 0 && S_ISREG (s.st_mode); +} + /* Call libiberty's buildargv, and return the result. If buildargv fails due to out-of-memory, call nomem. Therefore, the returned value is guaranteed to be non-NULL, diff --git a/gdb/utils.h b/gdb/utils.h index 995a1cf..0adb097 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -135,6 +135,14 @@ extern void substitute_path_component (char **stringp, const char *from, const char *to); char *ldirname (const char *filename); + +/* Return non-zero if PATH is a directory. */ + +extern int gdb_path_isdir (const char *path); + +/* Return non-zero if PATH is a plain file. */ + +extern int gdb_path_isfile (const char *path); /* GDB output, ui_file utilities. */ |