From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) by sourceware.org (Postfix) with ESMTPS id 771BC3858D28 for ; Wed, 25 Jan 2023 16:42:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 771BC3858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-f46.google.com with SMTP id d4-20020a05600c3ac400b003db1de2aef0so1742472wms.2 for ; Wed, 25 Jan 2023 08:42:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:from:references:to:subject :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=l3ckSYm7kQJfzGPKQbN/XDB8aQc4qw/weDhOlbiCgAI=; b=cCGt9ycAZCqkqnn+lC+OFGlUA7HvdXpREm/hHrZV/fTYoufbACl0nGHhEiOG+guqY4 CNR5iEvCYFaeJDQCejqTmuABtP8VnIaUnNtJItnyH2rplUwQczvijhCCJn9rxFJQ/apC AH0aa8/iaaNCgj1p9qSlTqnJQcCYpa47DrZKotNwscixqdgK3IILRQqwZkoKHkywZGsm P0kTfcz83ZzHrF+yDxtgiFQap/YFJaqwggLKS4za1AdBlCmFOzOcv6tL0v9rUfTjJYLR Zb2yypTgy10BSC96v+AirvBHgQPWdCUJbs/kIld+oGaRViMkWgvcM2LyffgB6Hrh52zE s7mg== X-Gm-Message-State: AFqh2ko8UtC72koWftWqE0Y2/fslIIRSU61723+kaW99kng4SY9/Hsd5 7xW28y7y5vECLOIGDaio2oXi6ZfhIE+zrw== X-Google-Smtp-Source: AMrXdXt4yfIL2i/fy+78p7S9vrXOmUxhYO5xntOYmEAqJv6Y78BlcaTXkUrp0Y2pBlXD9VYSMNo3vg== X-Received: by 2002:a05:600c:1c8e:b0:3d9:e5f9:984c with SMTP id k14-20020a05600c1c8e00b003d9e5f9984cmr32705197wms.2.1674664968227; Wed, 25 Jan 2023 08:42:48 -0800 (PST) Received: from ?IPv6:2001:8a0:f92b:9e00::1fe? ([2001:8a0:f92b:9e00::1fe]) by smtp.gmail.com with ESMTPSA id hu10-20020a05600ca28a00b003d9f14e9085sm2271043wmb.17.2023.01.25.08.42.47 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Jan 2023 08:42:47 -0800 (PST) Subject: Re: [PATCH 1/2 version 3] fix for gdb.reverse/finish-precsave.exp and gdb.reverse/finish-reverse.exp To: Ulrich Weigand , "gdb-patches@sourceware.org" , "will_schmidt@vnet.ibm.com" , Bruno Larsen , "cel@us.ibm.com" References: <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> <8c4ebc33-f7b5-14a3-3bb0-155fe03e92d8@redhat.com> <837e302b-3ac3-67bd-5314-55194ab35421@redhat.com> From: Pedro Alves Message-ID: Date: Wed, 25 Jan 2023 16:42:45 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.10.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,KAM_DMARC_STATUS,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,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: On 2023-01-25 2:11 p.m., Ulrich Weigand wrote: > Pedro Alves wrote: > >>> 11 func1 (argc); func2 (argc); >>> 0x000055555555515f <+15>: mov -0x4(%rbp),%edi >>> 0x0000555555555162 <+18>: call 0x555555555130 >>> 0x0000555555555167 <+23>: mov -0x4(%rbp),%edi >>> => 0x000055555555516a <+26>: call 0x555555555140 >>> >>> 12 } >>> 0x000055555555516f <+31>: xor %eax,%eax >>> 0x0000555555555171 <+33>: add $0x10,%rsp >>> 0x0000555555555175 <+37>: pop %rbp >>> 0x0000555555555176 <+38>: ret >>> End of assembler dump. >>> (gdb) reverse-step >>> func1 (i=1) at reverse.c:3 >>> 3 } >>> (gdb) >>> >>> We can see that GDB stopped on the call instruction instead. So a user that finished from func1 or reverse-finished from func2 may see different inferior states. > >> Seeing different inferior states is expected, as finish and reverse-finish are not the exact mirror of one another, like step >> and reverse-step are. The exact reversal of finish would be the equivalent of being stopped at a function call return insn after >> a "finish" (and the command could only be used while stopped there), and stepping back into the function up until the point >> where you had typed "finish" and stopping there. Obviously impossible to implement. So we made "reverse-finish" do something >> sensible, such as stepping backwards up until the call site. > > Hi Pedro, > > I certainly agree with you that reverse-step needs to be fixed, > and this explains at least part of the problems we were seeing. > > However, I do think there is still another issue specific to > reverse-finish, along the lines Bruno pointed out. And in fact, > I do think that there is (or at least should be!) a well-defined > symmetry between finish and reverse-finish: > > The effect of "finish" is: skip until the end of the current > function and then do a "step". (Semantically equivalently, > do a series of "next" until you leave the current function.) But that this is not actually true -- this is not how finish is implemented. Instead, we unwind to the caller frame, and put a breakpoint at that frame'c PC, and run freely to that. A frame's PC is defined as the address of the instruction that is executed once the callee returns. OTOH, a (forward) step at the return line of a function steps until a different line is reached, and in the case we step out of a function, once it reaches the caller it notices we ended up in the middle of a line so it continues stepping until the next line. Note that finish vs step difference visible here: (gdb) list 1 1 int func1 (int i) 2 { 3 return i + 1; 4 } 5 6 int func2 (int i) 7 { 8 return i + 1; 9 } 10 11 int main (int argc, char **argv) 12 { 13 func1 (func2 (argc)); 14 return 0; 15 } (gdb) (gdb) b func2 Breakpoint 1 at 0x1147: file finish.c, line 8. (gdb) r Starting program: /home/pedro/finish [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, func2 (i=1) at finish.c:8 8 return i + 1; (gdb) finish Run till exit from #0 func2 (i=1) at finish.c:8 0x000055555555516c in main (argc=1, argv=0x7fffffffdcb8) at finish.c:13 <<< stopped in the middle of the line, as indicated by address on the left 13 func1 (func2 (argc)); Value returned is $1 = 2 <<< at this location we can use ABI knowledge to retrieve the return value (gdb) p $pc $2 = (void (*)()) 0x55555555516c <<< matches the "0x000055555555516c in main" above, of course (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/pedro/finish [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, func2 (i=1) at finish.c:8 8 return i + 1; (gdb) step 9 } <<< stopped a line bounary, and stepped over the func1 call as well! (gdb) p $pc $3 = (void (*)()) 0x55555555514d > > Similarly, the effect of "reverse-finish" *should* be: reverse-skip > until the beginning of the current function and then do a reverse-step. > (Or semantically equivalent, do a series of "reverse-next" until you > leave the current function.) I disagree, because that reverse-step would step backwards too much. Instead of stepping back to the call of the function, it would step back further, as reverse-step will try to stop at the beginning of a line. By doing that, you'll potentially step backwards more statements that exist in the same line. Like: a = 1; b = 2; func(); stepping back from inside func should stop at the first instruction of that whole line. But finishing backwards should stop at the call to func(), without considering line boundaries, just like forward finish does not. >From the manual: "Like the step command, reverse-step will only stop at the beginning of a source line. It “un-executes” the previously executed source line." > > However, the actual implementation of reverse-finish is subtly but > significantly different: it reverse-skips until the beginning of the > current function and then does a reverse-stepi (not reverse-step). > > This has the at least surprising, but IMO even incorrect, effect > that when on the first line of a function, "reverse-finish" ends > up in a different place than "reverse-step". I believe they > ought to end up in the same place. I disagree. Pedro Alves > > > This was one of the primary intentions behind Carl's patch: change > reverse-finish so it does a reverse-step instead of a reverse-stepi. > (Of course, for this to be useful, reverse-step itself needs to work > correctly - which it doesn't right now as you point out.) > > Bye, > Ulrich >