From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id qcnPJ3PweGklQRgAWB0awg (envelope-from ) for ; Tue, 27 Jan 2026 12:05:55 -0500 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=I0MlIRlu; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=I0MlIRlu; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 9D5401E0DD; Tue, 27 Jan 2026 12:05:55 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.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,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 CFA171E08D for ; Tue, 27 Jan 2026 12:05:53 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 2399D4BAD168 for ; Tue, 27 Jan 2026 17:05:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2399D4BAD168 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=I0MlIRlu; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.a=rsa-sha256 header.s=selector1 header.b=I0MlIRlu 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 59DFE4BA900D for ; Tue, 27 Jan 2026 17:04:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 59DFE4BA900D 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 59DFE4BA900D Authentication-Results: server2.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=1769533458; cv=pass; b=qKyXRVhiw2O8QDrLXRC3PE4SJQeHhIjnLsHgGqWgol9lx2I7FG4s55jG/dOfId90SPEyvTCbhLnbQ2aKmlFEpQXo+pV4UbuwFDp2O8t5WWpPJq3MKLnrdmhY5pJ+RTYvMnKhFcXV2tykf+yzSi6UFiuofe9Rmpr6EfdAF32g1Hg= ARC-Message-Signature: i=3; a=rsa-sha256; d=sourceware.org; s=key; t=1769533458; c=relaxed/simple; bh=zflKeATROHJk5u2kumJuL9hU01qOz0SDr+U2UxSUtuw=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=d2zB+R+6qM8+KBRcR1CjOiUGZ/BqoilpTbWdXXuykhaPBNz82fONmoLkc65YDvMaUVBbHnHt8Cv75tTAeuNcLb7fEDSY6IcDtfKMkaRtvNqW+JmmvFClc7t1vK293M74Ha9ueIoSVk7dA7rnJiahoy73J5uicXY6Yt5NgWMI+BY= ARC-Authentication-Results: i=3; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 59DFE4BA900D ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=iAETK8vuTCDXSBe2vbMujgLoHG0P1/KPKDJOxwmVkskTYfrCO/Jzu/pSHSqq42dQ53CHopLC12W8gb5SckMnBR9CltCo6UTIRQ2nk95dpfvUvf7lPikjcnNacakkBhBJC0c1g4jvMP5MYUjZdbOznGFXJKqRhZCXqQZXGvFZJHPc+0ow2R469aHspQtelyInZGlujrCkj5n+ru0yJRl5qrA0BCKRBx6AmaDEUHpgULzPOFOpVDPLklP5gys6Mi2epzluBsGdyPLPYWXPdqQQwmAk7lUPiAArexu6qzQvXnXRUb6kFZCCDIMsfWcDW5RjPsJo0xZ9jbcpnKlXleSFew== 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=aAl5Vpv7H4YVQxHmvbHz53CLJTPNYtdo+eZfsxdGZJw=; b=hmzSSAGD/41tx4ng8vXtIhGJT2sCt0Pv2WWqB0fQPaAZ+OEOM3HPxTAAGirjvobHZfEoAC53rHG+iR9y1i3dlcIzl0hyILFmCYEHrBa70BtNoQkc8UTXjxNXDF2NyIIJ5kGY9VmjcOjF7UeI+g2Ew/EGtiYGjI+zQ26iv6IUYhh4IB8jSKmMIj9RJf6LD3AWBD8sWkncZB/NmxvFGizd7aiiwc3WqS78HXIX1GGmR5x/xekFiwa3DYEuGnv3aenpefA5jQQ5GYvOdF8zD0ThC0x7LjF3uoEb0vKCuTt9KbmEnPd3/4zeQCf1h6/moLJpFfaMaPNAPJxdsXXpc6QonQ== 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=aAl5Vpv7H4YVQxHmvbHz53CLJTPNYtdo+eZfsxdGZJw=; b=I0MlIRluoe7xMogQT4dU89o4tVlAYnf88Sys/L5sEA95JB2tkJyY3QPHpp7S657wuz4rFRhDS3t5L299f27uvECxViojLYdzOj7riCosxlaj7qNrn2y8aMLG1BWek9pjfM1U48v1Xm+jxTmFVJpzcQPAml5qcp4+Fon+QTm0nxI= Received: from AS8P189CA0019.EURP189.PROD.OUTLOOK.COM (2603:10a6:20b:31f::32) by AS8PR08MB6168.eurprd08.prod.outlook.com (2603:10a6:20b:294::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.14; Tue, 27 Jan 2026 17:04:08 +0000 Received: from AMS0EPF000001B3.eurprd05.prod.outlook.com (2603:10a6:20b:31f:cafe::e) by AS8P189CA0019.outlook.office365.com (2603:10a6:20b:31f::32) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9542.16 via Frontend Transport; Tue, 27 Jan 2026 17:04:05 +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 AMS0EPF000001B3.mail.protection.outlook.com (10.167.16.167) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9564.3 via Frontend Transport; Tue, 27 Jan 2026 17:04:08 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=BOGSiX5ne9GTW8HAoiLB4J8Lbgt8MnvDR4zraKTEuamMD0ZB5m0QxENt5EPOopzdKVLzaWjmc+KSAlXtxvc+GaHICXURCR1pe1XIoe+HB8IWvFzEeNBPf/LMZP8kY6Zc2b9JDNVhtUL8UNMXWvOy/2yOMImvnBQwmglOF7AzA8fO0OQ288rFc32Z/XsAUR3dw6XgXb1gpme8EOd9aoLRLT5Z5gkAb/VdTLIbEc2gCVp7O1yEfW0uOfF//oRGFClkTLyeVBlQL3BLG3lbN913BCXWNU1/XKQtnd9xcaPUQGBFfRy1v50xBjtOZm5cxdS7h+L6aNfNVGRmxr8qIAf0rQ== 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=aAl5Vpv7H4YVQxHmvbHz53CLJTPNYtdo+eZfsxdGZJw=; b=Ek33Yo7Cj0MpjS7TjwUwR5qh9DYsmHlYkAm5cD5mHhSdQm5VGLlf0ACgVlHwydG1uG9aUhjvM8X/OmSmx8jStt+x8HIvGLqNlTohqjAHTnw6ivU6pHQYGsWfmTv9b62zBaydQ0KAId3g9jzkP9rJsDcz3J7ycSEMe51caYMoDgzssejY8BNH92vz8YFN8g+LoeEB5dwZIH59RK5sTakIY0BzialwbHU4+KCxGbKx5hViU8V5pzmDFuMLasgmEAYFCWkBPdYFnan+W59Xu6uZXv2ijx+uXdB4JmqCZIrprw+ZRNqTQI4+8SQhPYHPw/FAU7qH4gu1NCutlZ6Q/Hvlxg== 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=aAl5Vpv7H4YVQxHmvbHz53CLJTPNYtdo+eZfsxdGZJw=; b=I0MlIRluoe7xMogQT4dU89o4tVlAYnf88Sys/L5sEA95JB2tkJyY3QPHpp7S657wuz4rFRhDS3t5L299f27uvECxViojLYdzOj7riCosxlaj7qNrn2y8aMLG1BWek9pjfM1U48v1Xm+jxTmFVJpzcQPAml5qcp4+Fon+QTm0nxI= Received: from DUZPR01CA0170.eurprd01.prod.exchangelabs.com (2603:10a6:10:4b3::28) by AS2PR08MB8806.eurprd08.prod.outlook.com (2603:10a6:20b:5f2::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9542.15; Tue, 27 Jan 2026 17:03:01 +0000 Received: from DU2PEPF00028D00.eurprd03.prod.outlook.com (2603:10a6:10:4b3:cafe::4d) by DUZPR01CA0170.outlook.office365.com (2603:10a6:10:4b3::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9564.7 via Frontend Transport; Tue, 27 Jan 2026 17:03:29 +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 DU2PEPF00028D00.mail.protection.outlook.com (10.167.242.184) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9564.3 via Frontend Transport; Tue, 27 Jan 2026 17:03:01 +0000 Received: from AZ-NEU-EX03.Arm.com (10.240.25.137) by AZ-NEU-EX03.Arm.com (10.240.25.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.29; Tue, 27 Jan 2026 17:02:59 +0000 Received: from PF4S4363.arm.com (10.57.51.184) by mail.arm.com (10.240.25.137) with Microsoft SMTP Server id 15.2.2562.29 via Frontend Transport; Tue, 27 Jan 2026 17:02:59 +0000 From: Matthieu Longo To: CC: Tom Tromey , Matthieu Longo Subject: [PATCH v2 4/6] gdb: new setters and getters for __dict__, and attributes Date: Tue, 27 Jan 2026 17:02:13 +0000 Message-ID: <20260127170215.1803582-5-matthieu.longo@arm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260127170215.1803582-1-matthieu.longo@arm.com> References: <20260127170215.1803582-1-matthieu.longo@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 1 X-MS-TrafficTypeDiagnostic: DU2PEPF00028D00:EE_|AS2PR08MB8806:EE_|AMS0EPF000001B3:EE_|AS8PR08MB6168:EE_ X-MS-Office365-Filtering-Correlation-Id: 611a4625-5cd8-4637-53c5-08de5dc615f4 x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; ARA:13230040|36860700013|1800799024|376014|82310400026|13003099007; X-Microsoft-Antispam-Message-Info-Original: =?utf-8?B?eWpQSXBIRWpub0lTSTZWOWJKRDV4eWF4SVAvdExoL2V4elpLVUZHZHR1a2tO?= =?utf-8?B?dVdIUFlqeW1YSFZzay9lay9ZWlRjLzZSQTlWaW9MeGROaS9VOUhuNkw4RE5J?= =?utf-8?B?KzYzVGFrQ1ZmUjJrL2pEaXlaZzlQT25qVjJGT3pOTTRnUy91Sm1kcU9PM2VE?= =?utf-8?B?U09XeHBvbU9FcGxvY0VhcDBUeEhCN3liazF0R3NHay9BMHNnQWkrMGFtVEVG?= =?utf-8?B?b09oYWg2RjZJVXJjRm5qSUJuU0xFNW51c2lqVHFaMzUwalBUTUVNOE93NXQ2?= =?utf-8?B?SUxteEhSNFIrQ3JtZXFKRVRpemhYL2ROL0JSWmwzQ3VKYXFUeDE3SmtHdWFh?= =?utf-8?B?cWppdVA3U0pYQVU0aXQ4WTlTQmZURXl6VnJ3VWhwV1FhOE5lbXRwNVRqYU5K?= =?utf-8?B?ak5TcUhLK0NQRGJYY0VaVE1uNytOWG5TdURPWU1wQVFrOGR5VHloQVRHeEx6?= =?utf-8?B?YkY5TVJhdW1UL1NHcFlSNTRFYVpDWEhLWnJkU3F0TFdDUGdXNFlETzJMTkI2?= =?utf-8?B?OTVkZC90WVRKWWM0NmFGZzk2ZWhFNTh6YUhETkdaR2UvZ2xKZ25hSm5DWkM3?= =?utf-8?B?Zm9nNWxVa3NPUEtMdjV0emthVEJKSkx0SmFWWnZ6V05Tb3VwR01Sang1QTQ1?= =?utf-8?B?ZXVDKytURXdYOUFTR3hlbEpMMkI1Y0VqTGRxSGIrcWRHU1I4VW5HZ0xMNkdY?= =?utf-8?B?ekppckQxS2F4dmVFK1gwcWZLS3Y1NkNSUXp5V29leTZpdW1vTEpIVE1XRU44?= =?utf-8?B?N3VLOTRJT3VPRWlpcVRIc2JzZnNtRnc5dkVMRnFLWStRODQ4SUYxOFpsamVy?= =?utf-8?B?K0cvTTgxYm1sWE5mcmJ0c3pHWDhJT3ZiVmFubTAvZDJJZG10amx2bFRzZFRM?= =?utf-8?B?aE56L1E4V1hQeXlHUTlKQVgySTdVeVlhdnkvMVVGRkN6RGk2eGhiV0pnQ1g4?= =?utf-8?B?ZlpWbzVOU0F4RGQzLyszSGp1UjhnL045c0Q5V28vQ2V5cEw2NkRIT0FnWlJl?= =?utf-8?B?ckwzY0dhYTMvdGVSeTJ6S3BCdGpYUmNOcklJOU1tc2xWdVhpNzBUaFAwR1Rt?= =?utf-8?B?dTBLSWRMQloyT2pLcFZJLzdSNkd4TWZXQTFDVEhidnQzQjVieGlpRzRXMkwy?= =?utf-8?B?Z3UrYWZzZkpCN092OFIwV1pocHFQK04zKzlSTVJ2NzR1QmRWbzBDZWM3RSt4?= =?utf-8?B?VEVySWpXQ20vNDZTdFBISjFINlpOY1lnT1hYM2cxcFNwVzZnKzFOaFRXVnpw?= =?utf-8?B?MldWd1JuVzllWnhkZi80a1VvN3labEg0dEkxQ2NiZWoyb0QzL09idjVXWFhZ?= =?utf-8?B?OWo1cXBkVGdCNkRQRHJKcU5JbjdIdXRZeXoxTTI3M0hZZzA3YTNYSWtCQVJK?= =?utf-8?B?UHQ5MjZmTk5PQXlCQ2Q2dzVxWDBQUlNiY3lhZkdweUNDOEw1UGFHTi9LWThn?= =?utf-8?B?SU5YQ01GYXpPNnlQK1gyNnRTWWNSSEhMWVRvL1dsVDZzNlhBUlQzTE1zcmhx?= =?utf-8?B?cVlsMGw2WmMzbHR4cjFkTVI4aHA0Q2Iyb2hnTW1LVWxCMDFMSE9GOU13WUpa?= =?utf-8?B?V1hSc1JiOHB3dDFUNk5FNEhhYjQ2elRzdlhySkVYYmVwbmJ1NjNnU0Z4akpG?= =?utf-8?B?NWtWVjlCRGI5aGlpU1NOMmNEenUxejBwT0p1LzdaTnhqcUh4OWpkdzVBbEhU?= =?utf-8?B?YUwxYWlFaWdwMmwwNG11dVNrUW5PRnpMbnlPYWZ3bG9pb3ppT2dWMytYVW1R?= =?utf-8?B?dnErUE5yNWFwRXVhaTVPdUVDSGlsUStxcXdoNTBMODMvM2k1Y2VOTk5uVEFx?= =?utf-8?B?ZkJ4dzY2amFFR2R2SVZhUWtLYVZRbFc1NjVsUkd0M1oxM2wyM3NjemIzRm9z?= =?utf-8?B?cmFMbWI2aUwwTEJNSUg1eEhDN0dKTVZwbHJDRVJ2eHdNNmkrcmpzQS8wOUhl?= =?utf-8?B?cVNuM1FOVEFoaHlsZW1lUmhwZEcyQkZEeE0vK3llM3pMVVBMQk8zNGRPT3h3?= =?utf-8?B?YkNPMitrTzFzcG9OSWcxVzN2QXBHZ2lTTUx0bVQ2U0FSR2plQndLZkhHNXpw?= =?utf-8?B?Y05sY3ZpcDZEcVdyRGI0YitLbmg1NVBKSjJEQVRreUlZZG1TdHJvRlFnZUFu?= =?utf-8?B?MitJWE5rVmUyZlc1ZVJtNWxmTmdHUFp5dU0wVUJ3clV3cm1HaisydGEvbGQ0?= =?utf-8?B?Q05NYzAvRGwwVW83Z2lOWDBJQ0JHcmgwajhBM3kreGNjZytGSFN1L0p1UVhQ?= =?utf-8?B?anNjcmYvdnEyVVRVSVYxbENKdDd3PT0=?= 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)(36860700013)(1800799024)(376014)(82310400026)(13003099007); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR08MB8806 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AMS0EPF000001B3.eurprd05.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: f1fbe115-5cb0-4ed3-61f6-08de5dc5edbd X-Microsoft-Antispam: BCL:0; ARA:13230040|35042699022|36860700013|14060799003|1800799024|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?utf-8?B?a2tjZXVjU1U1REJmRVZPWDBqU0pWNUVXTjJSb0s3enQ4ZUFmYm9IWDNOdnJ1?= =?utf-8?B?WVlQYWYrZGZ6THNnRFBNUTBLNGxGNUsxYVlNSTk5bXBSek9RSEZWbXRqOHBz?= =?utf-8?B?dnl4NkVUeHN5U2t5UXRVellBOCtwU0pvZXJ5d2dkc29UK2ZFNTAwNnNoNDQw?= =?utf-8?B?MTlZSG1oekdRRUpaN25EZS9XdWhVeUQvWmVYeWJBRFlTN3N6eklONVJCVzEx?= =?utf-8?B?ZzJpZ09VcGxQZFNBaVBrSFRFVmxHUlZJNURiVmowdGZIMXFRMFZjcFNHWmRT?= =?utf-8?B?UGxWNmh5SmJ4NFFETkxsRjJmNlNHVUpLMjl6YVBGdWxzbkNlMmtMeDlHSTFJ?= =?utf-8?B?Z254dWhoT2d2R0E1c3BiS3hXRlhTNytwTGZKZXRmR1JYQ2ZMeHNqUWVCSDlN?= =?utf-8?B?Vmt1WnFVd2VnemdCYk5WbFlqMzdpYXkzYVF4V0tyak96TThrQ043cGxwY3E1?= =?utf-8?B?d1pFUFFOaDVvOWpIYlpzZ1BnMnhibE5KVWJRTmJiRld4NGtneFhobFdTTmIz?= =?utf-8?B?aVBDQkpFSDk0a09ReWlsbENERGx3Y3ZDUitub0F5akRmV0xVN0pZN3p0SEtI?= =?utf-8?B?Y3RSU3ByNEJXUUhWNXROSDhxTmJzdmQzaldaMFlrZUtUQysySlc4TDhQTzd2?= =?utf-8?B?WUx2Y25DNFZ1TU9aeEQzQ1lQR1orNWFYcldQMlhqRDlYYjNMSUZHUVNEUXd2?= =?utf-8?B?aHUwVWVFQm5WanJ3U3pDLzc3UEVwME9qMWZ5T1ZaYmR1T2hsM2J6MHppeGpY?= =?utf-8?B?VUtDVDVDQXZqYWVMN1lvU3V2UlVLVjhYUjdjQksvWmdURWlnR0w4U0ZFOVZo?= =?utf-8?B?QlBrUE9BUno3bmQyRnJ5WEVHR3pGSUZpcThyUjVETW5wUnAvOWkxNWZMbUpV?= =?utf-8?B?dXRZTy8veEgvMUs0dVY5V0lJcHZ6MXRaSTI0SDJlUS95bDh3NmlERUlobExS?= =?utf-8?B?S2Z6cm1FUGxPQTlKRkFLUVZEdTNKZUpTUjg1WDBvc0dxNjArWjhpQldiSnBY?= =?utf-8?B?RGJEOHJ2TG5FandkdldIUGVxTWRDbHhkWnhnU2Zrc0QzZWNWNURDSzlDRUly?= =?utf-8?B?Yyt1ajNmQ3drbTNwcXI0a1ZjalNtd3ZlUDFld3g5SzJ5VnJtL2JuN05jZWFB?= =?utf-8?B?a2FGV3FZZ0ZGUytGMmxLVTBOUWxnMHVQZjFiRFR4S245RWhSWEFEWnZXaXFH?= =?utf-8?B?RGpmbjFmdVk0VDdXNWVIYlN2M21ZRkdKekt4cFBMc0dKbWhKS3VvN2tHYm1U?= =?utf-8?B?OWJQNUdQcHdSamZiRFJWWWRIUXNxbTkvYVhzeEtIemdLaHJESHRvUTJHbTdR?= =?utf-8?B?aXdNaHFqOGNSMUN4QndDNCtHb1JvMG9SY3VvZDZXbndQeXJEamNjeHdiRHM4?= =?utf-8?B?ZFYrVTRtMkVyWmlUZVd6bFBhT2IyU2NnVnpJalJibjdqWkkvZUZvVVJLelA2?= =?utf-8?B?SHBtN2d1eXBzNDlFNTM4N3lkdU1PV0pIQWY4SkM0UDkrelNFei85ZHl5YTFL?= =?utf-8?B?UWR4a2x5eTAwNWVTdXJRd3BMeTUvR093LzJSNnNhcU81K3VZc3hReWdvYVFt?= =?utf-8?B?aW11VitwRmUvcnJYUlF3VnJCalMrNzk2aUdwdjlveUxPd3dqN1REaXVmbGpI?= =?utf-8?B?cE1OTlFZZ09rNCs0TkViU2FCdFM1SHRTNEVDcWZUNkFvbmpISzVod01rVlRX?= =?utf-8?B?bEJwVXpNWjNFdnJWMjNSc2RiSmlpdGR4M3l2SmYvc1FNdGlRTm9vRzdkdERm?= =?utf-8?B?UW1PQjNZaXNhUkk3djNKcFY4MGt2K3liUFdtWnJQREtJcXZ3bzhDVEpWalhH?= =?utf-8?B?Y1NKdktDUHVBYXcydUNuOUEzTXU1S0R3Ymw5MWh3L1k0dFNWYkt6S3J1TFkw?= =?utf-8?B?YnpBcDdIUk5RQ2FZQ1drSmhRZ3o0MmdVZStGbE1aa0pZNEVQY0E5SDdiaExu?= =?utf-8?B?UlVBeExaMzhWZm9vNkd5ODA0TFhiS0xnb0UzbEh4L0pHMEMzbmhUdTNUNWNy?= =?utf-8?B?M084SmNvbVhiWTlheVk0M3VQbFRMbzJaM0lCUXVyOWV0dGF3TnR0Rjd4cHBI?= =?utf-8?B?NXFyRjBidUx4MmZQaTdIVk83cnpTNTM0N3VKK1VKTEREYmRrVkxPemZSTkI0?= =?utf-8?B?eWI5Z1pCMnllN3NvWTZXQ0RtbHIwVUxSbXR4Rm9PZnpzWGNFakZXdWw0TTdM?= =?utf-8?B?SHZCOFNvNGx5ZE5UdFl4WnovbmUvTWU0NGxKS0FhWjJpNXNsaWNZQTNvKzJp?= =?utf-8?B?dnRSaEtaN1lnME9JN1AvanBWc0NBPT0=?= 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)(36860700013)(14060799003)(1800799024)(376014)(82310400026); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2026 17:04:08.5946 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 611a4625-5cd8-4637-53c5-08de5dc615f4 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: AMS0EPF000001B3.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR08MB6168 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 GDB is currently using the Python unlimited API. Migrating the codebase to the Python limited API would have for benefit to make a GDB build artifacts compatible with older and newer versions of Python that they were built with. This patch prepares the ground for migrating the existing C extension types from static types to heap-allocated ones, by removing the dependency on tp_dictoffset, which is unavailable when using the limited API. One of the most common incompatibilities in the current static type declarations is the tp_dictoffset slot, which specifies the dictionary offset within the instance structure. Historically, the unlimited API has provided two approaches to supply a dictionary for __dict__: * A managed dictionary. Setting Py_TPFLAGS_MANAGED_DICT in tp_flags indicates that the instances of the type have a __dict__ attribute, and that the dictionary is managed by Python. According to the Python documentation, this is the recommended approach. However, this flag was introduced in 3.12, together with PyObject_VisitManagedDict() and PyObject_ClearManagedDict(), neither of which is part of the limited API (at least for now). As a result, this recommended approach is not viable in the context of the limited API. * An instance dictionary, for which the offset in the instance is provided via tp_dictoffset. According to the Python documentation, this "tp slot" is on the deprecation path, and Py_TPFLAGS_MANAGED_DICT should be used instead. Given the age of the GDB codebase and the requirement to support older Python versions (>= 3.4), no need to argue that today, the implementation of __dict__ relies on tp_dictoffset. However, in the context of the limited API, PyType_Slot does not provide a Py_tp_dictoffset member, so another approach is needed to provide __dict__ to instances of C extension types. Given the constraints of the limited API, the proposed solution consists in providing a dictionary through a common base class, gdbpy__dict__wrapper. This helper class owns a dictionary member corresponding to __dict__, and any C extension type requiring a __dict__ must inherit from it. Since extension object must also be convertible to PyObject, this wrapper class publicly inherits from PyObject as well. Access to the dictionary is provided via a custom getter defined in a PyGetSetDef, similarily to what was previously done with gdb_py_generic_dict(). Because __dict__ participates in attribute look-up, and since this dictionary is neither managed by Python nor exposed via tp_dictoffset, custom implementations of tp_getattro and tp_setattro are required to correctly redirect attribute look-ups to the dictionary. These custom implementations — equivalent to PyObject_GenericGetAttr() and PyObject_GenericSetAttr() — must be installed via tp_getattro / tp_setattro for static types, or Py_tp_getattro / Py_tp_setattro for heap-allocated types. - gdbpy__dict__wrapper: a base class for C extension objects that own a __dict__. - gdb_py_generic_dict_getter: a __dict__ getter for extension types derived from gdbpy__dict__wrapper. - gdb_py_generic_dict_setter: a __dict__ setter provided for completeness. It should not be used, as __dict__ should be read-only after the object initialization. - gdb_py_generic_getattro: equivalent of PyObject_GenericGetAttr, but fixes the look-up of __dict__. - gdb_py_generic_setattro: equivalent of PyObject_GenericSetAttr, but fixes the look-up of __dict__. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830 --- gdb/python/py-corefile.c | 18 +++---- gdb/python/py-event.c | 10 ++-- gdb/python/py-event.h | 8 +-- gdb/python/py-inferior.c | 29 ++--------- gdb/python/py-infthread.c | 10 ++-- gdb/python/py-objfile.c | 18 +++---- gdb/python/py-progspace.c | 18 +++---- gdb/python/py-ref.h | 40 +++++++++++++++ gdb/python/py-type.c | 19 +++----- gdb/python/py-utils.c | 95 +++++++++++++++++++++++++++++++----- gdb/python/python-internal.h | 35 +++++++++---- 11 files changed, 192 insertions(+), 108 deletions(-) diff --git a/gdb/python/py-corefile.c b/gdb/python/py-corefile.c index 6847722628f..4a6982231c8 100644 --- a/gdb/python/py-corefile.c +++ b/gdb/python/py-corefile.c @@ -26,20 +26,14 @@ /* A gdb.Corefile object. */ -struct corefile_object +struct corefile_object: public gdbpy__dict__wrapper { - PyObject_HEAD - /* The inferior this core file is attached to. This will be set to NULL when the inferior is deleted, or if a different core file is loaded for the inferior. When this is NULL the gdb.Corefile object is considered invalid.*/ struct inferior *inferior; - /* Dictionary holding user-added attributes. This is the __dict__ - attribute of the object. This is an owning reference. */ - PyObject *dict; - /* A Tuple of gdb.CorefileMappedFile objects. This tuple is only created the first time the user calls gdb.Corefile.mapped_files(), the result is cached here. If this pointer is not NULL then this is an owning @@ -511,8 +505,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_corefile); static gdb_PyGetSetDef corefile_getset[] = { - { "__dict__", gdb_py_generic_dict, nullptr, - "The __dict__ for the gdb.Corefile.", &corefile_object_type }, + { "__dict__", gdb_py_generic_dict_getter, nullptr, + "The __dict__ for the gdb.Corefile.", nullptr }, { "filename", cfpy_get_filename, nullptr, "The filename of a valid Corefile object.", nullptr }, { nullptr } @@ -548,8 +542,8 @@ PyTypeObject corefile_object_type = 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ + gdb_py_generic_getattro, /*tp_getattro*/ + gdb_py_generic_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "GDB corefile object", /* tp_doc */ @@ -566,7 +560,7 @@ PyTypeObject corefile_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (corefile_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c index c985159a6f7..8fb21b7fdad 100644 --- a/gdb/python/py-event.c +++ b/gdb/python/py-event.c @@ -101,8 +101,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_event); static gdb_PyGetSetDef event_object_getset[] = { - { "__dict__", gdb_py_generic_dict, NULL, - "The __dict__ for this event.", &event_object_type }, + { "__dict__", gdb_py_generic_dict_getter, NULL, + "The __dict__ for this event.", NULL }, { NULL } }; @@ -124,8 +124,8 @@ PyTypeObject event_object_type = 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ + gdb_py_generic_getattro, /* tp_getattro */ + gdb_py_generic_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "GDB event object", /* tp_doc */ @@ -142,7 +142,7 @@ PyTypeObject event_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (event_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0 /* tp_alloc */ }; diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h index 6c81d64eb4f..d21ca1e2873 100644 --- a/gdb/python/py-event.h +++ b/gdb/python/py-event.h @@ -31,12 +31,8 @@ #include "py-event-types.def" #undef GDB_PY_DEFINE_EVENT_TYPE -struct event_object -{ - PyObject_HEAD - - PyObject *dict; -}; +struct event_object: public gdbpy__dict__wrapper +{}; extern int emit_continue_event (ptid_t ptid); extern int emit_exited_event (const LONGEST *exit_code, struct inferior *inf); diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 8230f9d3943..69a7bfa3c37 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -32,25 +32,6 @@ #include "progspace-and-thread.h" #include "gdbsupport/unordered_map.h" -using thread_map_t - = gdb::unordered_map>; - -struct inferior_object -{ - PyObject_HEAD - - /* The inferior we represent. */ - struct inferior *inferior; - - /* thread_object instances under this inferior. This owns a - reference to each object it contains. */ - thread_map_t *threads; - - /* Dictionary holding user-added attributes. - This is the __dict__ attribute of the object. */ - PyObject *dict; -}; - extern PyTypeObject inferior_object_type; /* Deleter to clean up when an inferior is removed. */ @@ -1061,8 +1042,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior); static gdb_PyGetSetDef inferior_object_getset[] = { - { "__dict__", gdb_py_generic_dict, nullptr, - "The __dict__ for this inferior.", &inferior_object_type }, + { "__dict__", gdb_py_generic_dict_getter, nullptr, + "The __dict__ for this inferior.", nullptr }, { "arguments", infpy_get_args, infpy_set_args, "Arguments to this program.", nullptr }, { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL }, @@ -1144,8 +1125,8 @@ PyTypeObject inferior_object_type = 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ + gdb_py_generic_getattro, /* tp_getattro */ + gdb_py_generic_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "GDB inferior object", /* tp_doc */ @@ -1162,7 +1143,7 @@ PyTypeObject inferior_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (inferior_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0 /* tp_alloc */ }; diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c index e5d3222f9ae..d75742360d4 100644 --- a/gdb/python/py-infthread.c +++ b/gdb/python/py-infthread.c @@ -415,8 +415,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_thread); static gdb_PyGetSetDef thread_object_getset[] = { - { "__dict__", gdb_py_generic_dict, nullptr, - "The __dict__ for this thread.", &thread_object_type }, + { "__dict__", gdb_py_generic_dict_getter, nullptr, + "The __dict__ for this thread.", nullptr }, { "name", thpy_get_name, thpy_set_name, "The name of the thread, as set by the user or the OS.", NULL }, { "details", thpy_get_details, NULL, @@ -479,8 +479,8 @@ PyTypeObject thread_object_type = 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ + gdb_py_generic_getattro, /*tp_getattro*/ + gdb_py_generic_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "GDB thread object", /* tp_doc */ @@ -497,7 +497,7 @@ PyTypeObject thread_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (thread_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0 /* tp_alloc */ }; diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 8cf365a27dc..802b85144ac 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -26,17 +26,11 @@ #include "python.h" #include "inferior.h" -struct objfile_object +struct objfile_object: public gdbpy__dict__wrapper { - PyObject_HEAD - /* The corresponding objfile. */ struct objfile *objfile; - /* Dictionary holding user-added attributes. - This is the __dict__ attribute of the object. */ - PyObject *dict; - /* The pretty-printer list of functions. */ PyObject *printers; @@ -739,8 +733,8 @@ Look up a static-linkage global symbol in this objfile and return it." }, static gdb_PyGetSetDef objfile_getset[] = { - { "__dict__", gdb_py_generic_dict, NULL, - "The __dict__ for this objfile.", &objfile_object_type }, + { "__dict__", gdb_py_generic_dict_getter, NULL, + "The __dict__ for this objfile.", NULL }, { "filename", objfpy_get_filename, NULL, "The objfile's filename, or None.", NULL }, { "username", objfpy_get_username, NULL, @@ -785,8 +779,8 @@ PyTypeObject objfile_object_type = 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ + gdb_py_generic_getattro, /*tp_getattro*/ + gdb_py_generic_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "GDB objfile object", /* tp_doc */ @@ -803,7 +797,7 @@ PyTypeObject objfile_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (objfile_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ objfpy_new, /* tp_new */ diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c index ee26b761adb..a531026655f 100644 --- a/gdb/python/py-progspace.c +++ b/gdb/python/py-progspace.c @@ -29,17 +29,11 @@ #include "observable.h" #include "inferior.h" -struct pspace_object +struct pspace_object: public gdbpy__dict__wrapper { - PyObject_HEAD - /* The corresponding pspace. */ struct program_space *pspace; - /* Dictionary holding user-added attributes. - This is the __dict__ attribute of the object. */ - PyObject *dict; - /* The pretty-printer list of functions. */ PyObject *printers; @@ -758,8 +752,8 @@ GDBPY_INITIALIZE_FILE (gdbpy_initialize_pspace); static gdb_PyGetSetDef pspace_getset[] = { - { "__dict__", gdb_py_generic_dict, NULL, - "The __dict__ for this progspace.", &pspace_object_type }, + { "__dict__", gdb_py_generic_dict_getter, NULL, + "The __dict__ for this progspace.", NULL }, { "filename", pspy_get_filename, NULL, "The filename of the progspace's main symbol file, or None.", nullptr }, { "symbol_file", pspy_get_symbol_file, nullptr, @@ -821,8 +815,8 @@ PyTypeObject pspace_object_type = 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ + gdb_py_generic_getattro, /*tp_getattro*/ + gdb_py_generic_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "GDB progspace object", /* tp_doc */ @@ -839,7 +833,7 @@ PyTypeObject pspace_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (pspace_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h index b09d88dc30d..a8f3ff9201b 100644 --- a/gdb/python/py-ref.h +++ b/gdb/python/py-ref.h @@ -42,4 +42,44 @@ struct gdbpy_ref_policy template using gdbpy_ref = gdb::ref_ptr>; +/* A wrapper class for Python extension objects that have a __dict__ attribute. + + Any Python C object extension needing __dict__ should inherit from this + class. Given that the C extension object must also be convertible to + PyObject, this wrapper class publicly inherits from PyObject as well. + + Access to the dict requires a custom getter defined via PyGetSetDef. + gdb_PyGetSetDef my_object_getset[] = + { + { "__dict__", gdb_py_generic_dict_getter, nullptr, + "The __dict__ for this object.", nullptr }, + ... + { nullptr } + }; + + It is also important to note that __dict__ is used during the attribute + look-up. Since this dictionary is not managed by Python and is not exposed + via tp_dictoffset, custom attribute getter (tp_getattro) and setter + (tp_setattro) are required to correctly redirect attribute access to the + dictionary: + - gdb_py_generic_getattro (), assigned to tp_getattro for static types, + or Py_tp_getattro for heap-allocated types. + - gdb_py_generic_setattro (), assigned to tp_setattro for static types, + or Py_tp_setattro for heap-allocated types. */ +struct gdbpy__dict__wrapper: public PyObject +{ + /* Dictionary holding user-added attributes. + This is the __dict__ attribute of the object. */ + PyObject *dict; + + /* Compute the address of the __dict__ attribute for the given PyObject. + The CLOSURE argument is unused. */ + static PyObject ** + compute_addr (PyObject *self, void *closure ATTRIBUTE_UNUSED) + { + auto *wrapper = reinterpret_cast (self); + return &wrapper->dict; + } +}; + #endif /* GDB_PYTHON_PY_REF_H */ diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 40adbf0bb7d..1cc583b38d2 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -36,13 +36,8 @@ struct type_object: public PyObject extern PyTypeObject type_object_type; /* A Field object. */ -struct field_object -{ - PyObject_HEAD - - /* Dictionary holding our attributes. */ - PyObject *dict; -}; +struct field_object: public gdbpy__dict__wrapper +{}; extern PyTypeObject field_object_type; @@ -1707,8 +1702,8 @@ PyTypeObject type_object_type = static gdb_PyGetSetDef field_object_getset[] = { - { "__dict__", gdb_py_generic_dict, NULL, - "The __dict__ for this field.", &field_object_type }, + { "__dict__", gdb_py_generic_dict_getter, NULL, + "The __dict__ for this field.", NULL }, { NULL } }; @@ -1730,8 +1725,8 @@ PyTypeObject field_object_type = 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ + gdb_py_generic_getattro, /*tp_getattro*/ + gdb_py_generic_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "GDB field object", /* tp_doc */ @@ -1748,7 +1743,7 @@ PyTypeObject field_object_type = 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof (field_object, dict), /* tp_dictoffset */ + 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c index 131230f80b3..81c787ac43c 100644 --- a/gdb/python/py-utils.c +++ b/gdb/python/py-utils.c @@ -309,24 +309,97 @@ gdb_py_int_as_long (PyObject *obj, long *result) -/* Generic implementation of the __dict__ attribute for objects that - have a dictionary. The CLOSURE argument should be the type object. - This only handles positive values for tp_dictoffset. */ +/* Generic implementation of the getter for the __dict__ attribute for objects + having a dictionary. The CLOSURE argument is unused. */ PyObject * -gdb_py_generic_dict (PyObject *self, void *closure) +gdb_py_generic_dict_getter (PyObject *self, void *closure) { - PyObject *result; - PyTypeObject *type_obj = (PyTypeObject *) closure; - char *raw_ptr; + PyObject **py_dict_ptr = gdbpy__dict__wrapper::compute_addr (self, closure); + PyObject *py_dict = *py_dict_ptr; + if (py_dict == nullptr) + { + PyErr_SetString (PyExc_AttributeError, + "This object has no __dict__"); + return nullptr; + } + return Py_NewRef (py_dict); +} - raw_ptr = (char *) self + type_obj->tp_dictoffset; - result = * (PyObject **) raw_ptr; +/* Generic implementation of the setter for the __dict__ attribute for objects + having a dictionary. The CLOSURE argument is unused. */ - Py_INCREF (result); - return result; +int +gdb_py_generic_dict_setter (PyObject *self, PyObject *value, void *closure) +{ + if (value == nullptr) + { + PyErr_SetString (PyExc_TypeError, "cannot delete __dict__"); + return -1; + } + + PyObject **py_dict_ptr = gdbpy__dict__wrapper::compute_addr (self, closure); + + /* Delete the old value (if there is one). */ + if (*py_dict_ptr != nullptr) + Py_DECREF (*py_dict_ptr); + + *py_dict_ptr = Py_NewRef (value); + return 0; +} + +/* Generic attribute getter function similar to PyObject_GenericGetAttr () but + that should be used when the object has a dictionary __dict__. */ +PyObject * +gdb_py_generic_getattro (PyObject *self, PyObject *attr) +{ + PyObject *value = PyObject_GenericGetAttr (self, attr); + if (value != nullptr) + return value; + + if (! PyErr_ExceptionMatches (PyExc_AttributeError)) + return nullptr; + + /* Clear previous AttributeError set by PyObject_GenericGetAttr. */ + PyErr_Clear(); + + gdbpy_ref<> dict (gdb_py_generic_dict_getter (self, nullptr)); + value = PyDict_GetItemWithError (dict.get (), attr); + if (value != nullptr) + return Py_NewRef (value); + + PyErr_Format (PyExc_AttributeError, + "'%s' object has no attribute '%s'", + Py_TYPE (self)->tp_name, + PyUnicode_AsUTF8AndSize (attr, nullptr)); + return nullptr; } +/* Generic attribute setter function similar to PyObject_GenericSetAttr () but + that should be used when the object has a dictionary __dict__. */ +int +gdb_py_generic_setattro (PyObject *self, PyObject *attr, PyObject *value) +{ + if (PyObject_GenericSetAttr (self, attr, value) == 0) + return 0; + + if (! PyErr_ExceptionMatches (PyExc_AttributeError)) + return -1; + + /* Clear previous AttributeError set by PyObject_GenericGetAttr. */ + PyErr_Clear(); + + gdbpy_ref<> dict (gdb_py_generic_dict_getter (self, nullptr)); + /* Delete the old value (if there is one). */ + PyObject *old_value = PyDict_GetItem (dict.get (), attr); + if (old_value != nullptr) + Py_DECREF (old_value); + /* Set the new value. */ + return PyDict_SetItem (dict.get (), attr, value); +} + + + /* Like PyModule_AddObject, but does not steal a reference to OBJECT. */ diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 95619bf775e..cde2dfa2d52 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -107,6 +107,15 @@ typedef unsigned long gdb_py_ulongest; #endif /* HAVE_LONG_LONG */ +#if PY_VERSION_HEX < 0x030a0000 +static inline PyObject* +Py_NewRef (PyObject *obj) +{ + Py_INCREF (obj); + return obj; +} +#endif + /* A template variable holding the format character (as for Py_BuildValue) for a given type. */ template @@ -384,22 +393,27 @@ struct gdbpy_breakpoint_object extern gdbpy_breakpoint_object *bppy_pending_object; -struct thread_object +struct thread_object: public gdbpy__dict__wrapper { - PyObject_HEAD - /* The thread we represent. */ struct thread_info *thread; /* The Inferior object to which this thread belongs. */ PyObject *inf_obj; - - /* Dictionary holding user-added attributes. This is the __dict__ - attribute of the object. */ - PyObject *dict; }; -struct inferior_object; +using thread_map_t + = gdb::unordered_map>; + +struct inferior_object: public gdbpy__dict__wrapper +{ + /* The inferior we represent. */ + struct inferior *inferior; + + /* thread_object instances under this inferior. This owns a + reference to each object it contains. */ + thread_map_t *threads; +}; extern struct cmd_list_element *set_python_list; extern struct cmd_list_element *show_python_list; @@ -989,7 +1003,10 @@ gdbpy_ref<> gdb_py_object_from_longest (LONGEST l); gdbpy_ref<> gdb_py_object_from_ulongest (ULONGEST l); int gdb_py_int_as_long (PyObject *, long *); -PyObject *gdb_py_generic_dict (PyObject *self, void *closure); +PyObject *gdb_py_generic_dict_getter (PyObject *self, void *closure); +int gdb_py_generic_dict_setter (PyObject *self, PyObject *value, void *closure); +PyObject *gdb_py_generic_getattro (PyObject *self, PyObject *attr); +int gdb_py_generic_setattro (PyObject *self, PyObject *attr, PyObject *value); int gdb_pymodule_addobject (PyObject *mod, const char *name, PyObject *object); -- 2.52.0