From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id yVqkKdTnb2l1GQ0AWB0awg (envelope-from ) for ; Tue, 20 Jan 2026 15:38:44 -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=DnvTefSZ; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id A6BE41E0AD; Tue, 20 Jan 2026 15:38:44 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.1 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_SBL_CSS,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=no 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 BDD421E089 for ; Tue, 20 Jan 2026 15:38:43 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 3F5E04BBCDF3 for ; Tue, 20 Jan 2026 20:38:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3F5E04BBCDF3 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=DnvTefSZ 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 5DD544BA9001 for ; Tue, 20 Jan 2026 20:38:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5DD544BA9001 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 5DD544BA9001 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1768941495; cv=none; b=Mkwq9AP9bRZzg9oIUDmg2Z1HrSiEBqxA9btljGaxr2z7DxDhxULf0UmQ6HWCehhM3TK6EQYNpJcbBo528+hch8Jl9KQ0WYUbRR4d7djoj3i7bSRLbaaoV/CDtoM+/5FNSU+kMMxVnYt3YRnCHuM4R7GDBsn5odwApe64dx3sMvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1768941495; c=relaxed/simple; bh=QA//vntiuVMeCUgFKr/aerMW/VU4g4/IE82uXG1tFXU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Bgbwt7TIg5A0xbVxFuxxWSqYhXAtM2I9d7y1dAJk52k/6wsBzTj18ydSWWnFEQkFw3WjNCaG+75XVGTkDyccLs65+6KmNKL55SiyoAnb380a1yspGDfPvWzQnIhPFWYHWG6OYDCMkjdEJCoORwWs64jAR7Ni1BfXYFF0Zi6v9HQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5DD544BA9001 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768941495; 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=DhY5Ua6z9/C3h6Syu8HcwEkfBPPBXFnmSZlSTOzo/fk=; b=DnvTefSZwEWHtl4CNDO3lkSBnf80ob8YYyJn0QQ1UO9FNo9ldFkcCgbfAHvoe91bKfEUci p2IiG2MvL+vY7R1VF3AJIiMDlYz+W2etZIUkVAF7MGu8wZBPVta73jGtFzYroBr265wyAt exyBhq7zsCtgY+H/HGw2ze/9dquoVpY= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-379-gSfbEEa_PruE_oZ6a-lFFQ-1; Tue, 20 Jan 2026 15:38:13 -0500 X-MC-Unique: gSfbEEa_PruE_oZ6a-lFFQ-1 X-Mimecast-MFC-AGG-ID: gSfbEEa_PruE_oZ6a-lFFQ_1768941492 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-431054c09e3so5057152f8f.0 for ; Tue, 20 Jan 2026 12:38:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768941492; x=1769546292; 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=DhY5Ua6z9/C3h6Syu8HcwEkfBPPBXFnmSZlSTOzo/fk=; b=T6cR2Npf+X+KAMq3mnhWvW0T2VJQfTKBdxFHSjKIc45i7zj8DlvYyYE/ofVR0kaC4V DX8Sd/dEGZCOLIyWHtkeT8uS4b0KHqT5xqPqu/xwZtcb5xrzuBRYlpLIRA0PlQ7R7eXH 4cAzJ+zvWgMOtbMfhLUGZJwFmQf9nEP+fIRs/emTcOGXfYSGfjWr7wjV250fc+bIYWDL KPI0/IoyhBY3Qu6re9W3gbO4VqYYELtmlYGkOtPKbeIb1kTydYkpWKrUdqte2sVE+b67 VYY72el9hoXHzAfz9P3YWq4jY+iW855/K4OnwrYAu1KKe53uWhdx5/gCWG2uQycDRlJZ fsDg== X-Forwarded-Encrypted: i=1; AJvYcCVWb/X+KcGQeSCwyYGyJaVuBqLa8WJh/PjBaq7BoGFHf9ur7GG2eaph1gXvuSin5GOmUsX+JY1vohgxJg==@sourceware.org X-Gm-Message-State: AOJu0Yz4c1+IZ7pymPrZwnb6GbPqKvIFJK64m9eDDEiLlSEP3LOwH3Zv p+CwgPkmureoArCQj3cXtieLcdik3t8iaupxHTlDhvTVjk1egdct8CLDqgjlKqZWgHrjrp2UQsC 14NXEfGfL+T8ltHsfmebUQpRTF+qFPfWfF22UUboJVv5whlD0Iq6QsCqANsTr14g+86U3mKU= X-Gm-Gg: AY/fxX6Ea/TEoEVXOKPCEsEa3c0VBPojIPm5pgNE6C+SBLa34w4nSfz4RjFAdVBK/VW hQKu2k2zQ7JdbcSQsDvt635Cw/tXxG/3vM8APLuuT+FVdSbD7X1lpkb3mjaQJ3rmFuONJABKUmL 1vl3120T4n1maG6uuiifGt3kV5LED5KafVUOHRQ6yoMkI1J/Hw9728cvBYqLQQPsZY69rScIXXH K+49EQEeJ12fDvXt6BqCQWlSrleeiFMDF86LqeCxTa5IpMf6M6ef8t3DCiX5GNhrHtD/Fxo91Ia +XgQEEE6wNqwv8iHb1RpONwNCErkljKonwEYOEzhXLtsZJufXvucY5zEAaBuNo9SvJK/iAmD0FY 6a+kP2MufnnukoT9yoHQmcwsR3TcPXV/c/Q== X-Received: by 2002:a05:600c:19d0:b0:477:63b5:6f76 with SMTP id 5b1f17b1804b1-4801e3444f4mr209266575e9.25.1768941491777; Tue, 20 Jan 2026 12:38:11 -0800 (PST) X-Received: by 2002:a05:600c:19d0:b0:477:63b5:6f76 with SMTP id 5b1f17b1804b1-4801e3444f4mr209266305e9.25.1768941491284; Tue, 20 Jan 2026 12:38:11 -0800 (PST) Received: from localhost (92.40.184.235.threembb.co.uk. [92.40.184.235]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4801e886829sm262621765e9.8.2026.01.20.12.38.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jan 2026 12:38:10 -0800 (PST) From: Andrew Burgess To: Tom de Vries , gdb-patches@sourceware.org Subject: Re: [PATCH] [gdb/testsuite] Fix gdb.base/inline-frame-cycle-unwind.exp for s390x (alternative) In-Reply-To: <87a4y8qru0.fsf@redhat.com> References: <20251211133946.962934-1-tdevries@suse.de> <87a4y8qru0.fsf@redhat.com> Date: Tue, 20 Jan 2026 20:38:09 +0000 Message-ID: <877btchvf2.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: X2P_zY915syh7fnhJrBOnajfi8fG3rjQXMUgG2ImXk4_1768941492 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 Andrew Burgess writes: > Tom de Vries writes: > >> With test-case gdb.base/inline-frame-cycle-unwind.exp on s390x-linux, I run >> into: >> ... >> (gdb) bt^M >> #0 inline_func () at inline-frame-cycle-unwind.c:49^M >> #1 normal_func () at inline-frame-cycle-unwind.c:32^M >> #2 0x000000000100065c in inline_func () at inline-frame-cycle-unwind.c:45^M >> #3 normal_func () at inline-frame-cycle-unwind.c:32^M >> Backtrace stopped: previous frame identical to this frame (corrupt stack?)^M >> (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^M >> #0 inline_func () at inline-frame-cycle-unwind.c:49^M >> #1 normal_func () at inline-frame-cycle-unwind.c:32^M >> #2 0x0000000000401157 in inline_func () at inline-frame-cycle-unwind.c:45^M >> #3 normal_func () at inline-frame-cycle-unwind.c:32^M >> #4 0x0000000000401157 in inline_func () at inline-frame-cycle-unwind.c:45^M >> #5 normal_func () at inline-frame-cycle-unwind.c:32^M >> Backtrace stopped: previous frame identical to this frame (corrupt stack?)^M >> (gdb) PASS: $exp: bt: cycle at level 5: backtrace when the unwind is broken \ >> at frame 5 >> ... I took a look at this issue. I'm running out of time today, so I thought I'd just dump what I've seen so far. Here's a table I made for x86-64: | Level | $frame_base | $sp | $code | Type | |-------+----------------+----------------+----------+--------+ | 0 | 0x7fffffffa560 | 0x7fffffffa550 | 0x401128 | inline | | 1 | 0x7fffffffa560 | 0x7fffffffa550 | 0x401106 | normal | | 2 | 0x7fffffffa570 | 0x7fffffffa560 | 0x401128 | inline | | 3 | 0x7fffffffa570 | 0x7fffffffa560 | 0x401106 | normal | | 4 | 0x7fffffffa580 | 0x7fffffffa570 | 0x401128 | inline | | 5 | 0x7fffffffa580 | 0x7fffffffa570 | 0x401106 | normal | | 6 | 0x7fffffffa590 | 0x7fffffffa580 | 0x401189 | normal | |-------+----------------+----------------+----------+--------+ The $frame_base and $code are what we see in the frame-id, and $sp is the stack pointer ($sp) register in each frame. Notice the relationship between $frame_base and $sp as we move up the stack; as we move past each inline/normal frame pair the previous $frame_base becomes the $sp value. This makes sense to me. As a result of this the difference between $frame_base values is the same as the difference between $frame_base and $sp values. Here's the same table for s390: | Level | $frame_base | $sp | $code | Type | |-------+---------------+---------------+-----------+--------+ | 0 | 0x3ffffff7898 | 0x3ffffff7758 | 0x1000620 | inline | | 1 | 0x3ffffff7898 | 0x3ffffff7758 | 0x10005f0 | normal | | 2 | 0x3ffffff7938 | 0x3ffffff77f8 | 0x1000620 | inline | | 3 | 0x3ffffff7938 | 0x3ffffff77f8 | 0x10005f0 | normal | | 4 | 0x3ffffff79d8 | 0x3ffffff7898 | 0x1000620 | inline | | 5 | 0x3ffffff79d8 | 0x3ffffff7898 | 0x10005f0 | normal | | 6 | 0x3ffffff7a78 | 0x3ffffff7938 | 0x1000698 | normal | |-------+---------------+---------------+-----------+--------+ There are a couple of things here that I find are unexpected, but are probably a result of me not understanding the s390 ABI well enough. First, and this is not relevant to the test failure, but the inline and normal (non-inline) frames don't have the same $code address. I double checked the disassembly for frame #0, and it does appear like the function has been inlined, but maybe I'm wrong on this. This means that GDB manages to find some address within the function and claims this is the "start" of the inlined function. Weird. But like I said, I don't think this is really an issue for this test. Second, the difference between $frame_base values is 0xa0, and the difference between $sp values is also 0xa0. This is reassuring, each recursive frame moves 0xa0 bytes down the stack. But the difference between $sp and $frame_base values is 0x140 bytes. This was a little unexpected. But, I guess, this is fine. The DWARF spec doesn't (as far as I know) claim that the frame base has to mean anything specific, it's just an address that's unique to a frame, and from which we can offset to find frame local data. However, the test tries to calculate the frame #5 $frame_base address by taking the difference between frame #2 and frame #0 $sp value, and adding this difference to the frame #5 $sp value. For most architectures this works fine. But clearly this isn't going to work for s390. I don't have time right now, but tomorrow I'll double check the two weird things above, I'd like to confirm these really are how the DWARF defines things. But assuming it is, then I think your proposed solution is the right way to go; though I think the commit message needs updating to reflect the above. Having spent some time now running and debugging this test, I think one neat thing about the way it was originally written, is that the Python script could be used stand-alone, so long as the test program was stopped in the right place you could source the Python script and it would do the right thing. You proposed patch changes this slightly so that the .exp script is needed to setup some of the frame-id data. That's absolutely fine, but can make the test harder to run outside DejaGNU; if the stack addresses change the user needs to figure out the updated values. It's a really minor thing, but how about the patch below (still needs a commit message), but this does more of the work in the Python script again. Thanks, Andrew -- diff --git i/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py w/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py index 80cfb864f21..974d40d9219 100644 --- i/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py +++ w/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.py @@ -13,6 +13,7 @@ # 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,11 +22,8 @@ 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 = [] class FrameId(object): def __init__(self, sp, pc): @@ -49,16 +47,13 @@ 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)) + 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 +71,22 @@ 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 5, parse their frame-id and store it +# into the global FRAME_IDS list. +for i in range(6): + # Select the specific frame. Use to_string to suppress output. + gdb.execute(f"frame {i}", to_string=True) + + # Get the frame-id in a verbose text form. + output = gdb.execute("maint print frame-id", 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 match: + # 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)) + else: + raise gdb.GdbError("Could not parse frame-id for frame #%d" % i)