[v2,2/2] Handle stepping out of function into loop, case 2
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
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(+)
@@ -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)
{
@@ -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
+ }
+}