From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id uhEVMImBV2RTXAEAWB0awg (envelope-from ) for ; Sun, 07 May 2023 06:46:33 -0400 Received: by simark.ca (Postfix, from userid 112) id B16251E11D; Sun, 7 May 2023 06:46:33 -0400 (EDT) Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=i5X//l6M; dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 1A4851E0D6 for ; Sun, 7 May 2023 06:46:33 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0F3053857703 for ; Sun, 7 May 2023 10:46:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0F3053857703 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1683456392; bh=RDi0JHSD4lCkUzfvBS5Ah1JBcRIrHXsAhCXKyRjLBNo=; h=References:In-Reply-To:Date:Subject:To:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=i5X//l6Mm3A5upVUp2M8MKyvTeHV6zYz+/7QYR6W5ThwXUuS6S2IB8ojuZj7LtSCQ BS6hbbOl6trufdYZdTRY1KiKZ3EvSN38/Q8n6JC3vnPQJX4WEU/Jf8hPGLFebXQoOn 4fOVwdrzt2nbfn0J3DtDY2uydL822ymcKJBSdK90= Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id 2114A3858D35 for ; Sun, 7 May 2023 10:45:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2114A3858D35 Received: by mail-pg1-x52a.google.com with SMTP id 41be03b00d2f7-51f6461af24so2375873a12.2 for ; Sun, 07 May 2023 03:45:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683456354; x=1686048354; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RDi0JHSD4lCkUzfvBS5Ah1JBcRIrHXsAhCXKyRjLBNo=; b=RE72VxuITO6bTZ9+8X5kr2ePoZiHpRgPcnfQljM9hOjrZWWq/9mA+0+Ia6IyUVGU15 dQfcBwMxgKCGPTnASu1KcmFE9b+KTgpsF6uScEvlOEtexsb8KFt1Fb34vvm2XFAl/Cb3 NGKDyByJIH2L2iV6fcbukcrwQVcAtR1CIGHi7xKmO5qhl5G1N3bDrl8Z0x3WMvDcE3rC RHURD/33/qi3/kbq/s1vmRceHR0tu2chZvEj/J0wfqttI/u3H8J5bubp/2ywUg9Ae7vE qN3pvg0+o29tvARIA01xm2M1iwr5fl88SSWeUbIGr5nOlYYqvz1R7/tF1sR4UO0kdKfv zkdA== X-Gm-Message-State: AC+VfDxGWmsxYbaLu6vDkMSwxwrhyGtbIjPLNwJ6FLkQlxJ0T9L6pZ9O H7KcwuE7jP9r/MFP/SshbNoTu5q+dFVw2dq9Rno= X-Google-Smtp-Source: ACHHUZ7hD3a6S14S1dXKgLHrFqYIIrEI5Ewj0M1qlJGWAYmW3FkDuK4fIceU7cCHahizG43A8Jq0yOYpXV/rdkrZ8Qg= X-Received: by 2002:a17:90b:3504:b0:24e:4b02:4f0 with SMTP id ls4-20020a17090b350400b0024e4b0204f0mr7285093pjb.6.1683456353789; Sun, 07 May 2023 03:45:53 -0700 (PDT) MIME-Version: 1.0 References: <20230507094144.894866-1-simon.farre.cx@gmail.com> In-Reply-To: <20230507094144.894866-1-simon.farre.cx@gmail.com> Date: Sun, 7 May 2023 10:45:42 +0000 Message-ID: Subject: Re: [PATCH] gdb/DAP: Add customRequest To: Simon Farre Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Matt Rice via Gdb-patches Reply-To: Matt Rice Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" On Sun, May 7, 2023 at 9:42=E2=80=AFAM Simon Farre via Gdb-patches wrote: > > First, some preface; as a maintainer on one of the few implementations of= a pure GDB-only > debug adapter extension for VSCode (technically, it's designed for GDB+RR= ) > called "Midas", there is one thing that is crucial for making > the DAP interpreter useful, or rather, to make it be able to fully > utilize all the different super powers that GDB has and that is custom re= quests. > Midas implements the DA by making GDB feign the DAP in python, but using > CLI and MI, by parsing MI and turning it into JSON. Not great, > but it was the only solution that existed at the time. My somewhat initial thought was that there was some overlap here with the 'MI commands in Python' feature, https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-Commands-= In-Python.html#GDB_002fMI-Commands-In-Python But that still leaves one needing to convert MI to JSON. I'd want to note that Tromey's recent patch should allow MI commands to be trivially converted through json, https://sourceware.org/pipermail/gdb-patches/2023-April/198606.html `json.dumps(gdb.execute_mi("break-list"))`, or something of similar effect. It would seem like combining your customRequest patch with that, would lead to a fairly trivial command enabling access to all mi commands as json. This at least seems like it would be much less involved than manual translation of MI to JSON. > The Python interpreter, when in CLI-mode, currently provides something si= milar to custom requests, > with custom commands from the command line via the base class `gdb.Comman= d`. > But with the current implementation of the DAP-interpreter, no class hier= archies are needed. > > This patch introduces the customRequest, which allows for DA's (debug ada= pters) > that want to use the full extent of GDB's functionality by working a bit > like the extension of `gdb.Command`, But instead of deriving from a base = class > and instantiating a command object the DA would source python code > that will be added to the custom requests handler of the DAP-interpreter,= for example like: > `-iex "source foo.py"` or `-iex "source debug-adapter-std-lib.py"` or wha= tever she/he wants > to call it. > > Here's an example of what `foo.py` might look like: > > > import gdb > > import gdb.dap > > from gdb.dap import server # import logic, possibly should look differe= nt > > > > @server.custom_request("foo") > > def fooRequestHandler(argumentBaz): > > # full Python interpreter access, full access to all of GDB, like we'r= e @ the CLI > > # say goodbye to MI! Yay! :P > > return { "bar": gdb.execute("print foo", to_string=3DTrue), "someParam= ": argumentBaz } > > Now, the DA would be able to send a request that looks like > > header omitted > > {"seq":6,"type":"request","command":"customRequest","arguments":{"comma= nd":"foo","args":["baz"]}} > > And in this particular case the response to that request would be: > > > { > > "request_seq":6, > > "type":"response", > > "command":"customRequest", > > "body": { > > "bar": "resultFromPrintCommand", > > "someParam": "baz" > > }, > > "success":true,"seq":19 > > } > > If the command is unrecognized it will respond with a "success" : false, = and an error message. > > As a debug adapter maintainer for VSCode, a customRequest like this would= be not only useful, > but crucial. VSCode itself in it's debug adapter interface specification, > i.e. not the protocol spec, but the Typescript interface, defines customR= equest-functionality, > which can be found here; > https://github.com/microsoft/vscode-debugadapter-node/blob/main/adapter/s= rc/debugSession.ts#L638 > > Unfortunately, there's nothing about such a request in the DAP-spec, but = I'd argue that's really irrelevant; > the largest code editor for debug adapter protocol implementers, has a no= tion of it, > though it's up to DA-implementers to make sure they understand their own = requests. > > There are other, (in my opinion) bonuses of the customRequest functionali= ty. The major one > being it can be a driving factor for further development of Python in GDB= , by providing > an access point to GDB that returns "real python objects" (instead of the= above example > of returning a string from the CLI-command) from commands and make it mor= e > possible for future debug adapters to migrate away from MI (if they so ch= oose), > which is difficult to work with, hard to read and even harder to test. JS= ON is superior > since there's so much open source code that supports JSON and in > a lot of languages it's even got built in support. "Driving GDB" via the = DAP-interpreter > from any modern language is trivial because of this. > > Beyond this patch, documentation would be needed also, to document how > to create customRequests, like the one above. I'm hoping Eli can provide = me with > some direction here. > --- > gdb/python/lib/gdb/dap/server.py | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/gdb/python/lib/gdb/dap/server.py b/gdb/python/lib/gdb/dap/se= rver.py > index ff88282049f..7cd60873319 100644 > --- a/gdb/python/lib/gdb/dap/server.py > +++ b/gdb/python/lib/gdb/dap/server.py > @@ -33,6 +33,8 @@ _capabilities =3D {} > # Map command names to callables. > _commands =3D {} > > +_custom_requests =3D {} > + > # The global server. > _server =3D None > > @@ -171,6 +173,27 @@ def request(name): > return wrap > > > +def custom_request(name): > + """A decorator that indicates that the wrapper function should be > + handled by a custom request""" > + > + def wrap(func): > + global _custom_requests > + _custom_requests[name] =3D func > + return in_dap_thread(func) > + > + return wrap > + > +@request("customRequest") > +def custom_request_handler(**args): > + global _custom_requests > + cmd =3D args["command"] > + if _custom_requests.get(cmd) is not None: > + return _custom_requests[cmd](args["args"]) > + else: > + raise Exception(f"Unrecognized customRequest {cmd}") > + > + > def capability(name): > """A decorator that indicates that the wrapper function implements > the DAP capability NAME.""" > -- > 2.40.1 >