From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id y+WJEGRbdWmfhhMAWB0awg (envelope-from ) for ; Sat, 24 Jan 2026 18:53:08 -0500 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=D0CyjFXt; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 3237F1E0AD; Sat, 24 Jan 2026 18:53:08 -0500 (EST) 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 5B8131E089 for ; Sat, 24 Jan 2026 18:53:07 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id BE4C94BA23E5 for ; Sat, 24 Jan 2026 23:53:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BE4C94BA23E5 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=D0CyjFXt Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id CEAF64BA23ED for ; Sat, 24 Jan 2026 23:52:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CEAF64BA23ED 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 CEAF64BA23ED Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769298759; cv=none; b=SVQlyHjrWzBA8i8jjmJwolokzw4kgcOWcWIe9XM0P1/Ni8DCaMFU0zHkeayr4/XXxmPrffhv6mBVBgK1bafIvQSfNJFG9zFEQyOzt/YWHRsVlynOkAULszmBXzMzoU7fmFU6Mw+lpzMu2dyaaoCHkRRNauakd+/JrFlG+0TQtME= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769298759; c=relaxed/simple; bh=g9BIud7+ytorcgZ/i5zmHaAh/DzzMD2yPxibZNnlq0Q=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=nD2QBIT8n0YaqaXkF+P4/h7AkoLDaO1zVKeHRFxIeGE4gdX3eJOfjO5ljFiVUwCCCuW93hPDu7tVyyhlHYX5PkRTBDBiB9VJJ6nKqalF6c27KBd9hrm8euuoPJdNSMe2yjygBFtSgXkUtYVSdhxlO/JXRf3b7kTNMdPw/2K9A/I= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CEAF64BA23ED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1769298759; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k14Hgn6uFxpzTzpOnuzD+Jhc1wqZ7eDHvSCJB+gYYXs=; b=D0CyjFXtfF257vWWnt+TPkjINq9nuknjfbdYm9iBEBSJK0N56Wd76yqUWYif4BKJ9IY+f3 JdY/m/HCpfxzomlzGHFDJFJaXTbukqnqIpUoyPYTR5nPWbhY2R2uQ3YAnf4UQHdxBm5BEo Aa9TEDRy8ajIRA1VkYi/xGPC3UcQ0UE= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-252-FasY5OupNvqxR8SvA-il8Q-1; Sat, 24 Jan 2026 18:52:38 -0500 X-MC-Unique: FasY5OupNvqxR8SvA-il8Q-1 X-Mimecast-MFC-AGG-ID: FasY5OupNvqxR8SvA-il8Q_1769298757 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2FB1418003FC; Sat, 24 Jan 2026 23:52:37 +0000 (UTC) Received: from f42-mesa-1 (unknown [10.22.64.64]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 42C861955F66; Sat, 24 Jan 2026 23:52:36 +0000 (UTC) Date: Sat, 24 Jan 2026 16:52:33 -0700 From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Tom de Vries , Andrew Burgess Subject: Re: [PATCH v2] [gdb/testsuite] Fix gdb.base/inline-frame-cycle-unwind.exp for s390x (alternative) Message-ID: <20260124165233.7dabaf09@f42-mesa-1> In-Reply-To: <20260121122543.4129049-1-tdevries@suse.de> References: <20260121122543.4129049-1-tdevries@suse.de> Organization: Red Hat MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: LvAWl8d7rhTj6M9K8PBEoKZ5r2QJuHruLcJtQ7exnHg_1769298757 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit 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 Tom, Andrew, FWIW, I'm fine with the approach taken here. I prefer it over my attempt to fix these failures for s390x. Regarding the commit log - I'd like to see it written up in a way where all of the context is supplied, including a description of the problem being solved. (I see that Andrew has offered to work on the commit log and that Tom has accepted - that'd be great, IMO.) Kevin On Wed, 21 Jan 2026 13:25:43 +0100 Tom de Vries wrote: > From: Andrew Burgess > > With test-case gdb.base/inline-frame-cycle-unwind.exp on s390x-linux, I > run into: > ... > (gdb) bt > #0 inline_func () at inline-frame-cycle-unwind.c:49 > #1 normal_func () at inline-frame-cycle-unwind.c:32 > #2 0x000000000100065c in inline_func () at > inline-frame-cycle-unwind.c:45 #3 normal_func () at > inline-frame-cycle-unwind.c:32 Backtrace stopped: previous frame > identical to this frame (corrupt stack?) (gdb) FAIL: $exp: bt: cycle at > level 5: backtrace when the unwind is broken \ at frame 5 > ... > > In contrast, on x86_64-linux, I get: > ... > (gdb) bt > #0 inline_func () at inline-frame-cycle-unwind.c:49 > #1 normal_func () at inline-frame-cycle-unwind.c:32 > #2 0x0000000000401157 in inline_func () at > inline-frame-cycle-unwind.c:45 #3 normal_func () at > inline-frame-cycle-unwind.c:32 #4 0x0000000000401157 in inline_func () > at inline-frame-cycle-unwind.c:45 #5 normal_func () at > inline-frame-cycle-unwind.c:32 Backtrace stopped: previous frame > identical to this frame (corrupt stack?) (gdb) PASS: $exp: bt: cycle at > level 5: backtrace when the unwind is broken \ at frame 5 > ... > > Let's first see what happens on x86_64-linux. > > The test-case installs a custom unwinder, which gets triggered with > pending_frame.level() == 5. > > The responsibility of the unwinder at that point is to: > - calculate a frame ID for the pending frame, and > - provided the register values for the previous frame (with level > pending_frame.level() + 1), as saved in the pending frame. > > However, the custom unwinder does some else. While it does calculate the > frame ID for the pending frame, instead it provides the register values > for the pending frame, which causes the unwinder to stop. > > After adding some debugging prints, we can see that the frame ID > calculated by the custom unwinder: > ... > LEVEL: 5 > FrameID: sp: 7fffffffcd50, pc: 401116 > ... > matches the frame ID as calculated by GDB: > ... > (gdb) maint print frame-id 5 > frame-id for frame #5: > {stack=0x7fffffffcd50,code=0x0000000000401116,!special} ... > > Now back to s390x-linux. > > This time, the frame ID calculated by the custom unwinder: > ... > LEVEL: 5 > FrameID: sp: 3ffffffe8d0, pc: 1000608 > ... > does not match the frame ID as calculated by GDB: > ... > (gdb) maint print frame-id 5 > frame-id for frame #5: > {stack=0x3ffffffe970,code=0x0000000001000608,!special} ... > > Instead, it matches the frame ID for frame #3: > ... > (gdb) maint print frame-id 3 > frame-id for frame #3: > {stack=0x3ffffffe8d0,code=0x0000000001000608,!special} ... > > Fix this by using "maint print frame-id" to get all frame-ids, and using > those instead. > > Tested on x86_64-linux and s390x-linux. > > Co-Authored-By: Tom de Vries > --- > .../gdb.base/inline-frame-cycle-unwind.exp | 3 + > .../gdb.base/inline-frame-cycle-unwind.py | 58 +++++++++++++------ > 2 files changed, 43 insertions(+), 18 deletions(-) > > diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp > b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp index > cc9585ee325..fd9cba78f9a 100644 --- > a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp +++ > b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp @@ -72,6 +72,9 @@ > gdb_continue_to_breakpoint "stop at test breakpoint" gdb_test_no_output > "source ${pyfile}"\ "import python scripts" > > +# Print the captured frame IDs. > +gdb_test "python print_frame_ids()" > + > # Test with and without filters. > foreach bt_cmd { "bt" "bt -no-filters" } { > with_test_prefix "$bt_cmd" { > diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py > b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py index > 80cfb864f21..09ddfb7e536 100644 --- > a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py +++ > b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py @@ -13,6 +13,8 @@ > # You should have received a copy of the GNU General Public License > # along with this program. If not, see . > > +import re > + > import gdb > from gdb.unwinder import Unwinder > > @@ -21,10 +23,14 @@ from gdb.unwinder import Unwinder > # was written for. > stop_at_level = None > > -# Set this to the stack frame size of frames 1, 3, and 5. These > -# frames will all have the same stack frame size as they are the same > -# function called recursively. > -stack_adjust = None > +# List of FrameId instances, one for each stack frame. > +frame_ids = [] > + > + > +def print_frame_ids(): > + for i in range(len(frame_ids)): > + fid = frame_ids[i] > + print("frame-id for frame #%s: {stack=0x%x,code=0x%x}" % (i, > fid.sp, fid.pc)) > > class FrameId(object): > @@ -49,16 +55,25 @@ class TestUnwinder(Unwinder): > if stop_at_level is None or pending_frame.level() != > stop_at_level: return None > > - if stack_adjust is None: > - raise gdb.GdbError("invalid stack_adjust") > + if len(frame_ids) < stop_at_level: > + raise gdb.GdbError("not enough parsed frame-ids") > > if stop_at_level not in [1, 3, 5]: > raise gdb.GdbError("invalid stop_at_level") > > - sp_desc = pending_frame.architecture().registers().find("sp") > - sp = pending_frame.read_register(sp_desc) + stack_adjust > - pc = (gdb.lookup_symbol("normal_func"))[0].value().address > - unwinder = pending_frame.create_unwind_info(FrameId(sp, pc)) > + # We're unwinding frame #n (n == pending_frame.level()), and are > + # expected to return: > + # - a frame ID for frame #n, and > + # - the register values for frame #(n+1), as saved in frame #n > + # > + # Instead, we return the frame ID for frame #n, and the register > + # values for frame #n. > + # > + # This will cause the backtrace stop at level #n, meaning: > + # - the entry for frame #n will be printed. > + # - the entry for frame #(n+1) will not be printed, instead > + # "Backtrace stopped: " will be printed. > + unwinder = > pending_frame.create_unwind_info(frame_ids[stop_at_level]) > for reg in pending_frame.architecture().registers("general"): > val = pending_frame.read_register(reg) > @@ -76,11 +91,18 @@ gdb.unwinder.register_unwinder(None, TestUnwinder(), > True) # > # main -> normal_func -> inline_func -> normal_func -> inline_func -> > normal_func -> inline_func # > -# Compute the stack frame size of normal_func, which has inline_func > -# inlined within it. > -f0 = gdb.newest_frame() > -f1 = f0.older() > -f2 = f1.older() > -f0_sp = f0.read_register("sp") > -f2_sp = f2.read_register("sp") > -stack_adjust = f2_sp - f0_sp > +# Iterate through frames 0 to 6, parse their frame-id and store it > +# into the global FRAME_IDS list. > +for i in range(7): > + # Get the frame-id in a verbose text form. > + output = gdb.execute("maint print frame-id %d" % i, to_string=True) > + > + # Parse the frame-id in OUTPUT, find the stack and code addresses. > + match = re.search(r"stack=(0x[0-9a-fA-F]+).*?code=(0x[0-9a-fA-F]+)", > output) > + if not match: > + raise gdb.GdbError("Could not parse frame-id for frame #%d" % i) > + > + # Create the FrameId object. > + sp_addr = int(match.group(1), 16) > + pc_addr = int(match.group(2), 16) > + frame_ids.append(FrameId(sp_addr, pc_addr)) > > base-commit: 5606bf89ba974005089bb39bd23e944973fe60eb > -- > 2.51.0 >