Message ID | 20170123224004.8893-2-simon.marchi@ericsson.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 35573 invoked by alias); 23 Jan 2017 22:43:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <gdb-patches.sourceware.org> List-Unsubscribe: <mailto:gdb-patches-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:gdb-patches-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 35093 invoked by uid 89); 23 Jan 2017 22:43:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-HELO: sesbmg23.ericsson.net Received: from sesbmg23.ericsson.net (HELO sesbmg23.ericsson.net) (193.180.251.37) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Jan 2017 22:43:27 +0000 Received: from ESESSHC018.ericsson.se (Unknown_Domain [153.88.253.124]) by (Symantec Mail Security) with SMTP id 4A.3D.14025.D0786885; Mon, 23 Jan 2017 23:43:25 +0100 (CET) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.72) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 23 Jan 2017 23:40:56 +0100 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from elxcz23q12-y4.ca.am.ericsson.se (192.75.88.130) by DBXPR07MB399.eurprd07.prod.outlook.com (10.141.14.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.874.6; Mon, 23 Jan 2017 22:40:27 +0000 From: Simon Marchi <simon.marchi@ericsson.com> To: <gdb-patches@sourceware.org> CC: Simon Marchi <simon.marchi@polymtl.ca> Subject: [PATCH 1/5] Introduce specialized versions of gdbpy_ref Date: Mon, 23 Jan 2017 17:40:00 -0500 Message-ID: <20170123224004.8893-2-simon.marchi@ericsson.com> In-Reply-To: <20170123224004.8893-1-simon.marchi@ericsson.com> References: <20170123224004.8893-1-simon.marchi@ericsson.com> MIME-Version: 1.0 Content-Type: text/plain X-ClientProxiedBy: CY4PR13CA0008.namprd13.prod.outlook.com (10.168.161.146) To DBXPR07MB399.eurprd07.prod.outlook.com (10.141.14.149) X-MS-Office365-Filtering-Correlation-Id: acf79939-5779-4228-4b92-08d443e0d48a X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:DBXPR07MB399; X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB399; 3:dY3FZTdp0UtAFZMjG1FTVIC1gWUe7h60BViwjFBoRwrJ+kqIRcafjQQ1vy3CBJhovTswlwiAIxH41vz9ow/foL2Rc5SKt8So7RIwIH2XoSz+ebFcZC29fWX6VXf3MYLCNN0WjlzPyS2URtQYRdUHxQROQZQQqjx5axw9TGkrVoHhbBrLGDJZwbHxLbM75zQMkIcPoHvyu6VsS3T4xpGx/sQS1WB8TML2/yGff0wZIHvF35hzVeW82I7oHZCxUz4OmuDb7kaysbZlRJh03S7bqg==; 25:zf6zG0+fSNnpmx1KYkLTRCvqE72duIMpKN1vnpTxfKkxDkuFTJzI3UYm5vxKQVvD5NoxrVd+InDlln5VcZ6NgWOOSoq5V3Zl4nPb175ZtOyBVmaY4p1EdX5GVug2HsneDo16qPbCAuwAvpQwAthSGNBl9iXlkBAEXCKeDhsTN3BYZZ2+M6x3KC3LiBVMzewjKZfEbYcslKIgxt6OFHM+FPPK8MWCnPRnPsvCM3Kubib7Sg5agBxCCEdkdH9K6wKnkMuxGLrbaxMnlTIXGgec3k5U30/UZ1ibE1RY9guKHZKbwHL4Kw26MymnLafBRZHh00km0JD56XqCSBWjWqdkN5fBb4Z3zlpBnKDUdw2l8u3vrAxDMvF5U4yC1jCvnPl1tB0zuKHG9q4SJXQi8QxEuzIEQBI5WnhwjkawSDwbW3k4eU+8T3zf6x/1nS1qN/itzk1YPTD2A3jjsJdUwMTpsw== X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB399; 31:Uu7e4sm3w9NBjWHID5GyzohhpUI9q6bPaxLyKkw2eUlkcuVXnpve0eR3h99Y5bXOMaOpF+GO54/DbLLBXHapRkb4fxWGGQteWcl36+4gcmmkInk6pJveUFB76HcC+esvd3EIk0ABG3BVibPmNjVTAWZarLMV/x475A4VD2e0M/yiZhNOJZGVev1kSnV4hBKcXB2qbJN/sPkTTMekQMmv74ws2LjB2ezV3hwESWTEur2swPtejGp2HLLmFkvIuPjoGR5KggD6goYq3L6yER5PCZK+z9fEDvRCqNFX51a916hgtTUg6e0w+y7SqR96MOdl; 20:WTjxobp2YVmgMR+nTxbeDzTxGcLFp/vwI0y5R/6ZDkQz/+Mmct4CzXAwKarwkKWjVU6I7IJGMyXzXpkVkMfQzIDad/egC1+5QMEWK0uUcQt9Dpx3phgls0iTvjD6GEe6cOPc1I4nxHxBItqYkTTODNuEPu3hatg6EE3Fh5xeLmGbdbiXzWb+z9Nw4wTuKJZIm9F807yVfGjQ9u4tAdvwiFHVTaX1g88VwdN+Isc1trBvbhqKdtr6oAjxxIF6O7AoHTV4z8s4BgF898iX5QSjBkpQ2WWlaVZaaneZMVnKioHJCQLjC5xOHD2JBEG6YfgxTwV8+ncoyOAI1uh8IBZEBL8vXopl9Snu1KtzbfERhC8SgAOttr9fgj7oJoP/JvNPZ26q/fI4GECYi+OvtH5oY/q2vogUYwLbIDRVl41i7GGh0SAxMU61QjS54/Yq6u4Ru4SASSecdkv8gxKmh30la63x3V87kPXK0CEJXoT2aD7hB09LCtYeHZT1kDrZfL90 X-Microsoft-Antispam-PRVS: <DBXPR07MB3994DBBD3FA11458EB986EAED720@DBXPR07MB399.eurprd07.prod.outlook.com> X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6041248)(20161123560025)(20161123558021)(20161123555025)(20161123562025)(20161123564025)(6072148); SRVR:DBXPR07MB399; BCL:0; PCL:0; RULEID:; SRVR:DBXPR07MB399; X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB399; 4:ZzZlkCoyK86SUXKXH5IZY38wwmtdv1jAyMoHh3GVBK81LBBnxczXHJQsJbHHjU1Mse51v6kKkR3Vg6nCm5Lv5TaugO6KE/vCQwswhAOVSRHxjGt5dt5tcjr/C2mMSQTTaFfKK+iBt+OhTBwTURcGOOgVbJ4BXNIbQMgFd/cqnz6g9d67gKpFJjd6waZ4gHYFvj2QzXhIk0smdU2tUXdyUCiyqkRqQlfUslg3VpeyLT0iWOrCDFm8aLUz5yj5T35OQCRnxochOwgt/i5AsMRBOpxronnitOO7udTwr7KJSL6PC4iK7WrlLKFsZuYxg/z6jYH8U6Dqo3h4fdOr//Wft0RC6GZ+mTSAIcLgZHX7ScigO2/OkDyQsmMuEOG/qrJxYocWZwwed1+4mtAuieq1fQSbTQ9h+JM8Q0eB//UNlHJYT0wqumtM14AZsj3T2iOeBLuULMF3qMoIi12FOopumzuOflU35e/zr9Dl/Ovb9K11TmTq9BPqtSoKK7fy9diXzdCGo6bzcgGOCStHdGe2L+sNWVZrmQdwZUXgKBbzmmYSRI0rGIRqMpy8/llOtEsrYJBXSdKN6GCKkugcebstcBHZdIALPlIhSDt8OP2opHE= X-Forefront-PRVS: 0196A226D1 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(199003)(54534003)(189002)(6916009)(8676002)(110136003)(48376002)(4326007)(5660300001)(2906002)(105586002)(81156014)(81166006)(106356001)(2351001)(189998001)(7736002)(2950100002)(6666003)(50466002)(50226002)(68736007)(1076002)(5003940100001)(92566002)(305945005)(3846002)(6116002)(97736004)(6512007)(86362001)(25786008)(6486002)(6506006)(38730400001)(50986999)(33646002)(76176999)(42186005)(66066001)(47776003)(36756003)(53936002)(101416001); DIR:OUT; SFP:1101; SCL:1; SRVR:DBXPR07MB399; H:elxcz23q12-y4.ca.am.ericsson.se; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DBXPR07MB399; 23:a7dsvDtMg2yEhIvugZgm0zsbIoin0Tk9QYx2UaNE4A?= =?us-ascii?Q?FSMLEcunip7+BpSClj6GIvXlEzA4ohl4pNkV9IZiLxd/UztJXNNnGQMDpHBS?= =?us-ascii?Q?Ke+tTpgb25T6bC6vYFXa/cyCbofBLWoOL5FxbrpL+hZ5IZYXm3YyJcH1CFiU?= =?us-ascii?Q?ZU3UmKh/Kddw+5qiHeF/4hdOfDAfdsFm6n2eItj+IvzpCOntnUcVyobYNkjS?= =?us-ascii?Q?72CeFrrT4ebRiqYFr1bc4jzFcMCei+JFnK8IGtMMwAwnHqSTplMb75O3PCtQ?= =?us-ascii?Q?oTIYyarnHTGe3QxJjH77dJLIQIsLLYtZx2CAb+z8nfuNcoyeoaSHN/cZdY7C?= =?us-ascii?Q?/HHDBKReCHGo/JosvEZlCxCwL+ujtu5yyZ0Bt/5AuOUChI49Dfb/1v1gBZbC?= =?us-ascii?Q?lNiZhH0XCvYaxOEidwq3+9ic8CXRhGr49pRXAazetNw4zl063tedtwnZRdv/?= =?us-ascii?Q?HkM7F+BoC77EdyTmlATrZeyTPQEOzOnr6yrj0M5AkoirMRgMaZ6bufGdWML8?= =?us-ascii?Q?6xWATjoGQixoPqXtQbye4bRnCvG4E+L2ZBu223MLVo+ZxB0CiTm7g1tk3Clv?= =?us-ascii?Q?IMXUZe64mebPU3WNbkx0oBXTWkcNu7qjgfqih/eYQPsbfSzJojSBD51zT3D4?= =?us-ascii?Q?75CbrLfqTEoOc3RFcHx0KcGhK9HtWUl6x63fz+LgXpeP9NaoPtuzNyA/cfCv?= =?us-ascii?Q?p1i0o4U1hWwT/OLCw/53B0MgbBMAA3ldf1L6RtoEenPrr4dy9fUrCoZOibJS?= =?us-ascii?Q?NmbEk1R5FDCIke6bAvZO5e4fhaQfaItceP1rM2S5QJ/WKlHTttW40iC4jLGK?= =?us-ascii?Q?Eg1daZlMPXO5IJVHfJ/lHL4YwApFeoFTYv3ALODb1uu/CVDplRdrtnPB+0Xy?= =?us-ascii?Q?Dkfn6OGwvKlkKFMQFjbW7FFgXSzc3tV0fxWr3csyxnc36jNxRvXsbeGxPUmW?= =?us-ascii?Q?/yljrWChdgT09L0YHy/396VeSWtkkNN4DiJuoz585zJGpUsRX1u0rKHU0f+w?= =?us-ascii?Q?weaT/eoRCV+3ksPC+ZN4D0gDvjBefT6oRFnOCU1pZGf+Oqt6F9s+nszOAkWW?= =?us-ascii?Q?gMCi2Ef4Gc7jBpV3ACXYYeylFsKPChomYA3TBTfLYfLISnhgr7K8Tf+F8u2i?= =?us-ascii?Q?06Dt6HY1l0aVo2nVYofzoVbNqHkvIXEYXeoC11loztbTK679tbdQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB399; 6:mnZAOu73r0+MbKqplawEuZ6qV3GPqTF/pIKszGlrr7MqyMp7D4CqzGpeuD9jkuwMcVYwd2go9SgJi8dukFZu/ubMRKHJ7ZRRW/v/M8eXSWHQA0ODOTEsw2J7bKTEtBfiIsTBEwf6XXGty7brwAecsHWSYmHVSsEvJ445DyPNhAzkq/m4/dY4meUCMP6eHItX02iO2z5AUijuj2PA2d4uoRIkKST/K3We26sLCoiuMlJgY77FS7o8BkncHyqhgsVQZsJ2s9hAzJ8UHJTxvZ8F21L8ndSlygj2w4u7nKzpZ/z/5zGhsVNgVZx1MROxXdd5WiRqYoh9o7j2zrEDSESN0Ud+AI7x5JWRKDVM4VyQXeYlam8INxK4zE/kCgsDsy41Oa/g40cOikGGiorAJer72mDrdGAUvvDtOe2msD/DrLA=; 5:lw/8wU+8BT9Z3iGP72rjArzy2kshHnI2Lo8V5zhGhW43CXNuN+f8ZLrT8BymKs7Wf07g39t0NQH03SSDKRnH2eH/rDf8I9P2BHPGl0hgGIsR/+PgWl8mHIvhOYHY9Kh8uibi+mzHRNXNVCg+qUP4ug==; 24:Y0Jja5qwqaBFnvFHcdH7RNtg4FnLK5Hx7lN/t6a2P0ny/1zKuqI1TZdPreBAdjCvJ6TMyz4w+TRrPzcSvAuUuU0JmivTSJNB6zONsejGNyQ= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DBXPR07MB399; 7:UZpxxD77IwnP6oNPYl28Rymfupuc3AlPS5Ugnidhl4A+P44pSANREIKbNN+tGSjnpcdQax+tYoS/wOlcH+Y8wW8nugsCC33zFy5P3kcYciTRTtnVT6xnNQuiRmhDS0zO/sAOq7cq/8vOkROHLq5oCB957QF1A6eXZm9hGozb0oXY2NH4Ewo+vuOVTGWlLrofaSViXX61hjLZZqV4T7m0GvaXmr26ZXu8v78Bep15Mn9rw+U27KXNTdllqbtcOuWzuQGjDi3XGL6ZMFYL67ofCmN/v56vbzJdQR5PXFXNc3H0G2/fdThAuq9WB0Szu5Ks7wrTVhMQCQd0tlprS8vQCwq1OBAPYf7jDMhcpuKy4kgUu0nh90BNg4gEkp0KG96fwmjXH93Qu9apaGqqaq1V0oK8kGgFqfaGPMMEJ8TwvrJHr2Nr4mRdCOx7ulDfongC3FWdlL/3Jk1wF6VhbJDY5g== X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2017 22:40:27.6932 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBXPR07MB399 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes |
Commit Message
Simon Marchi
Jan. 23, 2017, 10:40 p.m. UTC
From: Simon Marchi <simon.marchi@polymtl.ca>
I was playing with the Python API implementation a bit, and I thought we
could improve/simplify the gdbpy reference counting a bit for our own
Python types. We currently have a single type, gdbpy_ref, which holds a
reference to a PyObject*. This means that if we want to wrap an
inferior_object* (which is a sub-class-ish of PyObject), we need to cast
it when constructing the reference:
gdbpy_ref ref ((PyObject *) an_inferior_object);
as well as when getting the reference
inferior_object *obj = (inferior_object *) ref.get ();
This patch generalizes the gdbpy_ref concept so that it can hold a reference to
other types than PyObject. This should mean less casting when dealing with
references to our specialized Python objects.
The main new part is the template class gdbpy_ref_base, which extends
gdb::ref_ptr with the gdbpy_ref_policy policy, much like gdbpy_ref did
previoulsy. However, the referenced object type is now the generic type
T instead of PyObject*. The gdbpy_ref_policy is generalized as well to
match. Note that we don't need to cast the pointers in incref/decref
since Py_INCREF/Py_DECREF already do that.
Specializations of gdbpy_ref_base can then be added for our various
Python types. This patch only adds gdbpy_ref to match the one that was
already there. So no behavioral changes are expected.
We must make sure to only use gdbpy_ref_base on objects that actually
are Python objects. For example, gdbpy_ref_base<thread_info> would make
not sense. Since the "inheritance" from the PyObject type is done in a
C way (using PyObject_HEAD), I don't know how we can check at
compile-time that we are not using it with a wrong type. If you have an
idea on how to do that, let me know. We would need to check that there
exists a field named ob_base. Bonus points for ensuring that its type
is PyObject. More bonus points for ensuring that it's the first field
in the structure.
For convenience, I added a get_py_obj method to gdbpy_ref_base, which
returns the pointer casted to PyObject*, something we need to do
relatively often).
gdb/ChangeLog:
* python/py-ref.h (gdbpy_ref_policy): Add template.
(gdbpy_ref_base): New class.
(gdbpy_ref): Define in terms of gdbpy_ref_base instead of
gdb::ref_ptr.
---
gdb/python/py-ref.h | 37 +++++++++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
Comments
>>>>> "Simon" == Simon Marchi <simon.marchi@ericsson.com> writes:
Simon> We currently have a single type, gdbpy_ref, which holds a
Simon> reference to a PyObject*. This means that if we want to wrap an
Simon> inferior_object* (which is a sub-class-ish of PyObject), we need to cast
Simon> it when constructing the reference:
This was the subject of this patch:
https://sourceware.org/ml/gdb-patches/2017-01/msg00277.html
I applied it all over the Python layer.
Tom
On 2017-01-24 10:53, Tom Tromey wrote: >>>>>> "Simon" == Simon Marchi <simon.marchi@ericsson.com> writes: > > Simon> We currently have a single type, gdbpy_ref, which holds a > Simon> reference to a PyObject*. This means that if we want to wrap an > Simon> inferior_object* (which is a sub-class-ish of PyObject), we need > to cast > Simon> it when constructing the reference: > > This was the subject of this patch: > > https://sourceware.org/ml/gdb-patches/2017-01/msg00277.html > > I applied it all over the Python layer. > > Tom Ah damn, shame on me for missing it. At least doing it by myself made me learn a lot :). I'll take a look at that series. There might still be some bits relevant in the current series, like the bug fix in patch 5 (unless you also addressed it). I'll re-evaluate it once your series is in. Simon
On 01/23/2017 10:40 PM, Simon Marchi wrote: > > We must make sure to only use gdbpy_ref_base on objects that actually > are Python objects. For example, gdbpy_ref_base<thread_info> would make > not sense. Since the "inheritance" from the PyObject type is done in a > C way (using PyObject_HEAD), I don't know how we can check at > compile-time that we are not using it with a wrong type. If you have an > idea on how to do that, let me know. We would need to check that there > exists a field named ob_base. Bonus points for ensuring that its type > is PyObject. More bonus points for ensuring that it's the first field > in the structure. You can do all this with SFINAE. For the "is first field check, you could use something like "(PyObject*) this == &this->ob_base" as expression, I think. https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error There are many examples around the web, if you search for SFINAE and "C++ check if member exists", etc. E.g,: http://stackoverflow.com/questions/1005476/how-to-detect-whether-there-is-a-specific-member-variable-in-class Though I still wonder whether just inheriting our objects from PyObject wouldn't make things simpler. > For convenience, I added a get_py_obj method to gdbpy_ref_base, which > returns the pointer casted to PyObject*, something we need to do > relatively often). Thanks, Pedro Alves
On 2017-02-09 06:58, Pedro Alves wrote: > On 01/23/2017 10:40 PM, Simon Marchi wrote: >> >> We must make sure to only use gdbpy_ref_base on objects that actually >> are Python objects. For example, gdbpy_ref_base<thread_info> would >> make >> not sense. Since the "inheritance" from the PyObject type is done in >> a >> C way (using PyObject_HEAD), I don't know how we can check at >> compile-time that we are not using it with a wrong type. If you have >> an >> idea on how to do that, let me know. We would need to check that >> there >> exists a field named ob_base. Bonus points for ensuring that its type >> is PyObject. More bonus points for ensuring that it's the first field >> in the structure. > > You can do all this with SFINAE. For the "is first field check, you > could > use something like "(PyObject*) this == &this->ob_base" as expression, > I think. > > https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error > > There are many examples around the web, if you search for SFINAE and > "C++ check if member exists", etc. E.g,: > > http://stackoverflow.com/questions/1005476/how-to-detect-whether-there-is-a-specific-member-variable-in-class Thanks! This kind of thing doesn't come to me naturally yet. > Though I still wonder whether just inheriting our objects from > PyObject wouldn't make things simpler. I'll have to try that. Thanks, Simon
diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h index b2479bf656..8b3b7732cc 100644 --- a/gdb/python/py-ref.h +++ b/gdb/python/py-ref.h @@ -23,20 +23,49 @@ #include "common/gdb_ref_ptr.h" /* A policy class for gdb::ref_ptr for Python reference counting. */ + +template <typename T> struct gdbpy_ref_policy { - static void incref (PyObject *ptr) + static void incref (T *ptr) { Py_INCREF (ptr); } - static void decref (PyObject *ptr) + static void decref (T *ptr) { Py_DECREF (ptr); } }; -/* A gdb::ref_ptr that has been specialized for Python objects. */ -typedef gdb::ref_ptr<PyObject, gdbpy_ref_policy> gdbpy_ref; +/* Reference counting specialized for Python objects. + + This class must only be used with Python types, i.e. types declared with + PyObject_HEAD as their first "field". */ + +template <typename T> +class gdbpy_ref_base : public gdb::ref_ptr<T, gdbpy_ref_policy<T>> +{ +public: + + /* Create a new NULL instance. */ + + gdbpy_ref_base () + : gdb::ref_ptr<T, gdbpy_ref_policy<T>> () + {} + + explicit gdbpy_ref_base (T *ptr) + : gdb::ref_ptr<T, gdbpy_ref_policy<T>> (ptr) + {} + + /* Return a pointer to the owned Python object as a generic PyObject. */ + + PyObject *get_py_obj () + { return (PyObject *) this->get(); } +}; + +/* Specializations of gdbpy_ref_base for concrete Python object types. */ + +typedef gdbpy_ref_base<PyObject> gdbpy_ref; #endif /* GDB_PYTHON_REF_H */