mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
Following on from the previous commit, this commit fixes the two KFAIL
in gdb.base/sysroot-debug-lookup.exp when not using the
native-extended-gdbserver board.
The failures in this test, when using the 'unix' board, are logged as
bug PR gdb/31804. The problem appears to be caused by the use of the
child_path function in find_separate_debug_file.
What happens on the 'unix' board is that the file is specified to GDB
with a target: prefix, however GDB spots that the target filesystem is
local to GDB and so opens the file without a target: prefix. When we
call into find_separate_debug_file the DIR and CANON_DIR arguments,
which are computed from the objfile_name() no longer have a target:
prefix.
However, in this test if the file was opened with a target: prefix,
then the sysroot also has a target: prefix. When child_path is called
it looks for a common prefix between CANON_DIR (from the objfile_name)
and the sysroot. However, the sysroot still has the target: prefix,
which means the child_path() call fails and returns nullptr.
What I think we need to do is this: if the sysroot has a target:
prefix, and the target filesystem is local to GDB, then we should
strip the target: prefix from the sysroot, just as we do when opening
a file (see gdb_bfd_open in gdb_bfd.c).
Now, when we make the child_path() call neither the sysroot nor
CANON_DIR will have a target: prefix, the child_path() call will
succeed, and GDB will correctly find the debug information.
There is just one remaining issue, the last path we look in when
searching for debug information is built by starting with the sysroot,
then adding the debug directory, see this line:
debugfile = path_join (target_prefix_str, root.c_str (),
debugdir.get (), base_path, debuglink);
The target_prefix_str is set to target: if DIR has a target: prefix,
and DIR should have a target: prefix if the file we're looking for was
opened with a target: prefix. However, in our case the file was in a
local filesystem so GDB stripped the prefix off.
The sysroot however, does have the target: prefix, and the test is
expecting to see GDB look within a file with the target: prefix.
Given that the above line is about looking within a sub-directory of
the sysroot, I think we should not be stripping the target: prefix off
the sysroot path (as we do when building ROOT), instead, we should, in
this case, not use TARGET_PREFIX_STR, and instead just use GDB's
sysroot as it is (in this case with the target: prefix).
With these fixes in place I now see no failures when using the 'unix',
'native-gdbserver', or 'native-extended-gdbserver' boards with this
test, and the KFAILs can be removed.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31804
185 lines
6.5 KiB
Plaintext
185 lines
6.5 KiB
Plaintext
# 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/>.
|
|
|
|
# Test GDB's ability to find debug information by looking within the
|
|
# sysroot.
|
|
#
|
|
# We compile a static binary (to reduce what we need to copy into the
|
|
# sysroot), split the debug information from the binary, and setup a
|
|
# sysroot.
|
|
#
|
|
# The debug-file-directory is set to just '/debug', but we're
|
|
# expecting GDB to actually look in '$SYSROOT/debug'.
|
|
#
|
|
# There's a test for using .build-id based lookup, and a test for
|
|
# gnu_debuglink based lookup.
|
|
|
|
require {!is_remote host}
|
|
|
|
standard_testfile main.c
|
|
|
|
# Create a copy of BINFILE, split out the debug information, and then
|
|
# setup a sysroot. Hide (by moving) the actual debug information file
|
|
# and create a symlink to the hidden debug information from within the
|
|
# sysroot.
|
|
#
|
|
# Start GDB, set the sysroot, and then load the executable, ensure GDB
|
|
# finds the debug information, which must have happened by lookin in
|
|
# the sysroot.
|
|
proc_with_prefix lookup_via_build_id {} {
|
|
set filename ${::binfile}_1
|
|
if { [build_executable "build exec" ${filename} $::srcfile \
|
|
{additional_flags=-static debug build-id}] } {
|
|
return
|
|
}
|
|
|
|
# Split debug information into a .debug file, remove debug
|
|
# information from FILENAME. Don't add a .gnu_debuglink to
|
|
# FILENAME, we rely on the build-id.
|
|
if {[gdb_gnu_strip_debug $filename { no-debuglink }] != 0} {
|
|
unsupported "cannot split debug information from executable"
|
|
return
|
|
}
|
|
|
|
set sysroot [standard_output_file "sysroot1"]
|
|
set debug_dir "/debug"
|
|
|
|
set debug_symlink \
|
|
${sysroot}${debug_dir}/[build_id_debug_filename_get $filename]
|
|
|
|
set build_id_dir [file dirname $debug_symlink]
|
|
|
|
set debug_filename ${filename}_hidden_debug
|
|
|
|
remote_exec build "mkdir -p $build_id_dir"
|
|
remote_exec build "mv $filename.debug $debug_filename"
|
|
remote_exec build "ln -sf $debug_filename $debug_symlink"
|
|
|
|
foreach_with_prefix sysroot_prefix { "" "target:" } {
|
|
clean_restart
|
|
|
|
gdb_test_no_output "set sysroot ${sysroot_prefix}$sysroot" "set sysroot"
|
|
gdb_test_no_output "set debug-file-directory $debug_dir"
|
|
|
|
gdb_file_cmd $filename
|
|
|
|
gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \
|
|
"ensure debug information was found"
|
|
|
|
if { $sysroot_prefix eq "target:"
|
|
&& [target_info gdb_protocol] == "extended-remote"} {
|
|
# Only when using the extended-remote board will we have
|
|
# started a remote target by this point. In this case GDB
|
|
# will see the 'target:' prefix as remote, and so the
|
|
# reported filename will include the 'target:' prefix.
|
|
#
|
|
# In all other cases we will still be using the default,
|
|
# initial target, in which case GDB considers the
|
|
# 'target:' prefix to indicate the local filesystem.
|
|
set lookup_filename $sysroot_prefix$debug_symlink
|
|
} else {
|
|
set lookup_filename $debug_filename
|
|
}
|
|
set re [string_to_regexp "Reading symbols from $lookup_filename..."]
|
|
gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \
|
|
"debug symbols read from correct file"
|
|
}
|
|
}
|
|
|
|
# Create a copy of BINFILE, split out the debug information, and then
|
|
# setup a sysroot. Hide (by moving) the actual debug information file
|
|
# and create a symlink to the hidden debug information from within the
|
|
# sysroot.
|
|
#
|
|
# Copy the executable into the sysroot and then start GDB, set the
|
|
# sysroot, and load the executable. Check that GDB finds the debug
|
|
# information, which must have happened by lookin in the sysroot.
|
|
proc_with_prefix lookup_via_debuglink {} {
|
|
set filename ${::binfile}_2
|
|
if { [build_executable "build exec" ${filename} $::srcfile \
|
|
{additional_flags=-static debug no-build-id}] } {
|
|
return
|
|
}
|
|
|
|
# Split debug information into a .debug file, remove debug
|
|
# information from FILENAME.
|
|
if {[gdb_gnu_strip_debug $filename] != 0} {
|
|
unsupported "cannot split debug information from executable"
|
|
return
|
|
}
|
|
|
|
# We're going to setup the sysroot like this:
|
|
#
|
|
# sysroot2/
|
|
# bin/
|
|
# $FILENAME
|
|
# debug/
|
|
# bin/
|
|
# $FILENAME.debug
|
|
#
|
|
# When looking up debug information via the debuglink, GDB will
|
|
# only search in the sysroot if the original objfile was in the
|
|
# sysroot. And GDB will resolve symlinks, so if the objfile is
|
|
# symlinked to outside the sysroot, GDB will not search in the
|
|
# sysroot for the debug information.
|
|
#
|
|
# So we have to copy the executable into the sysroot.
|
|
#
|
|
# We are OK to symlink the debug information to a file outside the
|
|
# sysroot though.
|
|
|
|
set sysroot [standard_output_file "sysroot2"]
|
|
|
|
foreach path { bin debug/bin } {
|
|
remote_exec build "mkdir -p $sysroot/$path"
|
|
}
|
|
|
|
# Copy the executable into the sysroot.
|
|
set file_basename [file tail $filename]
|
|
set exec_in_sysroot ${sysroot}/bin/${file_basename}
|
|
remote_exec build "cp $filename $exec_in_sysroot"
|
|
|
|
# Rename the debug file outside of the sysroot, this should stop
|
|
# GDB finding this file "by accident".
|
|
set debug_filename ${filename}_hidden_debug
|
|
remote_exec build "mv $filename.debug $debug_filename"
|
|
|
|
# Symlink the debug information into the sysroot.
|
|
set debug_symlink \
|
|
${sysroot}/debug/bin/${file_basename}.debug
|
|
remote_exec build "ln -sf $debug_filename $debug_symlink"
|
|
|
|
foreach_with_prefix sysroot_prefix { "" "target:" } {
|
|
# Restart GDB and setup the sysroot and debug directory.
|
|
clean_restart
|
|
gdb_test_no_output "set sysroot ${sysroot_prefix}$sysroot" "set sysroot"
|
|
gdb_test_no_output "set debug-file-directory /debug"
|
|
|
|
# Load the executable, we expect GDB to find the debug information
|
|
# in the sysroot.
|
|
gdb_file_cmd ${sysroot_prefix}$exec_in_sysroot
|
|
|
|
gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \
|
|
"ensure debug information was found"
|
|
|
|
set re [string_to_regexp "Reading symbols from ${sysroot_prefix}$debug_symlink..."]
|
|
gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \
|
|
"debug symbols read from correct file"
|
|
}
|
|
}
|
|
|
|
lookup_via_build_id
|
|
lookup_via_debuglink
|