aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorGuinevere Larsen <blarsen@redhat.com>2023-10-26 16:28:54 +0200
committerGuinevere Larsen <blarsen@redhat.com>2023-12-08 09:48:57 +0100
commitaaba0d3a1aae0fcf779a7f727064365612ad5837 (patch)
tree657ce1c11af872325232213f1be9d14300cd051f /gdb/symtab.c
parentc64ec6d0825f39ef9ac6f520d409569e7944b81e (diff)
downloadgdb-aaba0d3a1aae0fcf779a7f727064365612ad5837.zip
gdb-aaba0d3a1aae0fcf779a7f727064365612ad5837.tar.gz
gdb-aaba0d3a1aae0fcf779a7f727064365612ad5837.tar.bz2
gdb: Guarantee that an SAL's end is right before the next statement
When examining a failure that happens when testing gdb.python/py-symtab.c with clang, I noticed that it was going wrong because the test assumed that whenever we get an SAL, its end would always be right before statement in the line table. This is true for GCC compiled binaries, since gcc only adds statements to the line table, but not true for clang compiled binaries. This is the second time I run into a problem where GDB doesn't handle non-statement line table entries correctly. The other was eventually committed as 9ab50efc463ff723b8e9102f1f68a6983d320517: "gdb: fix until behavior with trailing !is_stmt lines", but that commit only changes the behavior for the 'until' command. In this patch I propose a more general solution, making it so every time we generate the SAL for a given pc, we set the end of the SAL to before the next statement or the first instruciton in the next line, instead of naively assuming that to be the case. With this new change, the edge case is removed from the processing of the 'until' command without regressing the accompanying test case, and no other regressions were observed in the testsuite. Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 9fd886c..d5d229f 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3207,10 +3207,16 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
unrelocated_addr (pc - objfile->text_section_offset ()),
pc_compare));
if (item != first)
- prev = item - 1; /* Found a matching item. */
+ {
+ prev = item - 1; /* Found a matching item. */
+ /* At this point, prev is a line whose address is <= pc. However, we
+ don't know if ITEM is pointing to the same statement or not. */
+ while (item != last && prev->line == item->line && !item->is_stmt)
+ item++;
+ }
/* At this point, prev points at the line whose start addr is <= pc, and
- item points at the next line. If we ran off the end of the linetable
+ item points at the next statement. If we ran off the end of the linetable
(pc >= start of the last line), then prev == item. If pc < start of
the first line, prev will not be set. */