RE: [PATCH 1/2] fix for gdb.reverse/finish-precsave.exp and gdb.reverse/finish-reverse.exp

Carl Love via Gdb-patches
2023-01-13T19:11:19Z

Bruno:

On Fri, 2023-01-13 at 18:04 +0100, Bruno Larsen wrote:
> > I haven't run into the issue that mentioned about GDB not
> > responding in
> > the epilogue. I will have to go play with that to see if I can
> > reproduce it. If you have any specific instructions on how you ran
> > into it that would be interesting and helpful.
>
> I manually ran gdb.reverse/finish-precsave (setting recording, of
> course), set a temporary breakpoint on void_func, nexted once to be
> in
> the epilogue and tried to reverse finish. I'm not sure if it was
> some
> stale file before I recompiled the test, though.
>
> Anyway, sorry if I was unclear, but that is not a regression of your
> patch. Rather, you patch fixed that issue, I just want that test to
> confirm that we don't accidentally regress it.

You were clear that you saw this as an existing issue before applying
my patches, i.e. not a regression due to my patch. But rather my patch
fixed an existing issue.

I have been playing around on my X86 box trying to reproduce the issue.

I have an X86 box running Ubuntu 22.04.1 LTS, gcc version Ubuntu
11.3.0-1ubuntu1~22.04.

Here is the log of what I did trying to reproduce the issue as you
described:

Note, I started by running

make check RUNTESTFLAGS='GDB=/home/carll/bin/gdb gdb.reverse/finish-precsave.exp'

to generate the binary for the test. I then cd'd to

~/GDB/build-finish-precsave/gdb/testsuite/outputs/gdb.reverse/finish-precsave

where the binary was saved.

Then I ran the test. The following is the results with the path names
to the files shortened to improve readability.

gdb ./finish-precsave
GNU gdb (GDB) 14.0.50.20230111-git

<snip>

Reading symbols from ./finish-precsave...
(gdb) break main
Breakpoint 1 at 0x11d3: file .../binutils-gdb-finish-precsave/gdb/testsuite/gdb.reverse/finish-reverse.c, line 95.
(gdb) r
Starting program: .../gdb/testsuite/outputs/gdb.reverse/finish-precsave/finish-precsave
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7fffffffe798)
at .../binutils-gdb-finish-precsave/gdb/testsuite/gdb.reverse/finish-reverse.c:95
95 for (i = 0; i < sizeof (testval.ffff); i++)
(gdb) record
(gdb) tb void_func
Temporary breakpoint 2 at 0x555555555131: file .../binutils-gdb-finishrecsave/gdb/testsuite/gdb.reverse/finish-reverse.c, line 44.
(gdb) c
Continuing.

Temporary breakpoint 2, void_func ()
at .../binutils-gdb-finish-precsave/gdb/testsuite/gdb.reverse/finish-reverse.c:44
44 void_test = 1; /* VOID FUNC */
(gdb) next
45 }
(gdb) reverse-finish
Run back to call of #0 void_func ()
at .../binutils-gdb-finish-precsave/gdb/testsuite/gdb.reverse/finish-reverse.c:45
0x00005555555551fd in main (argc=1, argv=0x7fffffffe798)
at ../binutils-gdb-finish-precsave/gdb/testsuite/gdb.reverse/finish-reverse.c:98
98 void_func (); /* call to void_func */
(gdb) reverse-step
98 void_func (); /* call to void_func */
(gdb) q

I have tried stopping in the other functions as well. The reverse-
finish still seems to work fine. I also tried setting layout-asm once
I reached the function and then did si to reach various instructions in
the epilog. Didn't seem to matter which instruction in the function I
was at when I issued the reverse-finish instruction, I was not able to
get gdb to hang. Unfortunately, I was not able to reproduce the issue
on X86. I have also tried reproducing the error on PowerPC without
success.

I created a new test case to do the above tests. My thought is if we
can get this new test case to reliably fail on your system without my
proposed patches, then we can add it to the new test case in the patch.
The test case passes on my X86 machine. Of course it fails on my PPC
machine due to the existing reverse finish issues. What do you think?

Carl
-------------------------------------------
reverse-finish hang test

---
.../gdb.reverse/gdb-reverse-finish-hang.exp | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 gdb/testsuite/gdb.reverse/gdb-reverse-finish-hang.exp

diff --git a/gdb/testsuite/gdb.reverse/gdb-reverse-finish-hang.exp b/gdb/testsuite/gdb.reverse/gdb-reverse-finish-hang.exp
new file mode 100644
index 00000000000..14a3991c9b9
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/gdb-reverse-finish-hang.exp
@@ -0,0 +1,54 @@
+# Copyright 2008-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite. It tests 'finish' with
+# reverse debugging.
+
+if ![supports_reverse] {
+ return
+}
+
+standard_testfile finish-reverse.c
+set precsave [standard_output_file finish.precsave]
+
+if { [prepare_for_testing "failed to prepare" "$testfile" $srcfile] } {
+ return -1
+}
+
+runto_main
+
+if [supports_process_record] {
+ # Activate process record/replay
+ gdb_test_no_output "record" "turn on process record"
+}
+
+# Test reverse finish from void func to see if gdb hangs.
+set breakloc [gdb_get_line_number "VOID FUNC" "$srcfile"]
+gdb_test "tbreak void_func" \
+ "Temporary breakpoint $decimal at .*$srcfile, line $breakloc\." \
+ "set breakpoint on void_func"
+gdb_continue_to_breakpoint "void_func" ".*$srcfile:$breakloc.*"
+
+# Step into epilogue of void_func.
+gdb_test "step" ".*}.*" "step to epilog"
+
+# Test to see if gdb hangs when doing a reverse-finish from the epilogue.
+gdb_test "reverse-finish" "$decimal.*void_func.*" \
+ "return to caller of void_func ()"
+
+# Do reverse-next, should stay on void_func function due to existing bug
+# in reverse-finish.
+gdb_test "reverse-next" "$decimal.*void_func.*" \
+ "reverse next in main"
--
2.34.1