From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id eY8KICJwjGr6yDwAWB0awg (envelope-from ) for ; Mon, 24 Aug 2026 12:24:02 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 7B4EC1E0A3; Mon, 24 Aug 2026 12:24:02 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable 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 DA34E1E033 for ; Mon, 24 Aug 2026 12:23:58 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D1E774BB1C02 for ; Mon, 24 Aug 2026 16:23:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D1E774BB1C02 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr Received: from AM0PR83CU005.outbound.protection.outlook.com (mail-westeuropeazlp170100001.outbound.protection.outlook.com [IPv6:2a01:111:f403:c201::1]) by sourceware.org (Postfix) with ESMTPS id 971B94BB1C04 for ; Mon, 24 Aug 2026 16:23:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 971B94BB1C04 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 971B94BB1C04 Authentication-Results: sourceware.org; arc=pass smtp.remote-ip=2a01:111:f403:c201::1 ARC-Seal: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1787588583; cv=pass; b=RevsNA3RWJuoPyuZYYf4rONVujzYnH64uIH7NGskpKBkC8OXHgtSIniOAKyAG9Nv7zG7/k8JgiW8KJxSaOYnj8+Pm3EW47HrMM+1SSZuCSPic9TQSquFoJMWR7Txu+ZgzdlZxj9P+Exr/skE+i5Zsf97L2V7Zz+/qpAnnVXk/1c= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1787588583; c=relaxed/simple; bh=rwSUOH2x09NQ+aBua3/156mpNXNKdUvYHTCndbUvR5M=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=KZCxvXbUTOeKZVs3VqNXoMdDjVWBl9eo5wD+Du8vkg8GIT2G8GXNr2I8DpAekhXeyhL5uIxye0QyRXVPXzClww47XgQ4uROpYwOUDSGo0/HdQWmw+r/tbVQktafovK+Np9GSD77km/GgjgBZRVsOT1yz16Mee4v+7drA3GTJbWg= ARC-Authentication-Results: i=3; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=f/Pocabr DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 971B94BB1C04 ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=w392zgrCqrnTZizMsWUXWiDQLw4T1DZsB7btkih2HzR8Gpgw44i0uUC49uQi+Mw5D34x+GxaZgYaW79XFvQU3I7Qx0/h5ZiT5nDjNoM5gzLygeEurwZfFER4AiMZKq8/Bq6M/rkgtvGxSMFwOSylohEZKbIqjSsAXHdH7HHxTvFAtUdUd5hE3ntpi6VFfezO7sfAFboWlTsroP5ctuiHdm5c7ynWgDhUykb7JD9kmsPnD/ymB7chYmoypJoVq9KNrJ9cRB3YEoP7KFRZOdsl2Pjvn4EX487PXDCIPBb+CQ+6DgYXiokxKm6jrH0Z9DbyEyodqJtXGE3/Wzqur1zA0A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=avoRh5aqtVrRbhW6GpGPtoNZjuAdOfT9LrXt5B2PGxU=; b=FgPCXT2pqStBCy9sWPX39JePygJv70auFvH7dbmSQjbnL9jeEups/sWDYtBajBNV5BYQcNcaVwF+QdlZH6mv1XOftOyeohV0p2un4ehEvzNkYogZwazeiwfPn+7TX6y9rpKsDDYXUuLaxPUx6mPLm3cwuJtjCyk4fH+KQxIUAuNY7qgTwkcpJgr3YyA5/6NzjpqH+HNHgoyQHcRhW7EcHsw2LkhSx/+JB2R6JOoqtbq1TwvPCvm24+lZn3IXigUyJ6oKdw7T+OqInwXkJtqVtKjFc45RrDAgjThoQ1FgZq8iYL6Hx/Ak2QdyhDkI9ZhyAFsVBf0dMlC8yNJShwgxLA== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) 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=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dmarc=[1,1,header.from=arm.com]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=avoRh5aqtVrRbhW6GpGPtoNZjuAdOfT9LrXt5B2PGxU=; b=f/PocabrEDFxtyvXkLSnehSSan8NOsDJs97wXYwTlFU/jTpdFiEBfOJt7CKdcp16Bpji0exhwrw/OAfn+Fcjlop4e1NE+WW9mRNwvsNaXt5wihYVm0gZ9nYbCK62aDSAviQRzs9pZil0Js1LpaopgnxmJB1xfSvxSnO3TtcjQjc= Received: from DUZPR01CA0076.eurprd01.prod.exchangelabs.com (2603:10a6:10:46a::7) by DU4PR08MB11574.eurprd08.prod.outlook.com (2603:10a6:10:627::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.339.12; Mon, 24 Aug 2026 16:22:57 +0000 Received: from DU2PEPF0001E9C4.eurprd03.prod.outlook.com (2603:10a6:10:46a:cafe::59) by DUZPR01CA0076.outlook.office365.com (2603:10a6:10:46a::7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.339.12 via Frontend Transport; Mon, 24 Aug 2026 16:22:57 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 4.158.2.129) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=arm.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 4.158.2.129 as permitted sender) receiver=protection.outlook.com; client-ip=4.158.2.129; helo=outbound-uk1.az.dlp.m.darktrace.com; pr=C Received: from outbound-uk1.az.dlp.m.darktrace.com (4.158.2.129) by DU2PEPF0001E9C4.mail.protection.outlook.com (10.167.8.73) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.360.3 via Frontend Transport; Mon, 24 Aug 2026 16:22:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=WbfU1IytH3kdXLAu2pJ2r1Io3RlJfOjdsLe2WSbzC/xdwRdxRcjroTnOMQsQQ+j1N+T31IhhZUYrJRCMWde4yaJinXLvQ28PbGZ8LIVSwVCe6rOuVnuSLY7UnkA8NEZNKJLFiM3sbUW9Sk9Y7VxkvgwqCzLb1xkJi/EeFoLrePuQi3Eg7/ZGOa7EWrnEr+K8wt21KgxBNXmnoGYxCxo0GEHfcgWQeqpk9ZvW12kJDlhuEWirWDtxsc0pAPJYXa55A29zY6LNw4o+jfIHM0iw9wzFr9uxS24+qTNb0MiRCa3MG8gpjWh+VHyYSMtRktlN026wbwsradieOMGpKLDEaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=avoRh5aqtVrRbhW6GpGPtoNZjuAdOfT9LrXt5B2PGxU=; b=tu7ZYFqnzC1575fiVlRFWobE2CA41KCnn6yjFfyoQEAcaIDsLVtcQ7d+En/JL8Kqrix8V5LzxuneOnDZdm+HuCijjA7j75YXi9jAHCdYU8oN3E8FFjjONDM3bIxpAlBYd2i0X2p/1HZLVinqCEAK5kHZXo1G3CsOQISARg01PdeUdn/h64SxmKEe3Z1EdjH04WqUOdNNRafbR88oTukw2tlOJp9vU3uwS/6ACEsDakAebtBM/xD4zJSFQubj1wzpMMuRZG35Pg01/MQ5Ef0566Q4X5l7keoJQUTjfN6Uwe7EvZNCbrlHKHEvBu6dZG4yKxIYtsc2+CyGTIfU5kZhiA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 172.205.89.229) smtp.rcpttodomain=sourceware.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arm.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=avoRh5aqtVrRbhW6GpGPtoNZjuAdOfT9LrXt5B2PGxU=; b=f/PocabrEDFxtyvXkLSnehSSan8NOsDJs97wXYwTlFU/jTpdFiEBfOJt7CKdcp16Bpji0exhwrw/OAfn+Fcjlop4e1NE+WW9mRNwvsNaXt5wihYVm0gZ9nYbCK62aDSAviQRzs9pZil0Js1LpaopgnxmJB1xfSvxSnO3TtcjQjc= Received: from VE1PR03CA0055.eurprd03.prod.outlook.com (2603:10a6:803:118::44) by AMVPR08MB12000.eurprd08.prod.outlook.com (2603:10a6:20b:773::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.339.12; Mon, 24 Aug 2026 16:22:21 +0000 Received: from MI3PEPF0000848E.eurprd03.prod.outlook.com (2603:10a6:803:118:cafe::e6) by VE1PR03CA0055.outlook.office365.com (2603:10a6:803:118::44) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.339.12 via Frontend Transport; Mon, 24 Aug 2026 16:22:21 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 172.205.89.229) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 172.205.89.229 as permitted sender) receiver=protection.outlook.com; client-ip=172.205.89.229; helo=nebula.arm.com; pr=C Received: from nebula.arm.com (172.205.89.229) by MI3PEPF0000848E.mail.protection.outlook.com (10.167.240.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.3 via Frontend Transport; Mon, 24 Aug 2026 16:22:21 +0000 Received: from AZ-NEU-EX04.Arm.com (10.240.25.138) by AZ-NEU-EX04.Arm.com (10.240.25.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.29; Mon, 24 Aug 2026 16:22:01 +0000 Received: from PF4S4363.arm.com (10.57.41.87) by mail.arm.com (10.240.25.138) with Microsoft SMTP Server id 15.2.2562.29 via Frontend Transport; Mon, 24 Aug 2026 16:22:01 +0000 From: Matthieu Longo To: , Simon Marchi CC: Matthieu Longo , Thiago Jung Bauermann Subject: [PATCH v2] gdb: rely on the first non-exited thread TPID when reading Linux procfs files Date: Mon, 24 Aug 2026 17:21:55 +0100 Message-ID: <20260824162155.467233-1-matthieu.longo@arm.com> X-Mailer: git-send-email 2.55.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: MI3PEPF0000848E:EE_|AMVPR08MB12000:EE_|DU2PEPF0001E9C4:EE_|DU4PR08MB11574:EE_ X-MS-Office365-Filtering-Correlation-Id: 98906e7e-7d88-4a53-b209-08df01fbf531 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|36860700016|376014|1800799024|23010399003|82310400026|13003099007|6133799003|3023799007|10067099003|56012099006|11063799006|5023799004|18002099003; X-Microsoft-Antispam-Message-Info-Original: h3bzV0yCUwbMWNhsFpzDVB0yUzCcTSkT1HHmYGp7cEE6cq1gsEfiVXg6nBhsvPAsW+3JMd9YSFWAWgjXBKe2nH/6Gz9Sy23Fq/xuBcVyXtOgUTNO6oOxVGy/2UFNWCk4pHg6FspfKOwxo5vgmKi7OzdDI4QtbnSWXcEk/oUcTpWO1xvsnosYxQKJF41K0SuvxiIScu8K0b21F6WkL1iZXcQ3b3XXzd+LLY8mz93xkwFRHqrwjPoopVoenOx7zgE/04q5D81LHQKn4IX2EoVLHFb/9GvWc14C3nm/WxMVJ8S3XspC5FPdnfdRe7ivePe15+eP5J8EWI0QKen2yWjskYYUtiOPBBh54HgD5GwU4PTTsHWDZWQu5gOVWGlJUZsrid5xHr2qu8clDHwEruciSzD8IqPssvpRpySOtPqPzX/FcZyoxg4aFRsn/iK+PoHOQW6gk55FnsdO+Su22B4QLz8YV/fJT53dZ5I3OusD2etJQBQ5+jebUrEx/g6V9lx5ah4zdcyDPr4woBM1eU5UzLsHFESoHdRtGco8rhPjrgTOVTeu6wpsjo4mBhCSX9O/6DkCrHNsNNO63ZuDhugJxJrC2icGej3+x9V4m+rLcmxpPXE50xZz/A1tzb9gJoYbHBCb+Ut4vbp5dGbi+wnPF7gWq+lCZEIvMdJB6uqL8RnbHmhUAuC6Tl9vpaJIwAO8MiXYIEp3NrgfwjYtHMU1Lw== X-Forefront-Antispam-Report-Untrusted: CIP:172.205.89.229; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(36860700016)(376014)(1800799024)(23010399003)(82310400026)(13003099007)(6133799003)(3023799007)(10067099003)(56012099006)(11063799006)(5023799004)(18002099003); DIR:OUT; SFP:1101; X-Exchange-RoutingPolicyChecked: nN9le0mAiSl2IkL/MSZH0sbfhNmAuJyML3AsQj54pRj1m805aDm6CITWmXjURdyJTYmnFvI96DhlswpULO5Xe0P35NpK1SQG0K1ZriURtifQ4d3oZN0Bn/iqRuE9Dka6wlOdmkFuTzGfLXi1vE4W97Q4WXHeZ1k91Ot9m9goDt2i4VBHGozq5IzkZpLAXVJyDKoZQWEEku2s2PWJmnNDY06xOcqEqMz27lPPtUknGBJo/gl+6Oy8yqsq2Ur7jrB08O4OOayr0owv1NEg3YhecBGhp9hkWcp/mFEbTCfSafS+LrbqVsUROBP2mkcPFBzBRSKGfnJcwiZeHHbjVQpuJQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AMVPR08MB12000 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DU2PEPF0001E9C4.eurprd03.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: ff3e607d-717e-44f9-3f02-08df01fbdfdd X-Microsoft-Antispam: BCL:0; ARA:13230040|35042699022|23010399003|82310400026|14060799003|1800799024|36860700016|376014|56012099006|10067099003|6133799003|3023799007|18002099003|11063799006|5023799004|13003099007; X-Microsoft-Antispam-Message-Info: 5TaR3zPExmN2OdUlLAOVlSimUbNMfrgdEwLC0KfPOvsMIv+YPL5pQL++z0+Q1N9KLEAzgxyZRgGTY/S6/srxJC0cCnqeSh6aecv9WZ1boIbCHL2I2AfBcjA0gyqCx97vmjE/xAkAjeoaOJSTLdpxRL22+uuGcAWZQKD1/agEZ3SvUVGaYHyJVDGNPbLtLXphSPhwEevnXiIVToqXrjQFQAYhof/yCb5WZyoGsOotVMgV/qUbQymwzn3CZts2bfO/Tu7Fy3OqVkkr+jdM29L/i4WRMXlUkHpGL9KKga/c6fFDQG5XSYuOSz4COVKRLyV/aD7pQ8xmjcYHSM5sdr5KgzXyH9Pmq2v7PJwhMRf3X86OiMZHNPACZxrPj3PqvgQUrRzIfwNZlgCl7oMqFyNozc3GLpOYjUCNPOepu96PROJ541qBkY1wuUXjv0MHKtfHikFAIHWiE2Jo3rGh3kvoEobuonbEzyHLXGEEFuHziqM1OLwdT/cFTQZyBvAC7h2PkK+8cg5EfnVVowz07iWA7VN99Kcd2og3DBFsru2RpnR4/NQpNaTUxabjjowo4Q/pxhenAy2pwY3SzGk/vXEQ5wHLVcDWrQlGVg/YhjH9Qnzx7smps7ROrGrLvQrbI1jwfCKh0vw/YutPYW6aWqxKsgLUNgq5tlvVMYdRapKvjuRukOg/R6cqnLWwOgUEyRp1V4g5Dv9jL6sxQ8LXKs3aAg== X-Forefront-Antispam-Report: CIP:4.158.2.129; CTRY:GB; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:outbound-uk1.az.dlp.m.darktrace.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(35042699022)(23010399003)(82310400026)(14060799003)(1800799024)(36860700016)(376014)(56012099006)(10067099003)(6133799003)(3023799007)(18002099003)(11063799006)(5023799004)(13003099007); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: GvXDipqvaAJrwzEuts2gSSvqS9v9YwUViwKjp2xqZmKjhA3xUjmuB0RxpYjEgna5+FUm3t0BjkNxDFBUNsSuIGS/0QyXLyT2q00yxKXBSSEET09DJ6/zAAyYwFrfxk1Y1ZGTJiVfpd2faZeOrqw9ha45WK5G64gZS+kklQ/Pzyqfqj8S4ii+D4RP0NjEbtNdqruORiEmfpLq28n1xafb+kXHEWi4imQh4SS+hxn1QY1Huo/isDPBGfxOGjeQQIjj4bCbR5ykqLLMQkvzBkBu0dhPwBfWreAcVPiWQWc9VZiP6jspLiOYzxtSeSFZtVPwHrEIU5B0rJdSlNMtFm5WRWpvuh3FWqt17oeD4fcEQpQmyQkCCpp1XTX/jGrL/KJ+lQIOYMHCk+aUBreZWN7HA5XbrkcB2K0FP2IrdqVsLtTlLV+OSGPz3zHQ7IiQjVCX X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Aug 2026 16:22:57.0853 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 98906e7e-7d88-4a53-b209-08df01fbf531 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[4.158.2.129]; Helo=[outbound-uk1.az.dlp.m.darktrace.com] X-MS-Exchange-CrossTenant-AuthSource: DU2PEPF0001E9C4.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU4PR08MB11574 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 Linux, /proc/ is keyed by the thread-group leader PID. When the leader has exited, some /proc//... entries become unavailable even though another thread is still alive. This can happen, for instance, when the main thread calls pthread_exit() and another thread continues the execution (existing test: gcore-stale-thread). This causes GDB to fail to read procfs entries such as cmdline, cwd, exe, maps, and smaps when it uses 'current_inferior ()->pid' after the thread-group leader has exited. Fix this by adding inferior::first_non_exited_thread(), which returns the PTID of the first non-exited thread of the inferior. Use its LWP ID when accessing procfs entries that only need a representative live LWP belonging to the process. This is a best-effort choice of a thread that is expected to still exist in the target. Since GDB's view of the threads list may be stale, the selected thread may already have exited by the time it is accessed. Callers must therefore still be prepared to handle that case. Update the following functions: - linux_info_proc - linux_process_address_in_memtag_page - linux_find_memory_regions_full - linux_fill_prpsinfo - linux_address_in_shadow_stack_mem_range to use the first non-exited thread's LWP ID instead of the inferior PID when constructing procfs paths. Add a new test in gdb.threads. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31207 Reviewed-by: Thiago Jung Bauermann --- gdb/inferior.c | 12 +++ gdb/inferior.h | 11 +++ gdb/linux-tdep.c | 90 +++++++++++++------ ...access-procfs-while-thread-leader-exited.c | 48 ++++++++++ ...cess-procfs-while-thread-leader-exited.exp | 78 ++++++++++++++++ 5 files changed, 211 insertions(+), 28 deletions(-) create mode 100644 gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.c create mode 100644 gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.exp diff --git a/gdb/inferior.c b/gdb/inferior.c index 8c619ffec5a..f6d77799ac2 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -250,6 +250,18 @@ inferior::find_thread (ptid_t ptid) /* See inferior.h. */ +thread_info * +inferior::first_non_exited_thread () const +{ + auto it = this->ptid_thread_map.cbegin (); + if (it != this->ptid_thread_map.cend ()) + return it->second; + else + return nullptr; +} + +/* See inferior.h. */ + void inferior::clear_thread_list () { diff --git a/gdb/inferior.h b/gdb/inferior.h index 217741adc07..34baf743995 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -513,6 +513,17 @@ class inferior : public refcounted_object, /* Find (non-exited) thread PTID of this inferior. */ thread_info *find_thread (ptid_t ptid); + /* Return the first non-exited thread of this inferior. + + This is only a best-effort choice of a thread that is expected to still + exist in the target. A thread may have exited after GDB last updated its + thread list, or GDB/gdbserver may have observed the exit but not yet + propagated it through all layers. Therefore the returned thread is not + guaranteed to still be alive when it is later accessed. This avoids the + common case where the current thread has exited, but callers must still be + prepared for the selected thread to no longer exist. */ + thread_info *first_non_exited_thread () const; + /* Delete all threads in the thread list, silently. */ void clear_thread_list (); diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index e37c400bed1..588984a1ca4 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -456,6 +456,37 @@ linux_has_shared_address_space (struct gdbarch *gdbarch) return linux_is_uclinux (); } +/* Return a PTID that identifies the current process and can be used to + access procfs safely. + + The returned PTID is that of the thread-group leader whenever it is + still alive. If the leader has already exited, the PTID of the first + non-exited thread in the current inferior is returned instead. + This ensures that the returned PTID always refers to a live thread + whose procfs entries are present and populated. */ +static ptid_t +get_process_reference_ptid () +{ + /* Get the current thread. */ + thread_info *thr = inferior_thread (); + + /* Construct the PTID of the thread-group leader. On Linux, + the leader's LWP ID is equal to the process ID. */ + ptid_t leader_ptid (thr->ptid.pid (), thr->ptid.pid ()); + + /* Use the thread-group leader if it is still alive. */ + thread_info *leader_thr + = current_inferior ()->find_thread (leader_ptid); + if (leader_thr != nullptr) + return leader_thr->ptid; + + /* Otherwise, use the first thread that has not exited. */ + thread_info *non_exited_thread + = current_inferior ()->first_non_exited_thread (); + gdb_assert (non_exited_thread != nullptr); + return non_exited_thread->ptid; +} + /* This is how we want PTIDs from core files to be printed. */ static std::string @@ -841,9 +872,7 @@ static void linux_info_proc (struct gdbarch *gdbarch, const char *args, enum info_proc_what what) { - /* A long is used for pid instead of an int to avoid a loss of precision - compiler warning from the output of strtoul. */ - long pid; + ptid_t ptid; int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL); int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL); int environ_f = (what == IP_ENVIRON || what == IP_ALL); @@ -858,7 +887,8 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, { char *tem; - pid = strtoul (args, &tem, 10); + long pid = strtoul (args, &tem, 10); + ptid = ptid_t (pid, pid); args = tem; } else @@ -868,17 +898,23 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, if (current_inferior ()->fake_pid_p) error (_("Can't determine the current process's PID: you must name one.")); - pid = current_inferior ()->pid; + ptid = get_process_reference_ptid (); + + if (ptid.pid () == ptid.lwp ()) + gdb_printf (_("process %d\n"), ptid.pid ()); + else + gdb_printf (_("process %d [Note: information was gathered from LWP %ld " \ + "as the thread-group leader (LWP=%d) already exited.]\n"), + ptid.pid (), ptid.lwp (), ptid.pid ()); } args = skip_spaces (args); if (args && args[0]) error (_("Too many parameters: %s"), args); - gdb_printf (_("process %ld\n"), pid); if (cmdline_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", ptid.lwp ()); gdb_byte *buffer; LONGEST len = target_fileio_read_alloc (nullptr, filename, &buffer); @@ -900,7 +936,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (cwd_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/cwd", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/cwd", ptid.lwp ()); std::optional contents = target_fileio_readlink (NULL, filename, &target_errno); if (contents.has_value ()) @@ -910,7 +946,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (environ_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/environ", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/environ", ptid.lwp ()); gdb_byte *buffer; LONGEST len = target_fileio_read_alloc (nullptr, filename, &buffer); @@ -934,7 +970,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (exe_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/exe", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/exe", ptid.lwp ()); std::optional contents = target_fileio_readlink (NULL, filename, &target_errno); if (contents.has_value ()) @@ -944,7 +980,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (mappings_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/maps", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/maps", ptid.lwp ()); gdb::unique_xmalloc_ptr map = target_fileio_read_stralloc (NULL, filename); if (map != NULL) @@ -989,7 +1025,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (status_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/status", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/status", ptid.lwp ()); gdb::unique_xmalloc_ptr status = target_fileio_read_stralloc (NULL, filename); if (status) @@ -999,7 +1035,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args, } if (stat_f) { - xsnprintf (filename, sizeof filename, "/proc/%ld/stat", pid); + xsnprintf (filename, sizeof filename, "/proc/%ld/stat", ptid.lwp ()); gdb::unique_xmalloc_ptr statstr = target_fileio_read_stralloc (NULL, filename); if (statstr) @@ -1670,9 +1706,9 @@ linux_process_address_in_memtag_page (CORE_ADDR address) if (current_inferior ()->fake_pid_p) return false; - pid_t pid = current_inferior ()->pid; + ptid_t ptid = get_process_reference_ptid (); - std::string smaps_file = string_printf ("/proc/%d/smaps", pid); + std::string smaps_file = string_printf ("/proc/%ld/smaps", ptid.lwp ()); gdb::unique_xmalloc_ptr data = target_fileio_read_stralloc (NULL, smaps_file.c_str ()); @@ -1730,7 +1766,6 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, linux_dump_mapping_p_ftype *should_dump_mapping_p, linux_find_memory_region_ftype func) { - pid_t pid; /* Default dump behavior of coredump_filter (0x33), according to Documentation/filesystems/proc.txt from the Linux kernel tree. */ @@ -1743,12 +1778,12 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, if (current_inferior ()->fake_pid_p) return false; - pid = current_inferior ()->pid; + ptid_t ptid = get_process_reference_ptid (); if (use_coredump_filter) { std::string core_dump_filter_name - = string_printf ("/proc/%d/coredump_filter", pid); + = string_printf ("/proc/%ld/coredump_filter", ptid.lwp ()); gdb::unique_xmalloc_ptr coredumpfilterdata = target_fileio_read_stralloc (NULL, core_dump_filter_name.c_str ()); @@ -1762,7 +1797,7 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, } } - std::string maps_filename = string_printf ("/proc/%d/smaps", pid); + std::string maps_filename = string_printf ("/proc/%ld/smaps", ptid.lwp ()); gdb::unique_xmalloc_ptr data = target_fileio_read_stralloc (NULL, maps_filename.c_str ()); @@ -1770,7 +1805,7 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, if (data == NULL) { /* Older Linux kernels did not support /proc/PID/smaps. */ - maps_filename = string_printf ("/proc/%d/maps", pid); + maps_filename = string_printf ("/proc/%ld/maps", ptid.lwp ()); data = target_fileio_read_stralloc (NULL, maps_filename.c_str ()); if (data == nullptr) @@ -2274,7 +2309,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) /* The state of the process. */ char pr_sname; /* The PID of the program which generated the corefile. */ - pid_t pid; + ptid_t ptid = get_process_reference_ptid (); /* Process flags. */ unsigned int pr_flag; /* Process nice value. */ @@ -2285,8 +2320,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) gdb_assert (p != nullptr); /* Obtaining PID and filename. */ - pid = inferior_ptid.pid (); - xsnprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid); + xsnprintf (filename, sizeof (filename), "/proc/%ld/cmdline", ptid.lwp ()); /* The full name of the program which generated the corefile. */ gdb_byte *buf = nullptr; LONGEST buf_len = target_fileio_read_alloc (nullptr, filename, &buf); @@ -2309,7 +2343,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) memset (p, 0, sizeof (*p)); /* Defining the PID. */ - p->pr_pid = pid; + p->pr_pid = ptid.pid (); /* Copying the program name. Only the basename matters. */ basename = lbasename (fname.get ()); @@ -2326,7 +2360,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) strncpy (p->pr_psargs, psargs.c_str (), sizeof (p->pr_psargs) - 1); p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0'; - xsnprintf (filename, sizeof (filename), "/proc/%d/stat", (int) pid); + xsnprintf (filename, sizeof (filename), "/proc/%ld/stat", ptid.lwp ()); /* The contents of `/proc/PID/stat'. */ gdb::unique_xmalloc_ptr proc_stat_contents = target_fileio_read_stralloc (NULL, filename); @@ -2404,7 +2438,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) /* Finally, obtaining the UID and GID. For that, we read and parse the contents of the `/proc/PID/status' file. */ - xsnprintf (filename, sizeof (filename), "/proc/%d/status", (int) pid); + xsnprintf (filename, sizeof (filename), "/proc/%ld/status", ptid.lwp ()); /* The contents of `/proc/PID/status'. */ gdb::unique_xmalloc_ptr proc_status_contents = target_fileio_read_stralloc (NULL, filename); @@ -3205,9 +3239,9 @@ linux_address_in_shadow_stack_mem_range if (!target_has_execution () || current_inferior ()->fake_pid_p) return false; - const int pid = current_inferior ()->pid; + ptid_t ptid = get_process_reference_ptid (); - std::string smaps_file = string_printf ("/proc/%d/smaps", pid); + std::string smaps_file = string_printf ("/proc/%ld/smaps", ptid.lwp ()); gdb::unique_xmalloc_ptr data = target_fileio_read_stralloc (nullptr, smaps_file.c_str ()); diff --git a/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.c b/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.c new file mode 100644 index 00000000000..0686b746c06 --- /dev/null +++ b/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.c @@ -0,0 +1,48 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2026 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 + +static pthread_t main_thread; + +static void * +start (void *arg) +{ + int i; + + i = pthread_join (main_thread, NULL); + assert (i == 0); + + return arg; /* break-here */ +} + +int +main (void) +{ + pthread_t thread; + int i; + + main_thread = pthread_self (); + + i = pthread_create (&thread, NULL, start, NULL); + assert (i == 0); + + pthread_exit (NULL); + assert (0); + return 0; +} diff --git a/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.exp b/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.exp new file mode 100644 index 00000000000..67bf3a17c26 --- /dev/null +++ b/gdb/testsuite/gdb.threads/access-procfs-while-thread-leader-exited.exp @@ -0,0 +1,78 @@ +# Copyright 2026 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 . + +standard_testfile +set corefile [standard_output_file ${testfile}.core] + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != ""} { + return +} + +clean_restart ${testfile} + +gdb_test_no_output "set non-stop on" + +if {![runto_main]} { + return +} + +gdb_test_multiple "info threads" "threads are supported" { + -re ".* main .*\r\n$gdb_prompt $" { + # OK, threads are supported. + } + -re "\r\n$gdb_prompt $" { + unsupported "gdb does not support threads on this target" + return + } +} + +gdb_breakpoint ${srcfile}:[gdb_get_line_number "break-here"] +# gdb_continue_to_breakpoint does not work as it uses "$gdb_prompt $" regex +# which does not work due to the output: (gdb) [Thread ... exited] +set name "continue to breakpoint: break-here" +gdb_test_multiple "continue" $name { + -re "Breakpoint .* (at|in) .* break-here .*\r\n$gdb_prompt " { + pass $name + } +} + +set test "info proc" +set fail_re \ + [multi_line \ + "process $decimal" \ + "warning: unable to open /proc file '/proc/$decimal/cmdline'" \ + "warning: unable to read link '/proc/$decimal/cwd'" \ + "warning: unable to read link '/proc/$decimal/exe'"] +set pass_re \ + [multi_line \ + "process $decimal \\\[Note: information was gathered from LWP $decimal as the thread-group leader \\(LWP=$decimal\\) already exited\\.\\\]" \ + "cmdline = '$binfile'" \ + "cwd = '.+'" \ + "exe = '$binfile'"] + +gdb_test_multiple "$test" $test { + -re -wrap $fail_re { + fail $test + } + -re -wrap $pass_re { + pass $test + } +} + +# Do not run "info threads" before "gcore" as it could workaround the bug +# by discarding non-current exited threads. +gdb_test "info threads" \ + {The current thread has terminated\. See `help thread'\.} \ + "exited thread is current due to non-stop" -- 2.55.0