mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 04:24:43 +00:00
gdb: pass minsym section to find_function_start_sal, when possible
We may rely on a minimal symbol to place a breakpoint on a function, for instance when debug infos are unavailable. The minsym_found function attempts to convert that minsym to a sal using either find_function_start_sal or filling a sal manually from the minimal symbol. This patch implements the decision to make it the responsibility of the sal creation site to properly fill out the section field when that is possible. The function address may be updated when dealing with ifuncs, which means the section from the minsym may be completely different from the actual function address's section. A preceding change (6f7ad238: gdb: ensure bp_location::section is set correct to avoid an assert) has proposed recomputing the section by calling find_pc_overlay. However, this ends up setting the section to NULL in most cases. While the section is often recomputed later on, I think it might be more appropriate to set it once and for all when creating the sal. The parent commit ensures that find_function_start_sal will return a symtab_and_line with a section if possible. minsym_found can pass the section if it can be trusted later on - it is in fact necessary to ensure we get the proper pc/section with overlays. When dealing with an ifunc that was resolved, then the section has to be recomputed since the ifunc implementation may be in another section, or objfile. This is now done in find_sal_for_pc_sect. This change restores the section argument in find_function_start_sal that was removed in a previous commit (6b0581fc: gdb/symtab: remove section parameter from find_function_start_sal), as it avoids an unnecessary lookup later in find_sal_for_pc_sect. The function now sends the minsym's section if it corresponds to the actual function, and not an ifunc. This commit fixes a failure on gdb.rocm/displaced-stepping.exp. A new test case is also provided to check that a breakpoint on a kernel is hit without debug infos. Approved-By: Tom Tromey <tom@tromey.com> Change-Id: I7a502dc4565911cec92618f34be3d4bcbf8560c5
This commit is contained in:
@@ -1046,7 +1046,7 @@ elf_gnu_ifunc_resolver_return_stop (code_breakpoint *b)
|
||||
|
||||
b->type = bp_breakpoint;
|
||||
update_breakpoint_locations (b, current_program_space,
|
||||
find_function_start_sal (resolved_pc, true),
|
||||
find_function_start_sal (resolved_pc, nullptr, true),
|
||||
{});
|
||||
}
|
||||
|
||||
|
||||
@@ -4059,6 +4059,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
|
||||
|
||||
CORE_ADDR func_addr;
|
||||
bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
|
||||
obj_section *section = msymbol->obj_section (objfile);
|
||||
|
||||
if (is_function)
|
||||
{
|
||||
@@ -4066,7 +4067,15 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
|
||||
|
||||
if (msymbol->type () == mst_text_gnu_ifunc
|
||||
|| msymbol->type () == mst_data_gnu_ifunc)
|
||||
want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
|
||||
{
|
||||
want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
|
||||
|
||||
/* We have found a different pc by resolving the ifunc. The
|
||||
section from the minsym may not be the same as the ifunc
|
||||
implementation. Do not trust it. */
|
||||
if (want_start_sal)
|
||||
section = nullptr;
|
||||
}
|
||||
else
|
||||
want_start_sal = true;
|
||||
}
|
||||
@@ -4074,7 +4083,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
|
||||
symtab_and_line sal;
|
||||
|
||||
if (is_function && want_start_sal)
|
||||
sal = find_function_start_sal (func_addr, self->funfirstline);
|
||||
sal = find_function_start_sal (func_addr, section, self->funfirstline);
|
||||
else
|
||||
{
|
||||
sal.objfile = objfile;
|
||||
@@ -4086,14 +4095,15 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
|
||||
else
|
||||
sal.pc = msymbol->value_address (objfile);
|
||||
sal.pspace = current_program_space;
|
||||
}
|
||||
|
||||
/* Don't use the section from the msymbol, the code above might have
|
||||
adjusted FUNC_ADDR, in which case the msymbol's section might not be
|
||||
the section containing FUNC_ADDR. It might not even be in the same
|
||||
objfile. As the section is primarily to assist with overlay
|
||||
debugging, it should reflect the SAL's pc value. */
|
||||
sal.section = find_pc_overlay (sal.pc);
|
||||
/* The minsym does not correspond to an ifunc that could be
|
||||
resolved. The section from the minsym may thus be trusted,
|
||||
and cannot be nullptr (since the minsym is from an objfile).
|
||||
Ensure all resulting sals have a non-null section when
|
||||
possible. */
|
||||
gdb_assert (section != nullptr);
|
||||
sal.section = section;
|
||||
}
|
||||
|
||||
if (self->maybe_add_address (objfile->pspace (), sal.pc))
|
||||
add_sal_to_sals (self, result, sal, msymbol->natural_name (), false);
|
||||
|
||||
@@ -3560,10 +3560,10 @@ find_function_start_sal_1 (CORE_ADDR func_addr, obj_section *section,
|
||||
/* See symtab.h. */
|
||||
|
||||
symtab_and_line
|
||||
find_function_start_sal (CORE_ADDR func_addr, bool funfirstline)
|
||||
find_function_start_sal (CORE_ADDR func_addr, obj_section *section, bool funfirstline)
|
||||
{
|
||||
symtab_and_line sal
|
||||
= find_function_start_sal_1 (func_addr, nullptr, funfirstline);
|
||||
= find_function_start_sal_1 (func_addr, section, funfirstline);
|
||||
|
||||
/* find_function_start_sal_1 does a linetable search, so it finds
|
||||
the symtab and linenumber, but not a symbol. Fill in the
|
||||
|
||||
@@ -2516,6 +2516,7 @@ extern symtab_and_line find_function_start_sal (symbol *sym, bool
|
||||
|
||||
/* Same, but start with a function address instead of a symbol. */
|
||||
extern symtab_and_line find_function_start_sal (CORE_ADDR func_addr,
|
||||
obj_section *section,
|
||||
bool funfirstline);
|
||||
|
||||
extern void skip_prologue_sal (struct symtab_and_line *);
|
||||
|
||||
30
gdb/testsuite/gdb.rocm/break-kernel-no-debug-info.cpp
Normal file
30
gdb/testsuite/gdb.rocm/break-kernel-no-debug-info.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2025 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/>. */
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
|
||||
__global__ void
|
||||
kern ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
kern<<<1, 1>>> ();
|
||||
return hipDeviceSynchronize () != hipSuccess;
|
||||
}
|
||||
53
gdb/testsuite/gdb.rocm/break-kernel-no-debug-info.exp
Normal file
53
gdb/testsuite/gdb.rocm/break-kernel-no-debug-info.exp
Normal file
@@ -0,0 +1,53 @@
|
||||
# Copyright 2025 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 setting a breakpoint on a kernel symbol without debug info,
|
||||
# relying on minimal symbols from the ELF.
|
||||
|
||||
# A bug occured when GDB did not find the appropriate architecture for
|
||||
# breakpoints on minimal symbols. This had the effect that the
|
||||
# breakpoint would not be hit on the GPU when no debugging infos are
|
||||
# available.
|
||||
|
||||
load_lib rocm.exp
|
||||
|
||||
standard_testfile .cpp
|
||||
|
||||
require allow_hipcc_tests
|
||||
|
||||
# Build for hip, explicitly without debug infos
|
||||
if {[build_executable "failed to prepare" $testfile $srcfile {hip nodebug}]} {
|
||||
return
|
||||
}
|
||||
|
||||
clean_restart
|
||||
|
||||
with_rocm_gpu_lock {
|
||||
gdb_test "file $::binfile" ".*No debugging symbols.*" "load file"
|
||||
|
||||
if {![runto_main]} {
|
||||
return
|
||||
}
|
||||
|
||||
gdb_test "with breakpoint pending on -- break kern" \
|
||||
"Breakpoint $::decimal \\(kern\\) pending."
|
||||
|
||||
gdb_test "continue" \
|
||||
"Thread $::decimal hit Breakpoint $::decimal, $::hex in kern.*"
|
||||
|
||||
gdb_test "continue" \
|
||||
"Inferior 1 .* exited normally.*" \
|
||||
"continue to end"
|
||||
}
|
||||
Reference in New Issue
Block a user