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
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),
{});
}
CORE_ADDR func_addr;
bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
+ obj_section *section = msymbol->obj_section (objfile);
if (is_function)
{
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;
}
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;
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);
/* 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
/* 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 *);
--- /dev/null
+/* 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;
+}
--- /dev/null
+# 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"
+}