| # Copyright 2024 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/>. |
| |
| # Check GDB's ability to auto-load the executable based on the file |
| # names extracted from the core file. |
| # |
| # Currently, only Linux supports reading full executable and arguments |
| # from a core file. |
| require {is_any_target "*-*-linux*" "*-*-freebsd*"} |
| |
| standard_testfile |
| |
| if {[build_executable $testfile.exp $testfile $srcfile {debug build-id}] == -1} { |
| untested "failed to compile" |
| return -1 |
| } |
| |
| # Load the COREFILE and confirm that GDB auto-loads the executable. |
| # The symbols should be read from SYMBOL_FILE and the core file should |
| # be reported as generated by GEN_FROM_FILE. |
| proc test_load { corefile symbol_file gen_from_file } { |
| clean_restart |
| set saw_generated_line false |
| set saw_reading_symbols false |
| |
| gdb_test_multiple "core-file $corefile" "load core file" { |
| |
| -re "^Reading symbols from [string_to_regexp $symbol_file]\\.\\.\\.\r\n" { |
| set saw_reading_symbols true |
| exp_continue |
| } |
| |
| -re "^Core was generated by `[string_to_regexp $gen_from_file]'\\.\r\n" { |
| set saw_generated_line true |
| exp_continue |
| } |
| |
| -re "^$::gdb_prompt $" { |
| gdb_assert { $saw_generated_line && $saw_reading_symbols} \ |
| $gdb_test_name |
| } |
| |
| -re "^\[^\r\n\]*\r\n" { |
| exp_continue |
| } |
| } |
| } |
| |
| with_test_prefix "absolute path" { |
| # Generate a core file, this uses an absolute path to the |
| # executable. |
| with_test_prefix "to file" { |
| set corefile [core_find $binfile] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_1 "$binfile.1.core" |
| remote_exec build "mv $corefile $corefile_1" |
| |
| test_load $corefile_1 $binfile $binfile |
| } |
| |
| # And create a symlink, and repeat the test using an absolute path |
| # to the symlink. |
| with_test_prefix "to symlink" { |
| set symlink_name "symlink_1" |
| set symlink [standard_output_file $symlink_name] |
| |
| with_cwd [standard_output_file ""] { |
| remote_exec build "ln -s ${testfile} $symlink_name" |
| } |
| |
| set corefile [core_find $symlink] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_2 "$binfile.2.core" |
| remote_exec build "mv $corefile $corefile_2" |
| |
| test_load $corefile_2 $symlink $symlink |
| } |
| |
| # Like the previous test, except this time, delete the symlink |
| # after generating the core file. GDB should be smart enough to |
| # figure out that we can use the underlying TESTFILE binary. |
| with_test_prefix "to deleted symlink" { |
| set symlink_name "symlink_2" |
| set symlink [standard_output_file $symlink_name] |
| |
| with_cwd [standard_output_file ""] { |
| remote_exec build "ln -s ${testfile} $symlink_name" |
| } |
| |
| set corefile [core_find $symlink] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_3 "$binfile.3.core" |
| remote_exec build "mv $corefile $corefile_3" |
| |
| remote_exec build "rm -f $symlink" |
| |
| # FreeBSD is unable to figure out the actual underlying mapped |
| # file, so when the symlink is deleted, FeeeBSD is stuck. |
| # |
| # There is some argument that this shouldn't even be a |
| # failure, the user ran the symlink, and if the symlink is |
| # gone, should we really expect GDB to find the underlying |
| # file? That we can on Linux is really just a quirk of how |
| # the mapped file list works. |
| setup_xfail "*-*-freebsd*" |
| |
| test_load $corefile_3 $binfile $symlink |
| } |
| |
| # Generate the core file with an absolute path to the executable, |
| # but move the core file and executable into a single directory |
| # together so GDB can't use the absolute path to find the |
| # executable. |
| # |
| # GDB should still find the executable though, but looking in the |
| # same directory as the core file. |
| with_test_prefix "in side directory" { |
| set binfile_2 [standard_output_file ${testfile}_2] |
| remote_exec build "cp $binfile $binfile_2" |
| |
| set corefile [core_find $binfile_2] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_4 "$binfile.4.core" |
| remote_exec build "mv $corefile $corefile_4" |
| |
| set side_dir [standard_output_file side_dir] |
| remote_exec build "mkdir -p $side_dir" |
| remote_exec build "mv $binfile_2 $side_dir" |
| remote_exec build "mv $corefile_4 $side_dir" |
| |
| set relocated_corefile_4 [file join $side_dir [file tail $corefile_4]] |
| set relocated_binfile_2 [file join $side_dir [file tail $binfile_2]] |
| test_load $relocated_corefile_4 $relocated_binfile_2 $binfile_2 |
| } |
| } |
| |
| with_test_prefix "relative path" { |
| # Generate a core file using relative a path. We ned to work |
| # around the core_find proc a little here. The core_find proc |
| # creates a sub-directory using standard_output_file and runs the |
| # test binary from inside that directory. |
| # |
| # Usually core_find is passed an absolute path, so thre's no |
| # problem, but we want to pass a relative path. |
| # |
| # So setup a directory structure like this: |
| # |
| # corefile-find-exec/ |
| # reldir/ |
| # <copy of $binfile here> |
| # workdir/ |
| # |
| # Place a copy of BINFILE in 'reldir/' and switch to workdir, use |
| # core_find which will create a sibling directory of workdir, and |
| # run the relative path from there. We then move the generated |
| # core file back into 'workdir/', this leaves a tree like: |
| # |
| # corefile-find-exec/ |
| # reldir/ |
| # <copy of $binfile here> |
| # workdir/ |
| # <core file here> |
| # |
| # Now we can ask GDB to open the core file, if all goes well GDB |
| # should make use of the relative path encoded in the core file to |
| # locate the executable in 'reldir/'. |
| # |
| # We also setup a symlink in 'reldir' that points to the |
| # executable and repeat the test, but this time executing the |
| # symlink. |
| set reldir_name "reldir" |
| set reldir [standard_output_file $reldir_name] |
| remote_exec build "mkdir -p $reldir" |
| |
| set alt_testfile "alt_${testfile}" |
| set binfile_3 "$reldir/${alt_testfile}" |
| remote_exec build "cp $binfile $binfile_3" |
| |
| set symlink_2 "symlink_2" |
| with_cwd $reldir { |
| remote_exec build "ln -s ${alt_testfile} ${symlink_2}" |
| } |
| |
| set work_dir [standard_output_file "workdir"] |
| remote_exec build "mkdir -p $work_dir" |
| |
| set rel_path_to_file "../${reldir_name}/${alt_testfile}" |
| set rel_path_to_symlink_2 "../${reldir_name}/${symlink_2}" |
| |
| with_cwd $work_dir { |
| with_test_prefix "to file" { |
| set corefile [core_find $rel_path_to_file] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_5 "${work_dir}/${testfile}.5.core" |
| remote_exec build "mv $corefile $corefile_5" |
| |
| test_load $corefile_5 \ |
| [file join $work_dir $rel_path_to_file] \ |
| $rel_path_to_file |
| } |
| |
| with_test_prefix "to symlink" { |
| set corefile [core_find $rel_path_to_symlink_2] |
| if {$corefile == ""} { |
| untested "unable to create corefile" |
| return 0 |
| } |
| set corefile_6 "${work_dir}/${testfile}.6.core" |
| remote_exec build "mv $corefile $corefile_6" |
| |
| test_load $corefile_6 \ |
| [file join $work_dir $rel_path_to_symlink_2] \ |
| $rel_path_to_symlink_2 |
| } |
| |
| # Move the core file. Now the relative path doesn't work so |
| # we instead rely on GDB to use information about the mapped |
| # files to help locate the executable. |
| with_test_prefix "with moved corefile" { |
| set corefile_7 [standard_output_file "${testfile}.7.core"] |
| remote_exec build "cp $corefile_6 $corefile_7" |
| test_load $corefile_7 $binfile_3 $rel_path_to_symlink_2 |
| } |
| } |
| } |