[PATCH 2/2] [gdb] Handle stepping out of function into loop, case 2
Tom de Vries
tdevries@suse.de
Thu Sep 5 15:06:40 GMT 2024
Consider the same test-case as in the previous commit, compiled with gcc 13.3
and -g:
...
$ g++ -g test.c
...
Using next to step out of function f steps out of the loop:
...
$ gdb -q a.out -ex start
Reading symbols from a.out...
Temporary breakpoint 1 at 0x4004fa: file test.c, line 12.
Starting program: a.out
Temporary breakpoint 1, main () at test.c:12
12 while (f(n))
(gdb) step
f (w=@0x7fffffffdc9c: 0) at test.c:5
5 bool result = ++count != 42;
(gdb) step
6 return result;
(gdb) step
7 }
(gdb) next
main () at test.c:14
14 return n;
(gdb)
...
As mentioned in the previous commit, the loop looks like:
...
4004fa: 90 nop
4004fb: 48 8d 45 fc lea -0x4(%rbp),%rax
4004ff: 48 89 c7 mov %rax,%rdi
400502: e8 bf ff ff ff call 4004c6 <_Z1fRi>
400507: 84 c0 test %al,%al
400509: 75 f0 jne 4004fb <main+0x9>
40050b: 8b 45 fc mov -0x4(%rbp),%eax
...
with this line info:
...
INDEX LINE REL-ADDRESS UNREL-ADDRESS IS-STMT
8 12 0x00000000004004fa 0x00000000004004fa Y
9 14 0x000000000040050b 0x000000000040050b Y
...
so we cannot expect a user stop at line 12.
However, the next also steps over all subsequent calls to f.
Change the behaviour to stop at the next call to f, by degrading the
next to a step.
Tested on x86_64-linux.
PR gdb/32000
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32000
---
gdb/infrun.c | 8 ++++++++
gdb/testsuite/gdb.dwarf2/dw2-insn-loop-nop.exp | 14 ++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/gdb/infrun.c b/gdb/infrun.c
index ec9becae2f1..32bd715f289 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -8183,6 +8183,14 @@ process_event_stop_test (struct execution_control_state *ecs)
= (ecs->event_thread->current_line != stop_pc_sal.line
|| ecs->event_thread->current_symtab != stop_pc_sal.symtab);
+ if (different_line && execution_direction == EXEC_FORWARD
+ && ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+ {
+ /* Stepped out of line, degrade next to step. */
+ ecs->event_thread->control.step_over_calls
+ = STEP_OVER_UNDEBUGGABLE;
+ }
+
bool refresh_step_info = true;
if (different_line && ecs->event_thread->stop_pc () == stop_pc_sal.pc)
{
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-insn-loop-nop.exp b/gdb/testsuite/gdb.dwarf2/dw2-insn-loop-nop.exp
index 4c9f63647d5..65ee1b850ae 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-insn-loop-nop.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-insn-loop-nop.exp
@@ -65,3 +65,17 @@ gdb_test_multiple step "step out of foo using step" {
pass $gdb_test_name
}
}
+
+if { ! $in_foo } {
+ return
+}
+
+gdb_test_multiple next "step out of foo using next" {
+ -re -wrap $re_foo {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_main_return {
+ # Behaviour in gdb 15 and earlier.
+ fail $gdb_test_name
+ }
+}
--
2.35.3
More information about the Gdb-patches
mailing list