From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id YI6/J3IdK2qjGwIAWB0awg (envelope-from ) for ; Thu, 11 Jun 2026 16:41:22 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Nq8301pP; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 6A58E1E070; Thu, 11 Jun 2026 16:41:22 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 938DF1E070 for ; Thu, 11 Jun 2026 16:41:21 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1C5064BA23D6 for ; Thu, 11 Jun 2026 20:41:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1C5064BA23D6 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Nq8301pP Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 61A194BA23D3 for ; Thu, 11 Jun 2026 20:40:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 61A194BA23D3 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 61A194BA23D3 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1781210435; cv=none; b=ZJULlnh9NSWBV5TZJuPWalkvBFXcVIPykZH6ATGRfeyxXQjopx4L3sREicP2AQrf2HOvS0rKPnYZoNUIjFJSd0xCP65Ayxdn9T9QLRBWPMVQ5Q8BXihPhAO7spCi0B6qqX3bIO4ZfS9rmn5ek9s+B9wQ0W2iUsY2+7qp0s6D6y4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1781210435; c=relaxed/simple; bh=czay2CR17/tEBAib3RCw69xD0vtcBQFk6ekpZQgSnvs=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DXGw6RxLJ1aw3DlXXGhUrIBbN/2sXTK1s7HtBXo7FsEYOigdRoq1YC9SE7uDNNc7lYOEh0SfvR/UmKlwcEVeo0atMEOAyezIkw9Lwb1yBMlCJ068/AV1kb4wyReX5RJ7OYm2H3OeEPqmu/AAivtm8s6FWCfWl7TtVjCZjXmUFQE= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Nq8301pP DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61A194BA23D3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1781210435; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=jEPVmQG18103Aay+vdWTnScIu3KiPMglbwf8Jj2CmtM=; b=Nq8301pPj+9/d/A2DmReO+pOo+IOL+PC+iVVaEafghr+RckAl9kEOdJRKxfjttp8NIv5o9 DzUlXMe4kiQkZRlM4K2MVg8XeVx1ZT6gbrPYB5mBib+d/KUf88t/s+lW4u09yCPjsbWnou q6XLjvvc0/urQQoDOgFXfmFASROoU10= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-627-DkM5zwXvOiyhJAwgRnYwmA-1; Thu, 11 Jun 2026 16:40:33 -0400 X-MC-Unique: DkM5zwXvOiyhJAwgRnYwmA-1 X-Mimecast-MFC-AGG-ID: DkM5zwXvOiyhJAwgRnYwmA_1781210433 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-46016bedbaaso151601f8f.1 for ; Thu, 11 Jun 2026 13:40:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781210432; x=1781815232; h=mime-version:message-id:date:references:in-reply-to:subject:to:from :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=jEPVmQG18103Aay+vdWTnScIu3KiPMglbwf8Jj2CmtM=; b=T/o6Zd62miklAPTlrDxLamMWNrctGKE6qmso76Ktcl9lQBIFgDiUisTA/z5mgmYtY/ 5C2kKjN5HLTgRCuSALN2ZTtSkNcCbL4GVwnzE98vMnNt5+fABQNXjXrMSvnhRAFJMofF jQnfbjqDbaPBQc4qVFF1XXbIWhxBbypQY5umVquM22Qmo2dG4chTTsZaF4WrhVtDUxsC VPMZvCEIcYEBVoMGtSesFiYo6DPw6Bjd6NcDSx5StDv08hEpOaFzSL2fjAPkft5UwSLa vE98l/RNlifJHbetmwtfkAw1g6rFeQt8qQwF2hXeV5s34JVi2d+HFppHYRtdURoh0bJR E2VA== X-Forwarded-Encrypted: i=1; AFNElJ93u4vnAPLI0Sd8VvImEn5UFw5OZP7bUq7+c0+79D88AvNUTRV5cs/yUvlfypNB5T60AmuQLZCG+zV0Ow==@sourceware.org X-Gm-Message-State: AOJu0YzlhS7XUJ6aqdzuz4vmydXEA8WgROj6lpqbPlqBTjo3F8UwkUIt WhGZJFN1irj6E962F33kOmeNgOC/x9zZpbUHjF36L4UaTOjCXLBcp3Q0uCliUZwn/KUx7moIave HHj1uisSuqqjW32aSCQ9QjZa4Ht0h4DFvmyHDrM8VUiz+mb4Q4/FgjDoYqVquNUM= X-Gm-Gg: Acq92OE+Qs/X0goYl3niZkLgOQke6YAIm4ZEpFQDbYGAtN74VFFa7uvnX0A0xMwsocl c/22N4yRG1BOu3dXf36pauQ40yF0muTB8+gdSeKJiQ4C1qHojNRKgMim1Bdxu6fO8eJbjzAzuZj lfDXrXyxMYjYNLyGf+wdXyB0q0CWbGOCCLjjYSFWFplRn8m7j+VWtW/905ubLYlQvALqxCUSupX b51Ec1bt0TslPpyGyKUlVBodZbJCJYADRTBG46JM4gzLl7T1WI5QeKAvWjF3vEjp7zsfyWW9Ssi s+KJ4oiBVyLnJWlsWO0MAdOjnXuzS/Ee51VSZ5hAHo2AI3cF0zh+w9Ftk7h7gDghlUeERzzT6pv wNRXsZEnTDpdQO9lx/DNIkziPB75aBtDrFsQQkxZ6 X-Received: by 2002:a05:6000:1acb:b0:460:1bf8:c981 with SMTP id ffacd0b85a97d-4606da57c41mr44612f8f.5.1781210432594; Thu, 11 Jun 2026 13:40:32 -0700 (PDT) X-Received: by 2002:a05:6000:1acb:b0:460:1bf8:c981 with SMTP id ffacd0b85a97d-4606da57c41mr44585f8f.5.1781210432077; Thu, 11 Jun 2026 13:40:32 -0700 (PDT) Received: from localhost (19.81.93.209.dyn.plus.net. [209.93.81.19]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4606c0c9b02sm1650765f8f.13.2026.06.11.13.40.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jun 2026 13:40:31 -0700 (PDT) From: Andrew Burgess To: Guinevere Larsen , gdb-patches@sourceware.org Subject: Re: [PATCH] gdb: allow 'until' to work in outermost frame In-Reply-To: <02e967d8-a06a-4774-8618-e8fddd665c26@redhat.com> References: <41fe591d58ba010fa771e80ca674b61e30feef2f.1780942441.git.aburgess@redhat.com> <02e967d8-a06a-4774-8618-e8fddd665c26@redhat.com> Date: Thu, 11 Jun 2026 21:40:30 +0100 Message-ID: <87o6hgq08x.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: LzhyDQogTvp18Rl0SNfJgLRlrB2E37Fys1O1JvLf2iA_1781210433 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Guinevere Larsen writes: > On 6/8/26 3:14 PM, Andrew Burgess wrote: >> The 'until' command with an argument, e.g. 'until *ADDRESS', is >> implemented by the until_break_command in breakpoint.c. >> >> The most important thing this function does is convert the location >> argument '*ADDRESS' in my example, into a vector of symtab_and_line >> objects. Each of these symtab_and_line objects is then used to create >> a temporary bp_until breakpoint. >> >> The other thing that until_break_command does is create a breakpoint >> in the caller frame. This breakpoint is there to ensure the inferior >> stops upon exiting the frame in which the 'until' command was issued. >> >> When compiling an assembler file into a static test program, if I use >> 'starti' to stop the inferior within the outermost frame, and then try >> to use 'until *ADDRESS' I see the following error: >> >> (gdb) starti >> Starting program: /tmp/hello >> >> Program stopped. >> 0x0000000000401000 in _start () >> (gdb) bt >> #0 0x0000000000401000 in _start () >> (gdb) until *0x0000000000401015 >> Warning: >> Cannot insert breakpoint 0. >> Cannot access memory at address 0x1 >> >> Command aborted. >> (gdb) >> >> The problem here is the breakpoint that 'until' tries to create in the >> caller frame. Though the 'bt' in the above example indicates that >> there is only a single frame, the outermost frame, this is only >> because GDB has specific code in get_prev_frame to stop the backtrace >> at the outermost frame. If we turn this off and try 'bt' again: >> >> (gdb) set backtrace past-entry on >> (gdb) bt >> #0 0x0000000000401000 in _start () >> #1 0x0000000000000001 in ?? () >> #2 0x00007fffffffac73 in ?? () >> #3 0x0000000000000000 in ?? () >> (gdb) >> >> What we are seeing here is the garbage values that happen to be in the >> registers tricking GDB into thinking there are frames before _start. >> >> GDB's code to handle this is in get_prev_frame, however, when 'until' >> creates the caller frame breakpoint it calls frame_unwind_caller_pc >> which calls frame_unwind_caller_frame, which skips get_prev_frame and >> calls get_prev_frame_always. As a result, the 'until' command will >> try to place a breakpoint in the bogus frame #1 shown above. As the >> frame is at address 0x1, which is non-writable, we see an error when >> trying to insert the breakpoint. >> >> In this commit I propose that we share the outer frame detection logic >> between get_prev_frame and frame_unwind_caller_frame. When 'backtrace >> past-entry' is off, which is the default, frame_unwind_caller_frame >> will return NULL for the outermost frame. This means that a command >> like 'until *ADDRESS' will no longer try to create a breakpoint in the >> caller frame when used in the outermost frame. > > Why not simply change frame_unwind_caller_frame to call get_prev_frame > instead of get_prev_frame_always? feels like it would be a better idea > to not assume that the caller is always available anyway, rather than > porting the bits of work-arounds back to it That's a great question. get_prev_frame presents a "user" configured view of the backtrace, for example it will stop at 'main', or the user can adjust the number of visible frame with 'set backtrace limit N'. In these cases it is possible that get_prev_frame will return NULL indicating that there is no previous frame, when in reality, there is a previous frame. In the context of the "until" command, where we want to place a breakpoint in the caller frame, we want that breakpoint created even if the user wouldn't normally see the caller frame in the 'bt' output. As a concrete example, if a user makes use of 'until' in the 'main' function, but the 'until' line is not hit, then GDB should stop upon return from 'main'. If we used get_prev_frame that wouldn't happen as the previous frame is usually hidden from the user. The entry frame is different. The entry frame is the very first frame, and there are no earlier frames. But, that doesn't mean that GDB doesn't see earlier frames! If the inferior starts with garbage in its registers then GDB might think there are frames before the entry frame, but the chances are these frames are completely bogus, and trying to place a breakpoint in them will only cause problems (e.g. cannot write to memory errors). If we look at all the checks in get_prev_frame there are: 1. Should the unwind stop at main? This check should be ignored for things like 'until'. 2. Has the user backtrace limit been reached? This check should be ignored for things like 'until'. 3. Has the entry frame been reached? I think this check should apply in the 'until' case. 4. Have we reached a frame with a zero $pc? I'm unsure about this one, so chose to ignore it for now. It's possible that this should also apply in the 'until' case, but I've chosen to ignore this case for now without a motivating example. A final note, I'm about to post a V2 for this patch, as what I posted here still has some problems. Thanks, Andrew