[v2,2/2] Handle stepping out of function into loop, case 2

Message ID 20240906144725.30233-2-tdevries@suse.de
State New
Headers
Series [v2,1/2] Handle stepping out of function into loop, case 1 |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Test failed

Commit Message

Tom de Vries Sept. 6, 2024, 2:47 p.m. UTC
  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 and aarch64-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(+)
  

Patch

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 5af873ed150..99112df2815 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
+    }
+}