aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/lib
AgeCommit message (Collapse)AuthorFilesLines
2023-12-11Implement DAP cancellationTom Tromey1-3/+88
This implements DAP cancellation. A new object is introduced that handles the details of cancellation. While cancellation is inherently racy, this code attempts to make it so that gdb doesn't inadvertently cancel the wrong request. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30472 Approved-By: Eli Zaretskii <eliz@gnu.org> Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
2023-12-11Catch KeyboardInterrupt in send_gdb_with_responseTom Tromey1-2/+2
Cancellation will generally be seen by the DAP code as a KeyboardInterrupt. However, this derives from BaseException and not Exception, so a small change is needed to send_gdb_with_response, to forward the exception to the DAP server thread. Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
2023-12-11Move DAP JSON reader to its own threadTom Tromey1-2/+13
This changes the DAP server to move the JSON reader to a new thread. This is key to implementing request cancellation, as now requests can be read while an earlier one is being serviced. Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
2023-12-11Clean up handling of DAP not-stopped responseTom Tromey1-1/+10
This patch introduces a new NotStoppedException type and changes the DAP implementation of "not stopped" to use it. I was already touching some code in this area and I thought this looked a little cleaner. This also has the advantage that we can now choose not to log the exception -- previously I was sometimes a bit alarmed when seeing this in the logs, even though it is harmless. Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
2023-12-11Simplify DAP stop-reason codeTom Tromey4-37/+76
Now that gdb adds stop-reason details to stop events, we can simplify the DAP code to emit correct stop reasons in its own events. For the most part a simple renaming of gdb reasons is sufficient; however, "pause" must still be handled specially.
2023-12-05Remove some DAP helper functionsTom Tromey6-111/+66
Now that DAP requests are normally run on the gdb thread, some DAP helper functions are no longer needed. Removing these simplifies the code.
2023-11-28Emit DAP "process" eventTom Tromey2-1/+39
DAP specifies a "process" event that is sent when a process is started or attached to. gdb was not emitting this (several DAP clients appear to ignore it entirely), but it looked easy and harmless to implement. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30473
2023-11-27Fix bug in DAP handling of 'pause' requestsTom Tromey1-2/+24
While working on cancellation, I noticed that a DAP 'pause' request would set the "do not emit the continue" flag. This meant that a subsequent request that should provoke a 'continue' event would instead suppress the event. I then tried writing a more obvious test case for this, involving an inferior call -- and discovered that gdb.events.cont does not fire for an inferior call. This patch installs a new event listener for gdb.events.inferior_call and arranges for this to emit continue and stop events when appropriate. It also fixes the original bug, by adding a check to exec_and_expect_stop.
2023-11-23[gdb/python] Reformat missing_debug.py using blackTom de Vries1-0/+4
Reformat gdb/python/lib/gdb/missing_debug.py with black after commit e8c3dafa5f5 ("[gdb/python] Don't import curses.ascii module unless necessary").
2023-11-22[gdb/python] Don't import curses.ascii module unless necessaryTom de Vries1-2/+12
I ran into a failure in test-case gdb.python/py-missing-debug.exp with python 3.6, which was fixed by commit 7db795bc67a ("gdb/python: remove use of str.isascii()"). However, I subsequently ran into a failure with python 3.11: ... (gdb) PASS: $exp: initial checks: debug info no longer found source py-missing-debug.py^M Traceback (most recent call last):^M File "py-missing-debug.py", line 17, in <module>^M from gdb.missing_debug import MissingDebugHandler^M File "missing_debug.py", line 21, in <module>^M from curses.ascii import isascii, isalnum^M File "/usr/lib64/python3.11/_import_failed/curses.py", line 16, in <module>^M raise ImportError(f"""Module '{failed_name}' is not installed.^M ImportError: Module 'curses' is not installed.^M Use:^M sudo zypper install python311-curses^M to install it.^M (gdb) FAIL: $exp: source python script ... Apparently I have the curses module installed for 3.6, but not 3.11. I could just install it, but the test-case worked fine with 3.11 before commit 7db795bc67a. Fix this by only using the curses module when necessary, for python <= 3.7. Tested on x86_64-linux, with both python 3.6 and 3.11.
2023-11-21Refactor DAP queue handlingTom Tromey2-10/+11
A couple of spots in the DAP code use the same workaround for the absence of queue.SimpleQueue before Python 3.6. This patch consolidates these into a single spot.
2023-11-17Ignore static members in NoOpStructPrinterTom Tromey1-1/+1
Hannes' patch to show local variables in the TUI pointed out that NoOpStructPrinter should ignore static members. This patch implements this.
2023-11-17Implement the notStopped DAP responseTom Tromey3-4/+52
DAP specifies that a request can fail with the "notStopped" message if the inferior is running but the request requires that it first be stopped. This patch implements this for gdb. Most requests are assumed to require a stopped inferior, and the exceptions are noted by a new 'request' parameter. You may notice that the implementation is a bit racy. I think this is inherent -- unless the client waits for a stop event before sending a request, the request may be processed at any time relative to a stop. https://sourceware.org/bugzilla/show_bug.cgi?id=31037 Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2023-11-17Remove ExecutionInvokerTom Tromey4-31/+16
ExecutionInvoker is no longer really needed, due to the previous DAP refactoring. This patch removes it in favor of an ordinary function. One spot (the 'continue' request) could still have used it, but is more succinctly expressed as a lambda. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2023-11-17Automatically run (most) DAP requests in gdb threadTom Tromey14-130/+116
Nearly every DAP request implementation forwards its work to the gdb thread, using send_gdb_with_response. This patch refactors the 'request' decorator to make this automatic, and to provide some parameters so that the unusual requests can express their needs as well. In a few spots this simplifies the code by removing an unnecessary helper function. This could be done in more places as well if we wanted. The main motivation for this patch is that I thought it would be helpful for cancellation. I am still working on that, but meanwhile the parameterization of 'request' makes it easy to handle the 'notStopped' response as well. Reviewed-by: Kévin Le Gouguec <legouguec@adacore.com>
2023-11-17Handle StackFrameFormat in DAPTom Tromey3-47/+215
DAP specifies a StackFrameFormat object that can be used to change how the "name" part of a stack frame is constructed. While this output can already be done in a nicer way (and also letting the client choose the formatting), nevertheless it is in the spec, so I figured I'd implement it. While implementing this, I discovered that the current code does not correctly preserve frame IDs across requests. I rewrote frame iteration to preserve this, and it turned out to be simpler to combine these patches. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30475
2023-11-16gdb/python: remove use of str.isascii()Andrew Burgess1-1/+2
This commit: commit 8f6c452b5a4e50fbb55ff1d13328b392ad1fd416 Date: Sun Oct 15 22:48:42 2023 +0100 gdb: implement missing debug handler hook for Python introduced a use of str.isascii(), which was only added in Python 3.7. This commit switches to use curses.ascii.isascii(), as this was available in 3.6. The same is true for str.isalnum(), which is replaced with curses.ascii.isalnum(). There should be no user visible changes after this commit.
2023-11-14Handle the static link in FrameDecoratorTom Tromey1-13/+51
A co-worker requested that the DAP scope for a nested function's frame also show the variables from outer frames. DAP doesn't directly support this notion, so this patch arranges to put these variables into the inner frames "Locals" scope. I chose to do this only for DAP. For CLI and MI, gdb currently does not do this, so this preserves the behavior. Note that an earlier patch (see commit 4a1311ba) removed some code that seemed to do something similar. However, that code did not actually work.
2023-11-14Fix a bug in DAP scopes codeTom Tromey1-2/+6
While working on static links, I noticed that the DAP scopes code does not handle the scenario where a frame decorator returns None. This situation should be handled identically to a frame decorator returning an empty iterator.
2023-11-14gdb: implement missing debug handler hook for PythonAndrew Burgess3-0/+436
This commit builds on the previous commit, and implements the extension_language_ops::handle_missing_debuginfo function for Python. This hook will give user supplied Python code a chance to help find missing debug information. The implementation of the new hook is pretty minimal within GDB's C++ code; most of the work is out-sourced to a Python implementation which is modelled heavily on how GDB's Python frame unwinders are implemented. The following new commands are added as commands implemented in Python, this is similar to how the Python unwinder commands are implemented: info missing-debug-handlers enable missing-debug-handler LOCUS HANDLER disable missing-debug-handler LOCUS HANDLER To make use of this extension hook a user will create missing debug information handler objects, and registers these handlers with GDB. When GDB encounters an objfile that is missing debug information, each handler is called in turn until one is able to help. Here is a minimal handler that does nothing useful: import gdb import gdb.missing_debug class MyFirstHandler(gdb.missing_debug.MissingDebugHandler): def __init__(self): super().__init__("my_first_handler") def __call__(self, objfile): # This handler does nothing useful. return None gdb.missing_debug.register_handler(None, MyFirstHandler()) Returning None from the __call__ method tells GDB that this handler was unable to find the missing debug information, and GDB should ask any other registered handlers. By extending the __call__ method it is possible for the Python extension to locate the debug information for objfile and return a value that tells GDB how to use the information that has been located. Possible return values from a handler: - None: This means the handler couldn't help. GDB will call other registered handlers to see if they can help instead. - False: The handler has done all it can, but the debug information for the objfile still couldn't be found. GDB will not call any other handlers, and will continue without the debug information for objfile. - True: The handler has installed the debug information into a location where GDB would normally expect to find it. GDB should look again for the debug information. - A string: The handler can return a filename, which is the file containing the missing debug information. GDB will load this file. When a handler returns True, GDB will look again for the debug information, but only using the standard built-in build-id and .gnu_debuglink based lookup strategies. It is not possible for an extension to trigger another debuginfod lookup; the assumption is that the debuginfod server is remote, and out of the control of extensions running within GDB. Handlers can be registered globally, or per program space. GDB checks the handlers for the current program space first, and then all of the global handles. The first handler that returns a value that is not None, has "handled" the objfile, at which point GDB continues. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2023-10-31Implement DAP setVariable requestTom Tromey3-21/+100
This patch implements the DAP setVariable request. setVariable is a bit odd in that it specifies the variable to modify by passing in the variable's container and the name of the variable. This approach can't handle variable shadowing (there are a couple of open DAP bugs on this topic), so this patch renames duplicates to avoid the problem.
2023-10-16Have DAP handle non-Value results from 'children'Tom Tromey1-2/+7
A pretty-printer's 'children' method may return values other than a gdb.Value -- it may return any value that can be converted to a gdb.Value. I noticed that this case did not work for DAP. This patch fixes the problem.
2023-10-16Handle gdb.LazyString in DAPTom Tromey1-1/+1
Andry pointed out that the DAP code did not properly handle gdb.LazyString results from a pretty-printer, yielding: TypeError: Object of type LazyString is not JSON serializable This patch fixes the problem, partly with a small patch in varref.py, but mainly by implementing tp_str for LazyString. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-10-16Add DAP scope cacheTom Tromey1-9/+29
Andry Ogorodnik, a co-worker, noticed that multiple "scopes" requests with the same frame would yield different variableReference values in the response. This patch adds a regression test for this, and adds a scope cache in scopes.py, ensuring that multiple identical requests will get the same response. Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2023-09-26Remove some unnecessary qualification from printing.pyTom Tromey1-5/+5
printing.py references "gdb.printing" in a few spots, but there's no need for this. I think this is leftover from when this code was (briefly) in some other module. This patch removes the unnecessary qualifications. Tested on x86-64 Fedora 36.
2023-09-26Add two new pretty-printer methodsTom Tromey2-11/+27
This adds two new pretty-printer methods, to support random access to children. The methods are implemented for the no-op array printer, and DAP is updated to use this. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-09-26Introduce gdb.ValuePrinterTom Tromey2-28/+29
There was an earlier thread about adding new methods to pretty-printers: https://sourceware.org/pipermail/gdb-patches/2023-June/200503.html We've known about the need for printer extensibility for a while, but have been hampered by backward-compatibilty concerns: gdb never documented that printers might acquire new methods, and so existing printers may have attribute name clashes. To solve this problem, this patch adds a new pretty-printer tag class that signals to gdb that the printer follows new extensibility rules. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30816 Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-09-26[gdb/dap] Fix dap for python < 3.8Tom de Vries1-1/+5
With any gdb.dap test and python 3.6 I run into: ... Error occurred in Python: 'code' object has no attribute 'co_posonlyargcount' ERROR: eof reading json header ... The attribute is not supported before python 3.8, which introduced the "Positional−only Parameters" concept. Fix this by using try/except AttributeError. Tested on x86_64-linux: - openSUSE Leap 15.4 with python 3.6, and - openSUSE Tumbleweed with python 3.11.5. Approved-By: Tom Tromey <tom@tromey.com>
2023-09-20Remove stray trailing "," from DAP breakpoint.pyTom Tromey1-1/+1
The buildbot pointed out that the last DAP series I checked in had an issue. Looking into it, it seems there is a stray trailing "," in breakpoint.py. This patch removes it. This seems to point out a test suite deficiency. I will look into fixing that.
2023-09-20gdb/dap: only include sourceReference if file path does not existGregory Anders1-5/+11
According to the DAP specification if the "sourceReference" field is included in a Source object, then the DAP client _must_ make a "source" request to the debugger to retrieve file contents, even if the Source object also includes path information. If the Source's path field is a valid path that the DAP client is able to read from the filesystem, having to make another request to the debugger to get the file contents is wasteful and leads to incorrect results (DAP clients will try to get the contents from the server and display those contents as a file with the name in "source.path", but this will conflict with the _acutal_ existing file at "source.path"). Instead, only set "sourceReference" if the source file path does not exist. Approved-By: Tom Tromey <tom@tromey.com>
2023-09-20gdb/dap: use breakpoint fullname to resolve sourceGregory Anders1-3/+3
If the breakpoint has a fullname, use that as the source path when resolving the breakpoint source information. This is consistent with other callers of make_source which also use "fullname" if it exists (see e.g. DAPFrameDecorator which returns the symtab's fullname). Approved-By: Tom Tromey <tom@tromey.com>
2023-09-20gdb/dap: ignore unused keyword args in step_outGregory Anders2-1/+8
Some DAP clients may send additional parameters in the stepOut command (e.g. "granularity") which are not used by GDB, but should nonetheless be accepted without error. Approved-By: Tom Tromey <tom@tromey.com>
2023-09-20gdb/dap: check for breakpoint source before unpackingGregory Anders1-8/+12
Not all breakpoints have a source location. For example, a breakpoint set on a raw address will have only the "address" field populated, but "source" will be None, which leads to a RuntimeError when attempting to unpack the filename and line number. Before attempting to unpack the filename and line number from the breakpoint, ensure that the source information is not None. Also populate the source and line information separately from the "instructionReference" field, so that breakpoints that include only an address are still included. Approved-By: Tom Tromey <tom@tromey.com>
2023-09-20Run 'black' on printing.pyTom Tromey1-1/+5
The buildbot pointed out that I neglected to re-run 'black' after making some changes. This patch fixes the oversight.
2023-09-19Handle pointers and references correctly in DAPTom Tromey1-0/+16
A user pointed out that the current DAP variable code does not let the client deference a pointer. Oops! Fixing this oversight is simple enough -- adding a new no-op pretty-printer for pointers and references is quite simple. However, doing this naive caused a regession in scopes.exp, which expected there to be no children of a 'const char *' variable. This problem was fixed by the preceding patches in the series, which ensure that a C type of this kind is recognized as a string. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30821
2023-09-12Avoid spurious breakpoint-setting failure in DAPTom Tromey1-1/+7
A user pointed out that if a DAP setBreakpoints request has a 'source' field in a SourceBreakpoint object, then the gdb DAP implementation will throw an exception. While SourceBreakpoint does not allow 'source' in the spec, it seems better to me to accept it. I don't think we should fully go down the "Postel's Law" path -- after all, we have the type-checker -- but at the same time, if we do send errors, they should be intentional and not artifacts of the implementation. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30820
2023-09-05Handle array- and string-like values in no-op pretty printersTom Tromey1-3/+23
This changes the no-op pretty printers -- used by DAP -- to handle array- and string-like objects known by the gdb core. Two new tests are added, one for Ada and one for Rust.
2023-09-05Select frame when fetching a frame variable in DAPTom Tromey2-3/+12
Right now, if a program uses multiple languages, DAP value formatting will always use the language of the innermost frame. However, it is better to use the variable's defining frame instead. This patch does this by selecting the frame first. This also fixes a possibly latent bug in the "stepOut" command -- "finish" is sensitive to the selected frame, but the DAP code may already select other frames when convenient. The DAP stepOut request only works on the newest frame, so be sure to select it before invoking "finish".
2023-08-16Implement DAP module-removed eventTom Tromey1-0/+13
DAP specifies an event that should be sent when a module is removed. This patch implements this. Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2023-08-03Remove f-string from DAPTom Tromey1-1/+1
One more f-string snuck into the DAP code, in breakpoint.py. Most of them were removed here: https://sourceware.org/pipermail/gdb-patches/2023-June/200023.html but I think this one landed after that patch. While DAP only supports Python 3.5 and later, f-strings were added in 3.6, so remove this. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30708
2023-08-03Use frame.name() in FrameDecoratorTom Tromey1-11/+4
A co-worker pointed out that gdb's DAP implementation might return an integer for the name of a stack frame, like: {"id": 1, "name": 93824992310799, ...} This can be seen currently in the logs of the bt-nodebug.exp test case. What is happening is that FrameDecorator falls back on returning the PC when the frame's function symbol cannot be found, relying on the gdb core to look up the minsym and print its name. This can actually yield the wrong answer sometimes, because it falls into the get_frame_pc / get_frame_address_in_block problem -- if the frame is at a call to a noreturn function, the PC in this case might appear to be in the next function in memory. For more on this, see: https://sourceware.org/bugzilla/show_bug.cgi?id=8416 and related bugs. However, there's a different approach we can take: the code here can simply use Frame.name. This handles the PC problem correctly, and gets us the information we need.
2023-08-01Implement DAP "source" requestTom Tromey1-1/+23
This implements the DAP "source" request. I renamed the "loadedSources" function from "sources" to "loaded_sources" to avoid any confusion. I also moved the loadedSources test to the new sources.exp. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30691
2023-08-01Handle Source in DAP breakpointLocationsTom Tromey2-8/+20
This changes the DAP breakpointLocations request to accept a Source and to decode it properly.
2023-08-01Introduce sourceReference handling in DAPTom Tromey3-20/+41
This changes the gdb DAP implementation to emit a real sourceReference, rather than emitting 0. Sources are tracked in some maps in sources.py, and a new helper function is introduced to compute the "Source" object that can be sent to the client.
2023-08-01Don't supply DAP 'path' for non-file shared librariesTom Tromey1-2/+4
The DAP 'module' event may include a 'path' component. I noticed that this is supplied even when the module in question does not come from a file. This patch only emits this field when the objfile corresponds to a real file. No test case, because I wasn't sure how to write a portable one. However, it's clear from gdb.log on Linux: {"type": "event", "event": "module", "body": {"reason": "new", "module": {"id": "system-supplied DSO at 0x7ffff7fc4000", "name": "system-supplied DSO at 0x7ffff7fc4000"}}, "seq": 21} Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30676
2023-08-01Implement ValueFormat for DAPTom Tromey3-78/+114
This patch implements ValueFormat for DAP. Currently this only means supporting "hex". Note that StackFrameFormat is defined to have many more options, but none are currently recognized. It isn't entirely clear how these should be handled. I'll file a new gdb bug for this, and perhaps an upstream DAP bug as well. New in v2: - I realized that the "hover" context was broken, and furthermore that we only had tests for "hover" failing, not for it succeeding. This version fixes the oversight and adds a test. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30469
2023-08-01Respect supportsMemoryReferences in DAPTom Tromey2-11/+7
I noticed that the support for memoryReference in the "variables" output is gated on the client "supportsMemoryReferences" capability. This patch implements this and makes some other changes to the DAP memory reference code: * Remove the memoryReference special case from _SetResult. Upstream DAP fixed this oversight in response to https://github.com/microsoft/debug-adapter-protocol/issues/414 * Don't use the address of a variable as its memoryReference -- only emit this for pointer types. There's no spec support for the previous approach. * Use strip_typedefs to handle typedefs of pointers.
2023-08-01Add DAP support for C++ exceptionsTom Tromey1-4/+17
This adds DAP support for the various C++ exception-catching operations. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30682
2023-08-01Implement DAP 'terminated' eventTom Tromey2-1/+2
This implements the DAP 'terminated' event. Vladimir Makaev noticed that VSCode will not report the debug session as over unless this is sent. It's not completely clear when exactly this event ought to be sent. Here I've done it when the inferior exits. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30681
2023-08-01Do not send "new breakpoint" event when breakpoint is setTom Tromey1-8/+28
When the DAP client sets a breakpoint, gdb currently sends a "new breakpoint" event. However, Vladimir Makaev discovered that this causes VSCode to think there are two breakpoints. This patch changes gdb to suppress the event in this case. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30678