aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2024-09-02 17:00:12 +0200
committerAndrew Burgess <aburgess@redhat.com>2024-12-04 14:03:44 +0000
commitcc9be6af06ab5490c31883a4b0ceaf212099cf57 (patch)
tree8947ce0ac3457f67c69a1eaa3f8a6750eedcda14 /gdb/symtab.c
parent215ba4f398c1bfabf50368d7379bcd1337addbe2 (diff)
downloadbinutils-users/aburgess/gdb-opt-code-debug.zip
binutils-users/aburgess/gdb-opt-code-debug.tar.gz
binutils-users/aburgess/gdb-opt-code-debug.tar.bz2
[wip] Fix range end handling of inlined subroutinesusers/aburgess/gdb-opt-code-debug
Currently there is a problem when debugging optimized code when the inferior stops at an inline sub-range end PC. It is unclear if that location is from the inline function or from the calling function. Therefore the call stack is often wrong. This patch detects the "weak" line table entries which are likely part of the previous inline block, and if we have such a location, it assumes the location belongs to the previous block. Additionally it may happen that the infrun machinery steps from one inline range to another inline range of the same inline function. That can look like jumping back and forth from the calling program to the inline function, while really the inline function just jumps from a hot to a cold section of the code, i.e. error handling. Additionally it may happen that one inline sub-range is empty or the inline is completely empty. But filtering that information away is not the right solution, since although there is no actual code from the inline, it is still possible that variables from an inline function can be inspected here. The issue with the empty ranges is also discussed here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 Conceptually this patch uses a heuristic to work around a deficiency in the dwarf-4 and dwarf-5 rnglists structure. There should be a location view number for each inline sub-range begin PC and end PC, similar to the DW_AT_GNU_entry_view which is the location view for the inline entry point.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f2e357d..5abd4b8 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3294,7 +3294,10 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
0) instead of a real line. */
if (prev && prev->line
- && (!best || prev->unrelocated_pc () > best->unrelocated_pc ()))
+ && (!best || prev->unrelocated_pc () > best->unrelocated_pc ()
+ || (prev->unrelocated_pc () == best->unrelocated_pc ()
+ && (best->pc (objfile) == pc
+ ? !best->is_stmt : best->is_weak))))
{
best = prev;
best_symtab = iter_s;
@@ -3322,7 +3325,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
&& (tmp - 1)->unrelocated_pc () == tmp->unrelocated_pc ()
&& (tmp - 1)->line != 0 && !tmp->is_stmt)
--tmp;
- if (tmp->is_stmt)
+ if (tmp->is_stmt && (tmp->pc (objfile) == pc || !tmp->is_weak))
best = tmp;
}
@@ -3346,18 +3349,14 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
We used to return alt->line - 1 here, but that could be
anywhere; if we don't have line number info for this PC,
don't make some up. */
- val.pc = pc;
- }
- else if (best->line == 0)
- {
- /* If our best fit is in a range of PC's for which no line
- number info is available (line number is zero) then we didn't
- find any valid line information. */
+ if (notcurrent)
+ pc++;
val.pc = pc;
}
else
{
val.is_stmt = best->is_stmt;
+ val.is_weak = best->is_weak;
val.symtab = best_symtab;
val.line = best->line;
val.pc = best->pc (objfile);