From patchwork Fri Sep 8 21:05:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Vrany X-Patchwork-Id: 75588 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3E0E13857718 for ; Fri, 8 Sep 2023 21:06:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E0E13857718 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1694207168; bh=832CMDwEcKsFN1OXGf9bwNexICG1sR1m85FC3kVdp5k=; h=To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=qXffUyLuKMfFNj/MQGHibnoOGX/lZM71wx3OqQZTNrsQhg56O8xk1MQ0iauC/jXBG jeE0Rw+Mk+pX4tmY755PPxwvoarZOZC76toMOe3/8kH5G2ebHbmN3/Ealbvqu3R3Mu bXE4pXqv7tmI135B8pJJnumQZs1zbkM+KW6I9zeA= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-114.mimecast.com (us-smtp-delivery-114.mimecast.com [170.10.129.114]) by sourceware.org (Postfix) with ESMTPS id BC3CA3858402 for ; Fri, 8 Sep 2023 21:05:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BC3CA3858402 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11lp2168.outbound.protection.outlook.com [104.47.58.168]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-7-6c3zDvPPNmauzvwKOmHXFg-1; Fri, 08 Sep 2023 17:05:38 -0400 X-MC-Unique: 6c3zDvPPNmauzvwKOmHXFg-1 Received: from SA0PR17MB4314.namprd17.prod.outlook.com (2603:10b6:806:e7::16) by SA0PR17MB4442.namprd17.prod.outlook.com (2603:10b6:806:e0::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.30; Fri, 8 Sep 2023 21:05:36 +0000 Received: from SA0PR17MB4314.namprd17.prod.outlook.com ([fe80::30eb:4c4a:cb5a:dd91]) by SA0PR17MB4314.namprd17.prod.outlook.com ([fe80::30eb:4c4a:cb5a:dd91%4]) with mapi id 15.20.6745.034; Fri, 8 Sep 2023 21:05:36 +0000 To: gdb-patches@sourceware.org CC: Jan Vrany Subject: [PATCH 2/2] gdb/python: implement support for sending custom MI async notifications Date: Fri, 8 Sep 2023 22:05:04 +0100 Message-ID: <20230908210504.89194-2-jan.vrany@labware.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230908210504.89194-1-jan.vrany@labware.com> References: <20230908210504.89194-1-jan.vrany@labware.com> X-ClientProxiedBy: LO4P123CA0550.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:319::20) To SA0PR17MB4314.namprd17.prod.outlook.com (2603:10b6:806:e7::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA0PR17MB4314:EE_|SA0PR17MB4442:EE_ X-MS-Office365-Filtering-Correlation-Id: d95e21d9-f2ad-4e30-9fc6-08dbb0af5934 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0 X-Microsoft-Antispam-Message-Info: 7CopR/QHrFosxBv5Pmy5J8Gtpu86ZABkrdQNVZoOf/INFO9fz1VL+rnb/AP/Wx8BNM1Gh26HsKxqNW5URZHv+ozDEOrERf6CTxERzV7SWJ8vUlaW8hYj8Vqs7SDD/51TrUdxXII5RDG5VmnvaddLK+2DuvDXwdmD2wia/gjigiTpU4+DgPoHhjm0ytZfgOOXxOZY7mvrmXxFugM3hikpwlIUGGDGJkWKMwHTNn4zrw/FV9i5SNgtGGXjy8c7y17yCSUpRsU6KPyHU36k5SulRajC1YjQmqAUvR5+MmB/yHScLkASILFTr6+W0FRt+rP2nOAHa0OxM64jzJyq1SfSOrOEpKX+pOerGwjkX94ogwDl7onwDvOsEWTerU207sDyyj2YUYE+kmoPX8TuLYvATN0bDka+n54Vm67LmootNyKna5zYoS1j7lqU/hjpbeVt/tyWmdUbR0LwH9cVAP22P98XJeqBpeHdYwDKBcPFgzYldFYKMl/idfkElt/CESiLl1bKe39FSK5O+3YK5JiiJVkI6jGjj5QauG+ErkHKuh3oQ845iN3+QIm4qf9sRGLVqSQiRiBl6PTmg5gq4LxxlN9snzS+1gIhzrFwSqtqdWU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SA0PR17MB4314.namprd17.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(396003)(346002)(136003)(376002)(366004)(39850400004)(1800799009)(186009)(451199024)(6486002)(6506007)(41300700001)(316002)(36756003)(2906002)(86362001)(478600001)(66476007)(66556008)(6916009)(38100700002)(66946007)(6666004)(5660300002)(2616005)(1076003)(83380400001)(107886003)(8676002)(8936002)(4326008)(26005)(15650500001)(44832011)(6512007)(2004002); DIR:OUT; SFP:1101 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 8q65SDwb4RYJWDGmeqLG5AzP2JeV3rDxxAEpfzCIvtk629EWB98AgLX1pXh1lT/qOSF/tilfmDu5iY1AjVDZwrjAvm6ODMAvVWwd9jPq4eyx9MqJvYvflPguvvQq/Uual2zn+DG/tfqJgeiqppLva+2Ksaoux/bhZCu/ewWFq3/SZ8qDMHVh1Z4WuledsHCauRTAToHptXdbJsYUCX672A/DMpXCoj3U6JWdevS4mSkMnz6Copt9AzR9tHUiA0B8C1KXIdCEkejXQxlRGnOWMC+6AYYE4FbPqBq/bJEqtdinqDv9tvoAatejlhBBrpERBJaIyRAvgK0VmuyuGdSHECbjorOpxdVNLOStGyWy4Ug+WlECHkJLNHGx3i+mNyV94DfqFEZiSSIP4N2oX2a1dZQ40Fd+Ni3eFT5Rr6f4canlQ03t4uIZuaJqD952mOk1fKCYmEr4CXnQAlgktATO6uVYwrfgXvP+lWGJ39UkcuU/2jtT4I/NWMuhg8AIy5GpHAXGDrRNX4cBWNCvt3g931kcnAMIBfdDhfxQvFANA8CaHLrSOwD2chLf+cI59YBC9OKsczHKyABfBu7s0b6seY4sQYpYl+z9nj3bXlCvT13jPR1ITwfJLL23HEwviva85a6hOb8udbu0X9o1pbK7Ht+6EJ1LBDahhgfub/v7czS4h74GSLCYSE6dTpT7W6LyjoWT7GAdVkFTKXd49RY6caKRR8d3YZ3/DRdGadm9had24y5I4vE6uj11HKib5u9hkj0a6LNldJ9HHZWai5n/FajjhDTqT9V4SRj8D6BYyDq00W8HmChgwxed0z+SKByOmyTgIslzMe/HaLEAoCdZXLgM9Af2tJu4QsIDbQETgcc8j2C3i7MlA78Z5PHqlj8ApWfkunfNliEseHOOU9JfHCWwwusyRP8pFK1GyYT+d4aagI6Exdo8hpMlKcfrqZOuT3ahiQJwcrGd5ukAONctn0CJOGmqaYkYVc9pFSwol558JfTCTs6h67I0B4JVP8HPixKbH5MZyye6JvYIhM3l8kfOWwt2ntvcXa6ERCKojd1svhIjSGysYjp0hGyNy5LUMQ9fiCsBvWenFpQ97eFCTTchbImySZx8YxyfuOJ/NucerDEiVcH/sB++B3wnh9TqiHeke8FjkUO0OHhPpxGKiJEU1PQpqsT1YASGK7G9QuMPpfite00uLSkzNA6hbLjdjsbC75dewMuIzgtAr0K26ScUq7mchrlqSEEiO9Je9TojTUe+nWpu5ykVdBHegBKbiepjvyBeGMd8ChsIA6atvb2fHIcEfjsTfgf68Lbvl74lzQklehao1BNTmqvA1Kfv1tYXFPxWhtKQXmPHzLI7CA9X0yIBG4I685oope5+2ubl2Fnfhh+PUI9CugW5qB99228BKWdZZmxPPnT590Jv3lq/9gGm1bXE65q630OUBJLC9+12thmHUTrWivjK2FueffnmUNXoffKTf1klLUkeeRNBfH2Ea4TA+rlx6uHqFmXFm5fYU9uUv3RUsqL8y6Cw+ZtSPkpLe9umZ9jyw6RdJ1QvVWNp/phhXgCqwMWLZf6zqG92u27A/elBomsGDGPk X-OriginatorOrg: labware.com X-MS-Exchange-CrossTenant-Network-Message-Id: d95e21d9-f2ad-4e30-9fc6-08dbb0af5934 X-MS-Exchange-CrossTenant-AuthSource: SA0PR17MB4314.namprd17.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Sep 2023 21:05:36.7806 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b5db0322-1aa0-4c0a-859c-ad0f96966f4c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: H8HC7Esbo7woUEcWn6IelTCYJI3PMz5L61nVcAwm+GZDAbMHgv4wXSAr9CyxIUsJfTGHIvY1weF1zkUaRWpBXA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR17MB4442 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: labware.com X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP 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: , X-Patchwork-Original-From: Jan Vrany via Gdb-patches From: Jan Vrany Reply-To: Jan Vrany Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This commit adds a new Python function, gdb.notify_mi, that can be used to emit custom async notification to MI channel. This can be used, among other things, to implement notifications about events MI does not support, such as remote connection closed or register change. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 3 ++ gdb/doc/python.texi | 38 ++++++++++++++++++ gdb/python/py-mi.c | 49 +++++++++++++++++++++++ gdb/python/python-internal.h | 3 ++ gdb/python/python.c | 4 ++ gdb/testsuite/gdb.python/py-mi-notify.exp | 47 ++++++++++++++++++++++ 6 files changed, 144 insertions(+) create mode 100644 gdb/testsuite/gdb.python/py-mi-notify.exp diff --git a/gdb/NEWS b/gdb/NEWS index 98ff00d5efc..4a1f383a666 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -286,6 +286,9 @@ info main might be array- or string-like, even if they do not have the corresponding type code. + ** New function gdb.notify_mi(NAME, DATA), that emits custom + GDB/MI async notification. + *** Changes in GDB 13 * MI version 1 is deprecated, and will be removed in GDB 14. diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index e9936991c49..cb2073976ba 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -4704,6 +4704,44 @@ Here is how this works using the commands from the example above: @{'string': 'abc, def, ghi'@} @end smallexample +@node GDB/MI Notifications In Python +@subsubsection @sc{gdb/mi} Notifications In Python + +@cindex MI notifications in python +@cindex notifications in python, GDB/MI +@cindex python notifications, GDB/MI + +It is possible to emit @sc{gdb/mi} notifications from +Python. This is done with the @code{gdb.notify_mi} function. + +@defun gdb.notify_mi (name , data) +Emit a @sc{gdb/mi} asynchronous notification. @var{name} is the name of the +notification, a string. @var{data} are additional values emitted with the notification, passed +as Python dictionary. The dictionary is converted to converted +to a @sc{gdb/mi} @var{result-record} (@pxref{GDB/MI Output Syntax}) the same way +as result of Python MI command (@pxref{GDB/MI Commands In Python}). + +If @var{data} is @code{None} then no additional values are emitted. +@end defun + +Here is how to emit @code{=connection-removed} whenever a connection to remote +GDB server is closed (see @pxref{Connections In Python}): + +@smallexample +def notify_connection_removed (event): + data = @{ 'id' : event.connection.num, + 'type' : event.connection.type @} + gdb.notify_mi("connection-removed", data) + +gdb.events.connection_removed.connect (notify_connection_removed) +@end smallexample + +Then, each time a connection is closed, there will be a notification on MI channel: + +@smallexample +=connection-removed,id="1",type="remote" +@end smallexample + @node Parameters In Python @subsubsection Parameters In Python diff --git a/gdb/python/py-mi.c b/gdb/python/py-mi.c index 66dc6fb8a32..dc2ec5ddd0f 100644 --- a/gdb/python/py-mi.c +++ b/gdb/python/py-mi.c @@ -19,8 +19,14 @@ #include "defs.h" #include "python-internal.h" +#include "utils.h" +#include "ui.h" #include "ui-out.h" +#include "interps.h" +#include "target.h" #include "mi/mi-parse.h" +#include "mi/mi-console.h" +#include "mi/mi-interp.h" /* A ui_out subclass that creates a Python object based on the data that is passed in. */ @@ -296,3 +302,46 @@ gdbpy_execute_mi_command (PyObject *self, PyObject *args, PyObject *kw) return uiout.result (); } + +/* Implementation of the gdb.notify_mi function. */ + +PyObject * +gdbpy_notify_mi (PyObject *self, PyObject *args, PyObject *kwargs) +{ + static const char *keywords[] = { "name", "data", nullptr }; + const char *name; + PyObject *data; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "sO", keywords, + &name, &data)) + return nullptr; // FIXME: is this the correct way to signal error? + + SWITCH_THRU_ALL_UIS () + { + struct mi_interp *mi = as_mi_interp (top_level_interpreter ()); + + if (mi == NULL) + continue; + + gdb_printf (mi->event_channel, "%s", name); + if (data != Py_None) + { + /* At the top-level, the data must be a dictionary. */ + if (!PyDict_Check (data)) + gdbpy_error (_("Data passed to notify_mi must be either None or a dictionary")); + + target_terminal::scoped_restore_terminal_state term_state; + target_terminal::ours_for_output (); + + ui_out *mi_uiout = mi->interp_ui_out (); + ui_out_redirect_pop redir (mi_uiout, mi->event_channel); + scoped_restore restore_uiout + = make_scoped_restore (¤t_uiout, mi_uiout); + + serialize_mi_data (data); + } + gdb_flush (mi->event_channel); + } + + Py_RETURN_NONE; +} diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 3f53b0ab6f0..2a7e8d68179 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -501,6 +501,9 @@ extern PyObject *gdbpy_execute_mi_command (PyObject *self, PyObject *args, extern void serialize_mi_data (PyObject *result); +extern PyObject *gdbpy_notify_mi (PyObject *self, PyObject *args, + PyObject *kw); + /* Convert Python object OBJ to a program_space pointer. OBJ must be a gdb.Progspace reference. Return nullptr if the gdb.Progspace is not valid (see gdb.Progspace.is_valid), otherwise return the program_space diff --git a/gdb/python/python.c b/gdb/python/python.c index 6a978d632e9..faa7e0c217d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -2669,6 +2669,10 @@ Return the name of the currently selected language." }, "print_options () -> dict\n\ Return the current print options." }, + { "notify_mi", (PyCFunction) gdbpy_notify_mi, + METH_VARARGS | METH_KEYWORDS, + "notify_mi (name, data) -> None\n\ +Output async record to MI channels if any." }, {NULL, NULL, 0, NULL} }; diff --git a/gdb/testsuite/gdb.python/py-mi-notify.exp b/gdb/testsuite/gdb.python/py-mi-notify.exp new file mode 100644 index 00000000000..8221794c4f3 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-mi-notify.exp @@ -0,0 +1,47 @@ +# Copyright (C) 2019-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 . + +# Test custom MI notifications implemented in Python. + +load_lib gdb-python.exp +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if {[mi_gdb_start]} { + return +} + +if {[lsearch -exact [mi_get_features] python] < 0} { + unsupported "python support is disabled" + return -1 +} + +standard_testfile + +mi_gdb_test "set python print-stack full" \ + ".*\\^done" \ + "set python print-stack full" + +mi_gdb_test "python gdb.notify_mi('test-notification', None)" \ + ".*=test-notification\r\n\\^done" \ + "python notification, no additional data" + +mi_gdb_test "python gdb.notify_mi('test-notification', \{ 'data1' : 1 , 'data2' : 2 })" \ + ".*=test-notification,data1=\"1\",data2=\"2\"\r\n\\^done" \ + "python notification, with additional data" + +mi_gdb_test "python gdb.notify_mi('test-notification', 1)" \ + ".*\\^error,msg=\".*\"" \ + "python notification, invalid additional data"