From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 1D98A3858D28 for ; Tue, 31 Jan 2023 00:17:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1D98A3858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=us.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=us.ibm.com Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 30V01l6V014055; Tue, 31 Jan 2023 00:17:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=message-id : subject : from : to : cc : date : in-reply-to : references : content-type : content-transfer-encoding : mime-version; s=pp1; bh=X3mjQdQE08Zez8mqqKmrTvYRrHIHALJg+mVY5mGUjWs=; b=SzNyzgpZLoSKTMv5caNVP0OydQTC59Y7R7hoR/LE5zJWSw3UN6RpArgLYXuoPcW+pMGC +mhxMOnc3felouHqKOZekP6PXrSksX2VWB84+CJCyXDziq82BZmotN+f6QZdCMyrBFS9 MhhE9AeKK0Tf4jT0nKivO4J29Q6BNW98unrngPR52Eh8sYzw2kOdWRwpmsCA0p4EJivX mXOB0XDiVN7WRLOmy27GU4PuE6sVkxD+ZJAilFHaPnfa0YSs7RfwuR8+NdOsOhqwIWmI +rFmEs64AcQP2AGPFDqDAfAAXrU3jYsnnvCpy96NVwaPWW+2wRzCR00Ggrb56Yz3qv1J mA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3nen254qfk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Jan 2023 00:17:31 +0000 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 30V0AR47013310; Tue, 31 Jan 2023 00:17:31 GMT Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3nen254qfe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Jan 2023 00:17:31 +0000 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 30ULnDpc006462; Tue, 31 Jan 2023 00:17:30 GMT Received: from smtprelay06.dal12v.mail.ibm.com ([9.208.130.100]) by ppma01dal.us.ibm.com (PPS) with ESMTPS id 3ncvtm8kea-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 31 Jan 2023 00:17:30 +0000 Received: from smtpav03.dal12v.mail.ibm.com (smtpav03.dal12v.mail.ibm.com [10.241.53.102]) by smtprelay06.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 30V0HTcn9044550 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 31 Jan 2023 00:17:29 GMT Received: from smtpav03.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 46A7A58061; Tue, 31 Jan 2023 00:17:29 +0000 (GMT) Received: from smtpav03.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C3F2A58056; Tue, 31 Jan 2023 00:17:28 +0000 (GMT) Received: from li-e362e14c-2378-11b2-a85c-87d605f3c641.ibm.com (unknown [9.163.12.142]) by smtpav03.dal12v.mail.ibm.com (Postfix) with ESMTP; Tue, 31 Jan 2023 00:17:28 +0000 (GMT) Message-ID: <6785a1c038d5956d43892f8a7f27106d9001de76.camel@us.ibm.com> Subject: Reverse-next bug test case From: Carl Love To: Pedro Alves , Bruno Larsen , Tom de Vries , Ulrich Weigand , gdb-patches@sourceware.org Cc: cel@us.ibm.com Date: Mon, 30 Jan 2023 16:17:28 -0800 In-Reply-To: <873eb58a-a6ab-08b2-0827-ca6e0c8088ae@palves.net> References: <50474aa92ba82eff05cdc8f49001eae56be29670.camel@us.ibm.com> <89331c26795e3f7743e1e068dce43b3c2dd53008.camel@us.ibm.com> <071f24ecf9b3a2bbbe8fee7db77492eb55c5f3ff.camel@us.ibm.com> <1d9b21914354bef6a290ac30673741e722e11757.camel@de.ibm.com> <3e3c9c40f07ab01c79fe10915e76ffa187c42ad9.camel@us.ibm.com> <122f5d2d3db9ef1979b0f8da927d005f32bba82c.camel@us.ibm.com> <011768e8-2b76-f8ed-1174-fbaa020b15e7@redhat.com> <58cebd1a-7883-fbc6-ac94-c67293f8fc8d@redhat.com> <5e5dc4a49aa8feb370419a1efecf277673b7dfc7.camel@us.ibm.com> <610d5f171d5f4baeb94887217e69d0e6d70e9d66.camel@us.ibm.com> <873eb58a-a6ab-08b2-0827-ca6e0c8088ae@palves.net> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5 (3.28.5-18.el8) X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: aXFwp6-Mb5r4M2wmWoIi8FsL05tSpuNd X-Proofpoint-GUID: PT2qK2CqAfqLASzR9PNT2eOCS8hkR481 Content-Transfer-Encoding: 8bit X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.122.1 definitions=2023-01-30_18,2023-01-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 clxscore=1015 lowpriorityscore=0 malwarescore=0 suspectscore=0 phishscore=0 spamscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2212070000 definitions=main-2301300217 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Pedro, Ulrich, Tom, Bruno: I put together a test case that demonstrates the error in the reverse- next command based on Pedro's example from our earlier discussion. I thought it would be best to make sure we all agree what the expected behavior of the test should be before attempting to fix the issue. :-) The first test scenario in the test is the example that Pedo gave. The test expects that the reverse-next will stop at the beginning of the line containing the two function calls. Then a reverse-step command should then stop at the previous source code line. The test currently fails the same on X86 and PowerPC, as expected, because the reverse- next in correctly stops between func1 and func2. The following reverse-step stops at the end of func1 not at the previous source code line as it should. I added a second test to do a reverse-step all the way back thru the source line with the two function calls on it to make sure we agree on the expected results for that scenario as well. The second test passes on X86 and PowerPC. The test case, explanation from Pedro's test, i.e. my first test case. The patch for the new test case is attached at the end. Thanks for the help reviewing this test. Carl On Tue, 2023-01-24 at 14:08 +0000, Pedro Alves wrote: > > Wait. That right there sounds bogus. The source line looks like: > > func1 (); func2 (); > > so stepping backwards over that line should always stop at the first > instruction of the line, not in the middle. Let's simplify this. > > Here's the full source code of my example: > > (gdb) list 1 > 1 void func1 () > 2 { > 3 } > 4 > 5 void func2 () > 6 { > 7 } > 8 > 9 int main () > 10 { > 11 func1 (); func2 (); > 12 } > > Compiled with: > > $ gcc reverse.c -o reverse -g3 -O0 > $ gcc -v > ... > gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04) > > Now let's debug it with target record, using current gdb git master > (f3d8ae90b236), > without your patch: > > $ gdb ~/reverse > GNU gdb (GDB) 14.0.50.20230124-git > ... > Reading symbols from /home/pedro/reverse... > (gdb) start > Temporary breakpoint 1 at 0x1147: file reverse.c, line 11. > Starting program: /home/pedro/reverse > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/lib/x86_64-linux- > gnu/libthread_db.so.1". > > Temporary breakpoint 1, main () at reverse.c:11 > 11 func1 (); func2 (); > (gdb) record > > (gdb) disassemble /s > Dump of assembler code for function main: > reverse.c: > 10 { > 0x000055555555513f <+0>: endbr64 > 0x0000555555555143 <+4>: push %rbp > 0x0000555555555144 <+5>: mov %rsp,%rbp > > 11 func1 (); func2 (); > => 0x0000555555555147 <+8>: mov $0x0,%eax > 0x000055555555514c <+13>: call 0x555555555129 > 0x0000555555555151 <+18>: mov $0x0,%eax > 0x0000555555555156 <+23>: call 0x555555555134 > 0x000055555555515b <+28>: mov $0x0,%eax > > 12 } > 0x0000555555555160 <+33>: pop %rbp > 0x0000555555555161 <+34>: ret > End of assembler dump. > > (gdb) n > 12 } > > So far so good, a "next" stepped over the whole of line 11 and > stopped at line 12. > > Let's confirm where we are now: > > (gdb) disassemble /s > Dump of assembler code for function main: > reverse.c: > 10 { > 0x000055555555513f <+0>: endbr64 > 0x0000555555555143 <+4>: push %rbp > 0x0000555555555144 <+5>: mov %rsp,%rbp > > 11 func1 (); func2 (); > 0x0000555555555147 <+8>: mov $0x0,%eax > 0x000055555555514c <+13>: call 0x555555555129 > 0x0000555555555151 <+18>: mov $0x0,%eax > 0x0000555555555156 <+23>: call 0x555555555134 > 0x000055555555515b <+28>: mov $0x0,%eax > > 12 } > => 0x0000555555555160 <+33>: pop %rbp > 0x0000555555555161 <+34>: ret > End of assembler dump. > > Good, we're at the first instruction of line 12. > > Now let's undo the "next", with "reverse-next": > > (gdb) reverse-next > 11 func1 (); func2 (); > > Seemingly stopped at line 11. Let's see exactly where: > > (gdb) disassemble /s > Dump of assembler code for function main: > reverse.c: > 10 { > 0x000055555555513f <+0>: endbr64 > 0x0000555555555143 <+4>: push %rbp > 0x0000555555555144 <+5>: mov %rsp,%rbp > > 11 func1 (); func2 (); > 0x0000555555555147 <+8>: mov $0x0,%eax > 0x000055555555514c <+13>: call 0x555555555129 > => 0x0000555555555151 <+18>: mov $0x0,%eax > 0x0000555555555156 <+23>: call 0x555555555134 > 0x000055555555515b <+28>: mov $0x0,%eax > > 12 } > 0x0000555555555160 <+33>: pop %rbp > 0x0000555555555161 <+34>: ret > End of assembler dump. > (gdb) > > And lo, we stopped in the middle of line 11! That is a bug, we > should have stepped > back all the way to the beginning of the line. The "reverse-next" > should have fully > undone the prior "next" command. Here's the same thing without the > distracting > disassemble commands: > > (gdb) b 11 > Breakpoint 1 at 0x1147: file reverse.c, line 11. > (gdb) r > Starting program: /home/pedro/reverse > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/lib/x86_64-linux- > gnu/libthread_db.so.1". > > Breakpoint 1, main () at reverse.c:11 > 11 func1 (); func2 (); > (gdb) p $pc > $1 = (void (*)()) 0x555555555147 > (gdb) record > (gdb) next > 12 } > (gdb) reverse-next > 11 func1 (); func2 (); > (gdb) p $pc > $2 = (void (*)()) 0x555555555151 > (gdb) > > > This: > > next -> reverse-next -> next -> reverse-next > > ... should leave you at the same instruction. But it doesn't in this > example! > ------------------------------------------------------- Patch for the test case based on Pedro's test New pedro test --- gdb/testsuite/gdb.reverse/pedro_test.c | 18 ++++ gdb/testsuite/gdb.reverse/pedro_test.exp | 118 +++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 gdb/testsuite/gdb.reverse/pedro_test.c create mode 100644 gdb/testsuite/gdb.reverse/pedro_test.exp diff --git a/gdb/testsuite/gdb.reverse/pedro_test.c b/gdb/testsuite/gdb.reverse/pedro_test.c new file mode 100644 index 00000000000..e3183356ff6 --- /dev/null +++ b/gdb/testsuite/gdb.reverse/pedro_test.c @@ -0,0 +1,18 @@ +void +func1 () +{ +} + +void +func2 () +{ +} + +int main () +{ + int a, b; + a = 1; + b = 2; + func1 (); func2 (); + a = a + b; // START REVERSE TEST +} diff --git a/gdb/testsuite/gdb.reverse/pedro_test.exp b/gdb/testsuite/gdb.reverse/pedro_test.exp new file mode 100644 index 00000000000..d315e993d5f --- /dev/null +++ b/gdb/testsuite/gdb.reverse/pedro_test.exp @@ -0,0 +1,118 @@ +# 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 . */ + +# This file is part of the GDB testsuite. It tests reverse stepping. +# Lots of code borrowed from "step-test.exp". + +# This test checks to make sure there is no regression failures for +# the reverse-next command when stepping back over two functions in +# the same line. + +if ![supports_reverse] { + return +} + +standard_testfile + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return -1 +} + +runto_main +set target_remote [gdb_is_target_remote] + +if [supports_process_record] { + # Activate process record/replay. + gdb_test_no_output "record" "turn on process record for test1" +} + +# Test 1, reverse-next command +# Set breakpoint at the line after the function calls. +set bp_start_reverse_test [gdb_get_line_number "START REVERSE TEST" $srcfile] +gdb_breakpoint $srcfile:$bp_start_reverse_test temporary + +# Continue to break point for reverse-next test. +# Command definition: reverse-next [count] +# Run backward to the beginning of the previous line executed in the current +# (innermost) stack frame. If the line contains function calls, they will be +# “un-executed” without stopping. Starting from the first line of a function, +# reverse-next will take you back to the caller of that function, before the +# function was called, just as the normal next command would take you from +# the last line of a function back to its return to its caller 2 . + +gdb_continue_to_breakpoint \ + "stopped at command reverse-next test start location" \ + ".*$srcfile:$bp_start_reverse_test\r\n.*" + +# The reverse-next should step all the way back to the begining of the line, +# i.e. at the begining of the func1 call. +gdb_test "reverse-next" ".*func1 \\(\\); func2 \\(\\);.*" \ + "reverse-next to line with two functions" + +# A reverse-step should step back and stop at the begining +# of the previous line b = 2, i.e. not in func1 (). +gdb_test "reverse-step" ".*b = 2;.*" \ + "reverse-step to previous line b = 2" + + +# Setup for test 2 +# Go back to the start of the function +gdb_test "reverse-continue" "a = 1;" "At start of main, setup for test 2" + +# Turn off record to clear logs and turn on again +gdb_test "record stop" "Process record is stopped.*" \ + "turn off process record for test1" +gdb_test_no_output "record" "turn on process record for test2" + + +# Test 2, reverse-step command +# Set breakpoint at the line after the function calls. +gdb_breakpoint $srcfile:$bp_start_reverse_test temporary + +# Continue to the start of the reverse-step test. +# Command definition: reverse-step [count] +# Run the program backward until control reaches the start of a +# different source line; then stop it, and return control to gdb. +# Like the step command, reverse-step will only stop at the beginning of a +# source line. It “un-executes” the previously executed source line. If the +# previous source line included calls to debuggable functions, reverse-step +# will step (backward) into the called function, stopping at the beginning +# of the last statement in the called function (typically a return +# statement). Also, as with the step command, if non-debuggable functions +# are called, reverse-step will run thru them backward without stopping. + +gdb_continue_to_breakpoint \ + "stopped at command reverse-step test start location" \ + ".*$srcfile:$bp_start_reverse_test\r\n.*" + +# The first reverse step should take us call of func2 (). +gdb_test "reverse-step" ".*}.*" \ + "reverse-step into func2 " + +# The second reverse step should take us call of func2 (). +gdb_test "reverse-step" ".*func1 \\(\\); func2 \\(\\);.*" \ + "reverse-step to line func1(); func2(), at call for func2 " + +# The third reverse step should take us into func1 (). +gdb_test "reverse-step" ".*}.*" \ + "reverse-step into func1 " + +# The fourth reverse step should take us call of func1 (). +gdb_test "reverse-step" ".*func1 \\(\\); func2 \\(\\);.*" \ + "reverse-step to line func1(); func2(), at call for func1 " + +# The fifth reverse step should take us to b = 2 (). +gdb_test "reverse-step" ".*b = 2;.*" \ + "reverse-step to line b = 2 " -- 2.37.2