From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id OwVqN0aeYGVZHw4AWB0awg (envelope-from ) for ; Fri, 24 Nov 2023 07:59:50 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-armh-onmicrosoft-com header.b=AEO+ce5H; dkim=pass (1024-bit key) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-armh-onmicrosoft-com header.b=AEO+ce5H; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D3A251E0D2; Fri, 24 Nov 2023 07:59:50 -0500 (EST) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (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 B87E71E091 for ; Fri, 24 Nov 2023 07:59:48 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1B7FB3857011 for ; Fri, 24 Nov 2023 12:59:48 +0000 (GMT) Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on2047.outbound.protection.outlook.com [40.107.8.47]) by sourceware.org (Postfix) with ESMTPS id E3E023858D3C for ; Fri, 24 Nov 2023 12:59:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E3E023858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E3E023858D3C Authentication-Results: server2.sourceware.org; arc=pass smtp.remote-ip=40.107.8.47 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1700830774; cv=pass; b=JPT5V7vECXX5jKC3nv65ieQC/mHvQ3tnHX9rgCw7yiltgTNldV3IkuEaC5P+TN4RTzCZzoIxPnRyLfrM2QyaEmK4yynsWbwNIsZFlErx2ZazYuQRQ9YKppLfy/48/V3qrmOx0ikFbizQY5Ff9cZf8NR6k0OghfD5KCxXQq6qFIg= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1700830774; c=relaxed/simple; bh=5dkUzE9sLIrZN78JbF+5U/XC1RAzojpM86i/k3Wwb7U=; h=DKIM-Signature:DKIM-Signature:Message-ID:Date:Subject:From:To: MIME-Version; b=W9Z9QrREBUufxCW/KvvutSyVhNJuIFlfhezcxAlu4p+gmVhBgqM8j9w/3+DAtjkZ0QA5CmrcErD5EySRCe9swE/b53z31voXZcNgbXKQbP0kIZ2sJlzB7sbkAGvX/HaYKP+IVXweOCqyNzgplEKkcNKDg1G5AY5h3XVt4mN8//0= ARC-Authentication-Results: i=3; server2.sourceware.org ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=ZOdZO5XbfGnOSxSKW/usBC9eSbcvLri0W/avdIMlMR9BwRDnDespcW6rxAmS1Gc+uCeXDeG647vw8yy9WhMtXSb7bQ5SkdpVRQ5EFK4Dd1CXn7JbwQPx5bQn0TU2Kx7E+03DQ2pq5EwFDqHKi1/14Nkn9NeRp3f/W7FixQcme5obixUvRjc3FMMXkOtYTp+4YdsIXDAkRxUID85yWoMGQPICbikG3Q+TxDfGGfE40tG007h3sskFLHeHo3Cky0YarSDZdbgmZ5/9bbbyLr/SxeZMDX523L/4UJCKVRyWBiTTmKlje70Jy3cWcKRUFTEL7Qh5NFy5RAskiXQU4ljOMw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OSzyiYbVHZkFrKh3MkYKANI/lt5yZYtbQJ1Kx8cYn3Q=; b=GadBRz4w6DJOyv1zGHmklUWfVzEsqMzpxWjToW1qAMOINiwx3l01xRpl+fjVIG/Y6smHQ5MSPFLThqd0qxtDWBBn+II/yAmdfskKwUdN8lqoHwh+y9LIo0HEAMrL5J8nztf+oJtcAK2LHN1vAVmEiMZ1mFa74Uh1WEWfqk91LsmCyyKd3LJzTzWwEDR6iiRtz+WpemP+3KrZHetDMU619PIqEmVKXtJv7maMF5+x1xnX6/KuWrpw4kZeHF+lJ61Yp6jgSO9mRd8UrP84Z5rFKyT1LdFBFZEZon2wYyNHkVpGsPTEABujTGmK4kDVCQiRq9GHQOz39wvXfP2U2LAlfw== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=sourceware.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OSzyiYbVHZkFrKh3MkYKANI/lt5yZYtbQJ1Kx8cYn3Q=; b=AEO+ce5Hq033u6Vx5mjHp23wy9qLRsz034+n2goZvsI19JkWbnfPyH+aIjOfUi0gqCJH/kABXz35Afsx4+IAWqKZINP2DKo6tk6h1qzIbYL4lINVG+xW/Ldmiftkkwz73jls9I/DubtjaUGiq4gQ+nO8fIX55LPWlgGL75l20is= Received: from AM0PR06CA0119.eurprd06.prod.outlook.com (2603:10a6:208:ab::24) by DB9PR08MB6649.eurprd08.prod.outlook.com (2603:10a6:10:26c::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7025.21; Fri, 24 Nov 2023 12:59:15 +0000 Received: from AMS0EPF0000019F.eurprd05.prod.outlook.com (2603:10a6:208:ab:cafe::7) by AM0PR06CA0119.outlook.office365.com (2603:10a6:208:ab::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7025.21 via Frontend Transport; Fri, 24 Nov 2023 12:59:15 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AMS0EPF0000019F.mail.protection.outlook.com (10.167.16.251) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7025.12 via Frontend Transport; Fri, 24 Nov 2023 12:59:15 +0000 Received: ("Tessian outbound 26ee1d40577c:v228"); Fri, 24 Nov 2023 12:59:14 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 727bda39484fd2be X-CR-MTA-TID: 64aa7808 Received: from c8e0646d9fb4.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 806DAD7D-7F27-46B9-AA95-922F58C371CD.1; Fri, 24 Nov 2023 12:59:08 +0000 Received: from EUR04-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id c8e0646d9fb4.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Fri, 24 Nov 2023 12:59:08 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=j6Jz5e8IepPzDqkiC/2Y5Vw08QNqhbTgp201ycouGJcgokdSSb5hB5o73hthtB5txKK2DxhI3VpGDF8vS+CrTMn6ygnEN5Dd72z/5c1gszI5ibnIr2PTSd5sIyvu4jrMWbuKkp9ADhcSMuEQfKdh7Gtr80pn2JzhtlVyiDktMbT/ojdTqTHaJ1ej9Fnn/fDhIZYqDSUSsEUFtt+xdT+4Br+fiFnNO/pxdTZH8A06I/PF1aZlWz/pc7xIVkrbNn6vUOnUb/lQhU/9sXv0M+F0NTsmfdcvRxLnpCgHGA20EQWFsyebGtUrz3kjciwqioALWvHJIOnjaXBE75rrTsyAGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OSzyiYbVHZkFrKh3MkYKANI/lt5yZYtbQJ1Kx8cYn3Q=; b=jXw51mEhtM5kDUE6Ut3EqrfiYng4+2+CrgYQqy+WcWB/4hPT/gonl+r0qEJ1PtVUf7Kcp/LRB6WItGeEXuBNv8ekwX/RX7xS1iBs5LIYOeEyOu+zJnEX1XlLAHJVBPMLfMpcVM/C4sa0shmhoSwlaau9AziAoAxj4Bso69BbNN1zDh6QM0aAUYYs7icKXBFCiZAxhTlZJ7JLq1EABj82vy3seJ2MYpd4bjW0eggljceF/Ek8VItprw8ON3ItHf8x1TtEpuGk8pKVFReB1W/Byfs5BqKSCMPH8pVM2emP/gjq35HW7LaGp6kpUMOxkDLR/c36V3UO/IeFhhbu2IJyBA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OSzyiYbVHZkFrKh3MkYKANI/lt5yZYtbQJ1Kx8cYn3Q=; b=AEO+ce5Hq033u6Vx5mjHp23wy9qLRsz034+n2goZvsI19JkWbnfPyH+aIjOfUi0gqCJH/kABXz35Afsx4+IAWqKZINP2DKo6tk6h1qzIbYL4lINVG+xW/Ldmiftkkwz73jls9I/DubtjaUGiq4gQ+nO8fIX55LPWlgGL75l20is= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) by AS2PR08MB8478.eurprd08.prod.outlook.com (2603:10a6:20b:55c::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7025.21; Fri, 24 Nov 2023 12:59:06 +0000 Received: from VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::e05e:c012:f1f9:eb51]) by VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::e05e:c012:f1f9:eb51%4]) with mapi id 15.20.7025.021; Fri, 24 Nov 2023 12:59:05 +0000 Message-ID: Date: Fri, 24 Nov 2023 12:59:00 +0000 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3] gdb/testsuite: add test for backtracing for threaded inferiors from a corefile Content-Language: en-US From: Luis Machado To: Guinevere Larsen , gdb-patches@sourceware.org Cc: Andrew Burgess References: <20231025114253.259603-2-blarsen@redhat.com> <7c764242-f056-47ee-b059-e4cee2f76207@arm.com> In-Reply-To: <7c764242-f056-47ee-b059-e4cee2f76207@arm.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-ClientProxiedBy: LO2P123CA0094.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:139::9) To VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB3919:EE_|AS2PR08MB8478:EE_|AMS0EPF0000019F:EE_|DB9PR08MB6649:EE_ X-MS-Office365-Filtering-Correlation-Id: e8b0d9de-2be6-4953-2b2a-08dbeced2985 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: haFJYY13liXclxCgOOd0apT42JKUFoVwcV03ahujy8FcBz3aL+e4FxqpQe0M+ihckZ1bv2qMUhrq2idf6zjqiH4mn2OB7FJYQWRHNTwp6VzvC+ZLhuPzMPwi0q87O22wnSzGfeSQLnWk6AafFnyrfW3m6ykz7QzYelJgiS/rTpYk5kG5W4L7KnxEAMANbun5HXiThQSGJKMJ3zfFyaZYi5Q2SYGkcnu3FJpZF+pdBAQ5f6iH/XQ2jB/m2NVbtWNi0NHLqhLP4izzc7eUOaXb/m8srXlRfD6U0A8cggGgY1L7D1QTL2WJZfrvn1jkJxGa5HKwvRtcan8hvme26C+ICkXrMsAUf01a/v1ImpKK/GDt1EkVoX/BScF2G79FbObBwC7PfM5nu7oCs2F6IWr6K/wbBRxrkdeyt7FbxKEbdmE9mnSonjhz+jp7AcZ60ljNMkHDU3g8jugA7PJCNIDODwA+rIJJe2GFlkqaWdJfcsUbwJB1OVU+XznyTm2gf6VeHE35Tvxnct6pmt3fio2z4lGs/M2AuXzRdFfw7vomG6kVZJrnB39N0hkNOrp2wqqYYkQTu+4pfFhYDJ987FSgRTuy5tly+Ypx/zTjrgK8nG7NH1N5m+U3SardtKbouTlvS+ABoFRnRu+dzI5ZlLfZq3rB+B1ZxBaX99gqO+pWYC0= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR08MB3919.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(346002)(136003)(39860400002)(396003)(376002)(230922051799003)(186009)(1800799012)(64100799003)(451199024)(316002)(66476007)(66946007)(66556008)(478600001)(6486002)(6666004)(5660300002)(41300700001)(36756003)(2906002)(30864003)(8936002)(8676002)(86362001)(4326008)(31696002)(44832011)(2616005)(26005)(83380400001)(53546011)(6506007)(38100700002)(6512007)(31686004)(2004002)(45980500001)(43740500002); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR08MB8478 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AMS0EPF0000019F.eurprd05.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 4160014c-0cff-4a4a-663a-08dbeced23da X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: B81PbVpS2RuCCPyZf2zzHGabuVnFT/Tapa4tzs+qDAzItEygiYQaU+H3h0Q7KlLACUSZWQm8860gmX83midZVIzlJksPe7QoUGQWLCROULviMgeLzGRMH57qa2cRCBETAmUA/BUP9q9dSmYu53V5GwWZJmA5BM9hSVUNPuGhMmu0XV69yTEzXIH92zjjk565ELa3rraCvT1jj1VqS3KWQKSp5AXHnuFbpbEjL6UIGoY4pgbfm0gIaykrCtprs/49jqvRA5YWq1kaMEZUUZzLvjVB4ZVzYP87ZGnYTVDDgt4fLS2WK0+u2KzFCgjea8410M06YuayVEnLG1Tb/z929PUJ8ePTQgpfp3WBsDybljzIX0E+0etQz5drEPlYUkWfb3OuvQgBrv+yzJga0EuhSSHMOAN/ctZXAx0qJkiWXlA6yJGu86n+zXThBSlowkE+KseCWkSrINekkMloVx2mI80Y2CXKTztEaR/Ny55Ek3AvE83KZEpzTLmMzqs6Fve8tJIaPLZE8o8jvIy1v7H/3DHZ05NDr2kQzyT5DRK82ukJxBwZ2rSOSXi75GtdsgH7kBb8ug9VIQHS0AnZcgXFWUsBlB1ndGzWo3vvdT9tVCibXWK8hO4yZ8c8sY3DsQjHjPJCj/WvjzGCmATOuofG03LZ0iPOLg8MqCvx6ZIUg/mtm8ZkQB1gp3Qp4k/2lxMcyYsDTE15OzlTJBSbzMxsHPUUxhNd2HUeplcRGqXDRGq2Xu66eVMX+dMXE5e5ietl8I/MuNRuJgqrrJI9XaVICsDHiJok6OhybXQU66pMnYk= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230031)(4636009)(39860400002)(396003)(346002)(136003)(376002)(230922051799003)(1800799012)(64100799003)(451199024)(82310400011)(186009)(40470700004)(46966006)(36840700001)(53546011)(316002)(6666004)(30864003)(81166007)(83380400001)(6506007)(8936002)(40480700001)(6486002)(8676002)(4326008)(26005)(70206006)(70586007)(86362001)(336012)(31686004)(31696002)(47076005)(36756003)(44832011)(478600001)(40460700003)(5660300002)(82740400003)(41300700001)(6512007)(356005)(2616005)(2906002)(36860700001)(107886003)(2004002)(43740500002); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Nov 2023 12:59:15.0429 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e8b0d9de-2be6-4953-2b2a-08dbeced2985 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AMS0EPF0000019F.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6649 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_NONE, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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 On 11/24/23 12:26, Luis Machado wrote: > On 10/25/23 12:42, Guinevere Larsen wrote: >> This patch is based on an out-of-tree patch that fedora has been >> carrying for a while. It tests if GDB is able to properly unwind a >> threaded program in the following situations: >> * regular threads >> * in a signal handler >> * in a signal handler executing on an alternate stack >> >> And the final frame can either be in a syscall or in an infinite loop. >> >> The test works by running the inferior until a crash to generate a >> corefile, or until right before the crash. Then applies a backtrace to >> all threads to see if any frame can't be identified, and the order of >> the threads in GDB. Finally, it goes thread by thread and tries to >> collect a large part of the backtrace, to confirm that everything is >> being unwound correctly. >> >> Co-Authored-By: Andrew Burgess >> --- >> >> Changes for v3: >> * Resolved Lancelot's comment >> * undid early exit in favor of more readable gdb_test usage to load the >> corefile >> >> Changes for v2: >> * Linaro CI identified an issue with the test, which made the test fail >> when using read1. Fixed here >> * Also added early exit on corefile tests, if the corefile isn't >> properly loaded >> >> --- >> gdb/testsuite/gdb.threads/threadcrash.c | 443 ++++++++++++++++++++++ >> gdb/testsuite/gdb.threads/threadcrash.exp | 209 ++++++++++ >> 2 files changed, 652 insertions(+) >> create mode 100644 gdb/testsuite/gdb.threads/threadcrash.c >> create mode 100644 gdb/testsuite/gdb.threads/threadcrash.exp >> >> diff --git a/gdb/testsuite/gdb.threads/threadcrash.c b/gdb/testsuite/gdb.threads/threadcrash.c >> new file mode 100644 >> index 00000000000..e476ae7b07d >> --- /dev/null >> +++ b/gdb/testsuite/gdb.threads/threadcrash.c >> @@ -0,0 +1,443 @@ >> +/* This testcase is part of GDB, the GNU debugger. >> + >> + Copyright 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 . */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/* The delay that the main thread gives once all the worker threads have >> + reached the barrier before the main thread enters the function on which >> + GDB will have placed a breakpoint. */ >> + >> +#define MAIN_THREAD_DELAY 2 >> + >> +/* The maximum time we allow this test program to run for before an alarm >> + signal is sent and everything will exit. */ >> +#define WATCHDOG_ALARM_TIME 600 >> + >> +/* Aliases for the signals used within this script. Each signal >> + corresponds to an action (from the FINAL_ACTION enum) that the signal >> + handler will perform. */ >> + >> +#define SPIN_SIGNAL SIGUSR1 >> +#define SYSCALL_SIGNAL SIGUSR2 >> + >> +/* Describe the final action that a thread should perform. */ >> + >> +enum final_action >> + { >> + /* Thread should spin in an infinite loop. */ >> + SPIN = 0, >> + >> + /* Thread should block in a syscall. */ >> + SYSCALL, >> + >> + /* This is just a marker to allow for looping over the enum. */ >> + LAST_ACTION >> + }; >> + >> +/* Where should the thread perform this action? */ >> + >> +enum exec_location >> + { >> + /* Just a normal thread, on a normal stack. */ >> + NORMAL = 0, >> + >> + /* In a signal handler, but use the normal stack. */ >> + SIGNAL_HANDLER, >> + >> + /* In a signal handler using an alternative stack. */ >> + SIGNAL_ALT_STACK, >> + >> + /* This is just a marker to allow for looping over the enum. */ >> + LAST_LOCACTION >> + }; >> + >> +/* A descriptor for a single thread job. We create a new thread for each >> + job_description. */ >> + >> +struct job_description >> +{ >> + /* What action should this thread perform. */ >> + enum final_action action; >> + >> + /* Where should the thread perform the action. */ >> + enum exec_location location; >> + >> + /* The actual thread handle, so we can join with the thread. */ >> + pthread_t thread; >> +}; >> + >> +/* A pthread barrier, used to (try) and synchronise the threads. */ >> +pthread_barrier_t global_barrier; >> + >> +/* Return a list of jobs, and place the length of the list in *COUNT. */ >> + >> +struct job_description * >> +get_job_list (int *count) >> +{ >> + /* The number of jobs. */ >> + int num = LAST_ACTION * LAST_LOCACTION; >> + >> + /* The uninitialised array of jobs. */ >> + struct job_description *list >> + = malloc (num * sizeof (struct job_description)); >> + assert (list != NULL); >> + >> + /* Fill the array with all possible jobs. */ >> + for (int i = 0; i < (int) LAST_ACTION; ++i) >> + for (int j = 0; j < (int) LAST_LOCACTION; ++j) >> + { >> + int idx = (i * LAST_LOCACTION) + j; >> + list[idx].action = (enum final_action) i; >> + list[idx].location = (enum exec_location) j; >> + } >> + >> + /* Return the array of jobs. */ >> + *count = num; >> + return list; >> +} >> + >> +/* This function should never be called. If it is then an assertion will >> + trigger. */ >> + >> +void >> +assert_not_reached (void) >> +{ >> + assert (0); >> +} >> + >> +/* The function for a SPIN action. Just spins in a loop. The LOCATION >> + argument exists so GDB can identify the expected context for this >> + function. */ >> + >> +void >> +do_spin_task (enum exec_location location) >> +{ >> + (void) location; >> + >> + /* Let everyone know that we're about to perform our action. */ >> + int res = pthread_barrier_wait (&global_barrier); >> + assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0); >> + >> + while (1) >> + { >> + /* Nothing. */ >> + } >> +} >> + >> +/* The function for a SYSCALL action. Just spins in a loop. The LOCATION >> + argument exists so GDB can identify the expected context for this >> + function. */ >> + >> +void >> +do_syscall_task (enum exec_location location) >> +{ >> + (void) location; >> + >> + /* Let everyone know that we're about to perform our action. */ >> + int res = pthread_barrier_wait (&global_barrier); >> + assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0); >> + >> + sleep (600); >> +} >> + >> +/* Return the required size for a sigaltstack. We start with a single >> + page, but do check against the system defined minimums. We don't run >> + much on the alternative stacks, so we don't need a huge one. */ >> + >> +size_t >> +get_stack_size (void) >> +{ >> + size_t size = getpagesize (); /* Arbitrary starting size. */ >> + if (size < SIGSTKSZ) >> + size = SIGSTKSZ; >> + if (size < MINSIGSTKSZ) >> + size = MINSIGSTKSZ; >> + return size; >> +} >> + >> +/* A descriptor for an alternative stack. */ >> + >> +struct stack_descriptor >> +{ >> + /* The base address of the alternative stack. This is the address that >> + must be freed to release the memory used by this stack. */ >> + void *base; >> + >> + /* The size of this alternative stack. Tracked just so we can query this >> + from GDB. */ >> + size_t size; >> +}; >> + >> +/* Install an alternative signal stack. Return a descriptor for the newly >> + allocated alternative stack. */ >> + >> +struct stack_descriptor >> +setup_alt_stack (void) >> +{ >> + size_t stack_size = get_stack_size (); >> + >> + void *stack_area = malloc (stack_size); >> + >> + stack_t stk; >> + stk.ss_sp = stack_area; >> + stk.ss_flags = 0; >> + stk.ss_size = stack_size; >> + >> + int res = sigaltstack (&stk, NULL); >> + assert (res == 0); >> + >> + struct stack_descriptor desc; >> + desc.base = stack_area; >> + desc.size = stack_size; >> + >> + return desc; >> +} >> + >> +/* Return true (non-zero) if we are currently on the alternative stack, >> + otherwise, return false (zero). */ >> + >> +int >> +on_alt_stack_p (void) >> +{ >> + stack_t stk; >> + int res = sigaltstack (NULL, &stk); >> + assert (res == 0); >> + >> + return (stk.ss_flags & SS_ONSTACK) != 0; >> +} >> + >> +/* The signal handler function. All signals call here, so we use SIGNO >> + (the signal that was delivered) to decide what action to perform. This >> + function might, or might not, have been called on an alternative signal >> + stack. */ >> + >> +void >> +signal_handler (int signo) >> +{ >> + enum exec_location location >> + = on_alt_stack_p () ? SIGNAL_ALT_STACK : SIGNAL_HANDLER; >> + >> + switch (signo) >> + { >> + case SPIN_SIGNAL: >> + do_spin_task (location); >> + break; >> + >> + case SYSCALL_SIGNAL: >> + do_syscall_task (location); >> + break; >> + >> + default: >> + assert_not_reached (); >> + } >> +} >> + >> +/* The thread worker function. ARG is a job_description pointer which >> + describes what this thread is expected to do. This function always >> + returns a NULL pointer. */ >> + >> +void * >> +thread_function (void *arg) >> +{ >> + struct job_description *job = (struct job_description *) arg; >> + struct stack_descriptor desc = { NULL, 0 }; >> + int sa_flags = 0; >> + >> + switch (job->location) >> + { >> + case NORMAL: >> + /* This thread performs the worker action on the current thread, >> + select the correct worker function based on the requested >> + action. */ >> + switch (job->action) >> + { >> + case SPIN: >> + do_spin_task (NORMAL); >> + break; >> + >> + case SYSCALL: >> + do_syscall_task (NORMAL); >> + break; >> + >> + default: >> + assert_not_reached (); >> + } >> + break; >> + >> + case SIGNAL_ALT_STACK: >> + /* This thread is to perform its action in a signal handler on the >> + alternative stack. Install the alternative stack now, and then >> + fall through to the normal signal handler location code. */ >> + desc = setup_alt_stack (); >> + assert (desc.base != NULL); >> + assert (desc.size > 0); >> + sa_flags = SA_ONSTACK; >> + >> + /* Fall through. */ >> + case SIGNAL_HANDLER: >> + { >> + /* This thread is to perform its action in a signal handler. We >> + might have just installed an alternative signal stack. */ >> + int signo, res; >> + >> + /* Select the correct signal number so that the signal handler will >> + perform the required action. */ >> + switch (job->action) >> + { >> + case SPIN: >> + signo = SPIN_SIGNAL; >> + break; >> + >> + case SYSCALL: >> + signo = SYSCALL_SIGNAL; >> + break; >> + >> + default: >> + assert_not_reached (); >> + } >> + >> + /* Now setup the signal handler. */ >> + struct sigaction sa; >> + sa.sa_handler = signal_handler; >> + sigfillset (&sa.sa_mask); >> + sa.sa_flags = sa_flags; >> + res = sigaction (signo, &sa, NULL); >> + assert (res == 0); >> + >> + /* Send the signal to this thread. */ >> + res = pthread_kill (job->thread, signo); >> + assert (res == 0); >> + } >> + break; >> + >> + default: >> + assert_not_reached (); >> + }; >> + >> + /* Free the alt-stack if we allocated one, if not DESC.BASE will be >> + NULL so this call is fine. */ >> + free (desc.base); >> + >> + /* Thread complete. */ >> + return NULL; >> +} >> + >> +void >> +start_job (struct job_description *job) >> +{ >> + int res; >> + >> + res = pthread_create (&job->thread, NULL, thread_function, job); >> + assert (res == 0); >> +} >> + >> +/* Join with the thread for JOB. This will block until the thread for JOB >> + has finished. */ >> + >> +void >> +finalise_job (struct job_description *job) >> +{ >> + int res; >> + void *retval; >> + >> + res = pthread_join (job->thread, &retval); >> + assert (res == 0); >> + assert (retval == NULL); >> +} >> + >> +/* Function that GDB can place a breakpoint on. */ >> + >> +void >> +breakpt (void) >> +{ >> + /* Nothing. */ >> +} >> + >> +/* Function that triggers a crash, if the user has setup their environment >> + correctly this will dump a core file, which GDB can then examine. */ >> + >> +void >> +crash_function (void) >> +{ >> + volatile int *p = 0; >> + volatile int n = *p; >> + (void) n; >> +} >> + >> +/* Entry point. */ >> + >> +int >> +main () >> +{ >> + int job_count, res; >> + struct job_description *jobs = get_job_list (&job_count); >> + >> + /* This test is going to park some threads inside infinite loops. Just >> + in case this program is left running, install an alarm that will cause >> + everything to exit. */ >> + alarm (WATCHDOG_ALARM_TIME); >> + >> + /* We want each worker thread (of which there are JOB_COUNT) plus the >> + main thread (hence + 1) to wait at the barrier. */ >> + res = pthread_barrier_init (&global_barrier, NULL, job_count + 1); >> + assert (res == 0); >> + >> + /* Start all the jobs. */ >> + for (int i = 0; i < job_count; ++i) >> + start_job (&jobs[i]); >> + >> + /* Notify all the worker threads that we're waiting for them. */ >> + res = pthread_barrier_wait (&global_barrier); >> + assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0); >> + >> + /* All we know at this point is that all the worker threads have reached >> + the barrier, which is just before they perform their action. But we >> + really want them to start their action. >> + >> + There's really no way we can be 100% certain that the worker threads >> + have started their action, all we can do is wait for a short while and >> + hope that the machine we're running on is not too slow. */ >> + sleep (MAIN_THREAD_DELAY); >> + >> + /* A function that GDB can place a breakpoint on. By the time we get >> + here we are as sure as we can be that all of the worker threads have >> + started and are in their worker action (spinning, or syscall). */ >> + breakpt (); >> + >> + /* If GDB is not attached then this function will cause a crash, which >> + can be used to dump a core file, which GDB can then analyse. */ >> + crash_function (); >> + >> + /* Due to the crash we never expect to get here. Plus the worker actions >> + never terminate. But for completeness, here's where we join with all >> + the worker threads. */ >> + for (int i = 0; i < job_count; ++i) >> + finalise_job (&jobs[i]); >> + >> + /* Cleanup the barrier. */ >> + res = pthread_barrier_destroy (&global_barrier); >> + assert (res == 0); >> + >> + /* And clean up the jobs list. */ >> + free (jobs); >> + >> + return 0; >> +} >> diff --git a/gdb/testsuite/gdb.threads/threadcrash.exp b/gdb/testsuite/gdb.threads/threadcrash.exp >> new file mode 100644 >> index 00000000000..ee81b5c32f2 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.threads/threadcrash.exp >> @@ -0,0 +1,209 @@ >> +# This testcase is part of GDB, the GNU debugger. >> + >> +# Copyright 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 test case looks at GDB's ability to get correct backtraces for a >> +# crashed inferior, recreating it from a live inferior, a corefile and >> +# a gcore. >> + >> + >> +# First check that we have 7 threads. >> + >> +proc test_thread_count {} { >> + set thread_count 0 >> + >> + gdb_test_multiple "info threads" "getting thread count" -lbl { >> + -re "Thread" { >> + incr thread_count >> + exp_continue >> + } >> + -re "$::gdb_prompt " { >> + gdb_assert {$thread_count == 7} >> + } >> + } >> + >> + return $thread_count >> +} >> + >> +# Apply all to quickly check if all expected states are >> +# present. Then, save the full desired backtrace in a list >> +# so we can check full backtraces later. >> + >> +proc thread_apply_all {} { >> + global test_list >> + >> + set unwind_fail false >> + >> + gdb_test_multiple "thread apply all backtrace" \ >> + "Get thread information" -lbl { >> + -re "#\[0-9\]+\\\?\\\?\[^\n\]*" { >> + set unwind_fail true >> + exp_continue >> + } >> + -re "\[^\n\]*syscall_task .location=SIGNAL_ALT_STACK\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*sleep.*" \ >> + ".*do_syscall_task .location=SIGNAL_ALT_STACK.*" \ >> + ".*signal_handler.*" \ >> + ".*signal handler called.*" \ >> + ".*pthread_kill.*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*syscall_task .location=SIGNAL_HANDLER\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*sleep.*" \ >> + ".*do_syscall_task .location=SIGNAL_HANDLER.*" \ >> + ".*signal_handler.*" \ >> + ".*signal handler called.*" \ >> + ".*pthread_kill.*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*syscall_task .location=NORMAL\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*sleep.*" \ >> + ".*do_syscall_task .location=NORMAL.*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*spin_task .location=SIGNAL_ALT_STACK\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*do_spin_task .location=SIGNAL_ALT_STACK.*" \ >> + ".*signal_handler.*" \ >> + ".*signal handler called.*" \ >> + ".*pthread_kill.*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*spin_task .location=SIGNAL_HANDLER\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*do_spin_task .location=SIGNAL_HANDLER.*" \ >> + ".*signal_handler.*" \ >> + ".*signal handler called.*" \ >> + ".*pthread_kill.*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*spin_task .location=NORMAL\[^\n\]*" { >> + set test_list [linsert $test_list end [multi_line ".*do_spin_task .location=NORMAL..*" \ >> + ".*thread_function.*"]] >> + exp_continue >> + } >> + -re "\[^\n\]*main\[^\n\]*" { >> + set test_list [linsert $test_list end ".*main.*"] >> + exp_continue >> + } >> + -re "$::gdb_prompt " { >> + pass $gdb_test_name >> + } >> + } >> + >> + gdb_assert {$unwind_fail == false} >> +} >> + >> +proc do_full_test {} { >> + global test_list >> + set thread_count [test_thread_count] >> + >> + thread_apply_all >> + >> + gdb_assert {$thread_count == [llength $test_list]} >> + >> + for {set i 0} {$i < $thread_count } {incr i} { >> + set thread_num [expr [llength $test_list] - $i] >> + >> + gdb_test "thread apply $thread_num backtrace" [lindex $test_list $i] >> + } >> +} >> + >> +proc_with_prefix test_corefile {} { >> + set corefile [core_find $::binfile] >> + if { $corefile == "" } { >> + untested "couldn't generate corefile" >> + return >> + } >> + set corefile [gdb_remote_download host $corefile] >> + >> + gdb_test "core-file $corefile" \ >> + "" \ >> + "loading_corefile" \ >> + "A program is being debugged already\\\. Kill it\\\? \\\(y or n\\\) " \ >> + "y" >> + >> + do_full_test >> +} >> + >> +proc_with_prefix test_gcore {} { >> + >> + clean_restart "$::binfile" >> + >> + gdb_test "handle SIGUSR1 nostop print pass" \ >> + ".*SIGUSR1.*No.*Yes.*Yes.*User defined signal 1" \ >> + "setup SIGUSR1" >> + gdb_test "handle SIGUSR2 nostop print pass" \ >> + ".*SIGUSR2.*No.*Yes.*Yes.*User defined signal 2" \ >> + "setup SIGUSR2" >> + >> + gdb_test "run" ".*Segmentation fault.*" "continue to crash" >> + >> + set gcore_name "${::binfile}.gcore" >> + set gcore_supported [gdb_gcore_cmd "$gcore_name" "saving gcore"] >> + >> + if {!$gcore_supported} { >> + unsupported "couldn't generate gcore file" >> + return >> + } >> + >> + set corefile [gdb_remote_download host $gcore_name] >> + >> + gdb_test "core-file $corefile" \ >> + "" \ >> + "loading_corefile" \ >> + "A program is being debugged already\\\. Kill it\\\? \\\(y or n\\\) " \ >> + "y" >> + >> + do_full_test >> +} >> + >> +standard_testfile >> + >> +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { >> + return -1 >> +} >> + >> +clean_restart ${binfile} >> + >> +gdb_test_no_output "set backtrace limit unlimited" >> + >> +set test_list { } >> + >> +with_test_prefix "live inferior" { >> + gdb_test "handle SIGUSR1 nostop print pass" \ >> + ".*SIGUSR1.*No.*Yes.*Yes.*User defined signal 1" \ >> + "setup SIGUSR1" >> + gdb_test "handle SIGUSR2 nostop print pass" \ >> + ".*SIGUSR2.*No.*Yes.*Yes.*User defined signal 2" \ >> + "setup SIGUSR2" >> + >> + gdb_breakpoint "breakpt" >> + gdb_test "run" ".*breakpt.*" "run to break function" >> + >> + do_full_test >> +} >> + >> +set test_list { } >> + >> +test_corefile >> + >> +set test_list { } >> + >> +test_gcore > > I gave this a try on aarch64-linux arm-linux and it works as expected. > > Unless others have further objections, I think this looks good. > > Reviewed-By: Luis Machado Just to complement, a small nit about the current patch is that it throws an ERROR when running the testsuite using the native-gdbserver board. ERROR: gdbserver does not support run without extended-remote while executing "error "gdbserver does not support $command without extended-remote"" Maybe we should punt when testing against native-gdbserver, or start the program differently.