aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
AgeCommit message (Collapse)AuthorFilesLines
2024-06-06DAP: Allow gdb exception in exec_and_log to propagateJohan Sternerup2-5/+8
This allows a request to specify that any gdb exception raised in exec_and_log within the gdb thread to be propagated back to the DAP thread (using the Canceller object as the orchestrator). Approved-By: Tom Tromey <tom@tromey.com>
2024-06-06DAP: Allow for deferring stop events from gdb threadJohan Sternerup2-7/+51
The existing `send_event_later()` method allows commands processed on the DAP thread to queue an event for execution until after the response has been sent to the client. We now introduce a corresponding method for use by the gdb thread. This method `send_event_maybe_later()` will queue the event just like `send_event_later()`, but only if it has been configured to do so by a new @request option `defer_stop_events`. As the name implies the functionality is currently only used for handling stop events. Approved-By: Tom Tromey <tom@tromey.com>
2024-06-04Return global scope from DAP scopes requestTom Tromey2-0/+101
A co-worker requested that the DAP code emit a scope for global variables. It's not really practical to do this for all globals, but it seemed reasonable to do this for globals coming from the frame's compilation unit. For Ada in particular, this is convenient as it exposes package-scoped variables. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-06-04Convert DAP disassemble code to use Block hashingTom Tromey1-4/+3
This changes the DAP disassemble code to use the new Block hashing, storing the already-visited blocks in a set rather than a list.
2024-06-04Memoize gdb.Block and make them hashableTom Tromey1-64/+79
In subsequent patches, it's handy if gdb.Block is hashable, so it can be stored in a set or a dictionary. However, doing this in a straightforward way is not really possible, because a block isn't truly immutable -- it can be invalidated. And, while this isn't a real problem for my use case (in DAP the maps are only used during a single stop), it seemed error-prone. This patch instead takes the approach of using the gdb.Block's own object identity to allow hashing. This seems fine because the contents don't affect the hashing. In order for this to work, though, the blocks have to be memoized -- two requests for the same block must return the same object. This also allows (actually, requires) the simplification of the rich-compare method for blocks. Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2024-06-04Put "source" into DAP scopeTom Tromey1-1/+4
I noticed a FIXME comment in the DAP code about adding a "source" field to a scope. This is easy to implement; I don't know why I didn't do this originally.
2024-06-03Enable call of overloaded subscript operator from pythonHannes Domani1-1/+5
If you try to use the overloaded subscript operator of a class in python, it fails like this: (gdb) py print(gdb.parse_and_eval('b')[5]) Traceback (most recent call last): File "<string>", line 1, in <module> gdb.error: Cannot subscript requested type. Error while executing Python code. This simply checks if such an operator exists, and calls it instead, making this possible: (gdb) py print(gdb.parse_and_eval('b')[5]) 102 'f' Approved-By: Tom Tromey <tom@tromey.com>
2024-06-03Allow calling of convenience functions with pythonHannes Domani1-5/+13
As mentioned in PR13326, currently when you try to call a convenience function with python, you get this error: (gdb) py print(gdb.convenience_variable("_isvoid")(3)) Traceback (most recent call last): File "<string>", line 1, in <module> RuntimeError: Value is not callable (not TYPE_CODE_FUNC or TYPE_CODE_METHOD). Error while executing Python code. So this extends valpy_call to handle TYPE_CODE_INTERNAL_FUNCTION as well, making this possible: (gdb) py print(gdb.convenience_variable("_isvoid")(3)) 0 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13326 Approved-By: Tom Tromey <tom@tromey.com>
2024-05-17Don't allow new-ui to start the TUITom Tromey1-0/+3
The TUI can't really work properly with new-ui, at least not as currently written. This patch changes new-ui to reject an attempt. Attempting to make a DAP ui this way is also now rejected. Regression tested on x86-64 Fedora 38. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29273 Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-05-10Add symbol, line, and location to DAP disassemble resultTom Tromey1-7/+52
The DAP spec allows a number of attributes on the resulting instructions that gdb currently does not emit. A user requested some of these, so this patch adds the 'symbol', 'line', and 'location' attributes. While the spec lets the implementation omit 'location' in some cases, it was simpler in the code to just always emit it, as then no extra tracking was needed.
2024-05-10Implement tp_richcompare for gdb.BlockTom Tromey1-1/+23
I noticed that two gdb.Block objects will never compare as equal with '=='. This patch fixes the problem by implementing tp_richcompare, as was done for gdb.Frame.
2024-05-10Simplify DAP make_source callersTom Tromey3-7/+8
A couple callers of make_source call basename by hand. Rather than add another caller like this, I thought it would be better to put this ability into make_source itself.
2024-05-10Remove FIXME from DAPTom Tromey1-1/+0
This patch removes one of the few DAP "FIXME" comments. This particular comment is already covered by PR dap/31036.
2024-05-10[gdb/python] Make gdb.UnwindInfo.add_saved_register more robust (fixup)Tom de Vries1-9/+17
In commit 2236c5e384d ("[gdb/python] Make gdb.UnwindInfo.add_saved_register more robust") I added this code in unwind_infopy_add_saved_register: ... if (value->optimized_out () || !value->entirely_available ()) ... which may throw c++ exceptions. This needs to be caught and transformed into a python exception. Fix this by using GDB_PY_HANDLE_EXCEPTION. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> Fixes: 2236c5e384d ("[gdb/python] Make gdb.UnwindInfo.add_saved_register more robust")
2024-05-08[gdb/python] Make gdb.UnwindInfo.add_saved_register more robustTom de Vries1-0/+12
On arm-linux, until commit bbb12eb9c84 ("gdb/arm: Remove tpidruro register from non-FreeBSD target descriptions") I ran into: ... FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: \ backtrace when the unwind is broken at frame 5 ... What happens is the following: - the TestUnwinder from inline-frame-cycle-unwind.py calls gdb.UnwindInfo.add_saved_register with reg == tpidruro and value "<unavailable>", - pyuw_sniffer calls value->contents ().data () to access the value of the register, which throws an UNAVAILABLE_ERROR, - this causes the TestUnwinder unwinder to fail, after which another unwinder succeeds and returns the correct frame, and - the test-case fails because it's counting on the TestUnwinder to succeed and return an incorrect frame. Fix this by checking for !value::entirely_available as well as valued::optimized_out in unwind_infopy_add_saved_register. Tested on x86_64-linux and arm-linux. Approved-By: Andrew Burgess <aburgess@redhat.com> PR python/31437 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31437
2024-04-25gdb: remove gdbcmd.hSimon Marchi8-8/+8
Most files including gdbcmd.h currently rely on it to access things actually declared in cli/cli-cmds.h (setlist, showlist, etc). To make things easy, replace all includes of gdbcmd.h with includes of cli/cli-cmds.h. This might lead to some unused includes of cli/cli-cmds.h, but it's harmless, and much faster than going through the 170 or so files by hand. Change-Id: I11f884d4d616c12c05f395c98bbc2892950fb00f Approved-By: Tom Tromey <tom@tromey.com>
2024-04-23gdb: change return type of check_quit_flag to boolSimon Marchi1-3/+3
Change the return type of the check_quit_flag function to bool. Update a few related spots. Change-Id: I9d3a15d3f8651efb02c7d211f06222a592bd4184 Approved-By: Tom Tromey <tom@tromey.com>
2024-04-16[gdb/python] Throw MemoryError in inferior.read_memory if malloc failsTom de Vries2-3/+17
PR python/31631 reports a gdb internal error when doing: ... (gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff) utils.c:709: internal-error: virtual memory exhausted. A problem internal to GDB has been detected, further debugging may prove unreliable. ... Fix this by throwing a python MemoryError, such that we have instead: ... (gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff) Python Exception <class 'MemoryError'>: Error occurred in Python. (gdb) ... Likewise for DAP. Tested on x86_64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31631
2024-04-02Run isortTom Tromey33-65/+77
This patch is the result of running 'isort .' in the gdb directory. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Prepare gdb for isortTom Tromey2-0/+5
This patch prepares gdb for isort: it adds a couple of isort marker comments where needed, and it adds an isort clause to setup.cfg. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Do not use bare "except"Tom Tromey2-4/+4
flake8 warns about a bare "except". The docs point out that this will also catch KeyboardInterrupt and SystemExit exceptions, which is normally undesirable. Using "except Exception" catches everything reasonable, so this patch makes this change. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Suppress some "undefined" warnings from flake8Tom Tromey1-8/+9
flake8 warns about some identifiers in __init__.py, because it does not realize these come from the star-imported _gdb module. This patch suppresses these warnings.
2024-04-02Specify ImportError in styling.pyTom Tromey1-1/+1
styling.py has a long try/except surrounding most of the body. flake8 warns about the final bare "except". However, this except is really only there to catch the situation where the host doesn't have Pygments installed. This patch changes this to only catch ImportError. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Suppress star import errorsTom Tromey2-3/+5
flake8 warns about the "from _gdb.disassembler import *" line in disassembler.py, and a similar line from __init__.py. These line are needed to re-export names from the corresponding C++ module, so this patch applies the appropriate "noqa" flags. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Remove bare "except" from disassembler.pyTom Tromey1-14/+7
flake8 complains about a bare "except" in disassembler.py. In this case, the code purports to guard against some kind of user error involving data structure corruption. I think it's better here to just let the error occur -- py-disasm.c will show a stack trace in this case. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Remove unused import from gdb/__init__.pyTom Tromey1-1/+0
flake8 points out that the import of _gdb in gdb/__init__.py is unused. Remove it. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Ignore unsed import in dap/__init__.pyTom Tromey1-15/+17
flake8 warns about dap/__init__.py because it has a number of unused imports. Most of these are intentional: the import is done to ensure that the a DAP request is registered with the server object. This patch applies a "noqa" comment to these imports, and also removes one import that is truly unnecessary. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-04-02Fix flake8 errors in dap/server.pyTom Tromey1-1/+2
Commit 032d23a6 ("Fix stray KeyboardInterrupt after cancel") introduced some errors into dap/server.py. A function is called but not imported, and the wrong variable name is used. This patch corrects both errors. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-03-26gdb, gdbserver, gdbsupport: remove includes of early headersSimon Marchi50-50/+0
Now that defs.h, server.h and common-defs.h are included via the `-include` option, it is no longer necessary for source files to include them. Remove all the inclusions of these files I could find. Update the generation scripts where relevant. Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837 Approved-By: Pedro Alves <pedro@palves.net>
2024-03-19Fix two serious flake8 reportsTom Tromey1-15/+10
flake8 points out that some code in frame_filters.py is referring to undefined variables. In the first hunk, I've changed the code to match what other 'complete' methods do in this file. In the second hunk, I've simply removed the try/except -- if get_filter_priority fails, it will raise GdbError, which is already handled properly by gdb.
2024-03-19gdb/python: Fix segfault when iterating over empty linetableToby Lloyd Davies1-1/+2
symtab-> linetable () is set to null in buildsym_compunit::end_compunit_symtab_with_blockvector () if the symtab has no linetable. Attempting to iterate over this linetable using the Python API caused GDB to segfault. Approved-By: Tom Tromey <tom@tromey.com>
2024-03-18Set __file__ when source'ing a Python scriptTom Tromey1-10/+63
This patch arranges to set __file__ when source'ing a Python script. This fixes a problem that was introduced by the "source" rewrite, and then pointed out by Lancelot Six. Reviewed-by: Lancelot Six <lancelot.six@amd.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-03-14Remove 'if' from GDB_PY_HANDLE_EXCEPTIONTom Tromey5-42/+17
This removes the embedded 'if' from GDB_PY_HANDLE_EXCEPTION and GDB_PY_SET_HANDLE_EXCEPTION. I believe this 'if' was necessary with the old gdb try/catch macros, but it no longer is: these should only ever be called from a 'catch' block, where it's already known that an exception was thrown. Simon pointed out, though, that in a few spots, these were in facts called outside of 'catch' blocks. This patch cleans up these spots. I also found one spot where a redundant 'return nullptr' could be removed.
2024-03-09[gdb/python] Handle deprecation of PyErr_{Fetch,Restore} in 3.12Tom de Vries1-0/+26
Starting python version 3.12, PyErr_Fetch and PyErr_Restore are deprecated. Use PyErr_GetRaisedException and PyErr_SetRaisedException instead, for python >= 3.12. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-03-09[gdb/python] Normalize exceptions in gdbpy_err_fetchTom de Vries1-1/+14
With python 3.12, I run into: ... (gdb) PASS: gdb.python/py-block.exp: check variable access python print (block['nonexistent'])^M Python Exception <class 'KeyError'>: 'nonexistent'^M Error occurred in Python: 'nonexistent'^M (gdb) FAIL: gdb.python/py-block.exp: check nonexistent variable ... The problem is that that PyErr_Fetch returns a normalized exception, while the test-case matches the output for an unnormalized exception. With python 3.6, PyErr_Fetch returns an unnormalized exception, and the test passes. Fix this by: - updating the test-case to match the output for a normalized exception, and - lazily forcing normalized exceptions using PyErr_NormalizeException. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-03-09[gdb/python] Use gdbpy_err_fetch::{type,value} as gettersTom de Vries2-6/+15
Similar to gdbpy_err_fetch::value, add a getter gdbpy_err_fetch::type, and use both consistently to get gdbpy_err_fetch members m_error_value and m_error_type. Tested on aarch64-linux.
2024-03-08Add return value to DAP scopeTom Tromey2-2/+40
A bug report in the DAP specification repository pointed out that it is typical for DAP implementations to put a function's return value into the outermost scope. This patch changes gdb to follow this convention. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31341 Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
2024-03-08Export "finish" return value to PythonTom Tromey1-1/+22
This patch changes the Python "stop" event emission code to also add the function return value, if it is known. This happens when the stop comes from a "finish" command and when the value can be fetched. The test is in the next patch. Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-02-29[gdb/dap] Fix stray KeyboardInterrupt after cancelTom de Vries1-21/+67
When running test-case gdb.dap/pause.exp 100 times in a loop, it passes 100/100. But if we remove the two "sleep 0.2" from the test-case, we run into (copied from dap.log and edited for readability): ... Traceback (most recent call last): File "startup.py", line 251, in message def message(): KeyboardInterrupt Quit ... This happens as follows. CancellationHandler.cancel calls gdb.interrupt to cancel a request in flight. The idea is that this interrupt triggers while in fn here in message (a nested function of send_gdb_with_response): ... def message(): try: val = fn() result_q.put(val) except (Exception, KeyboardInterrupt) as e: result_q.put(e) ... but instead it triggers outside the try/except. Fix this by: - in CancellationHandler, renaming variable in_flight to in_flight_dap_thread, and adding a variable in_flight_gdb_thread to be able to distinguish when a request is in flight in the dap thread or the gdb thread. - adding a wrapper Cancellable to to deal with cancelling the wrapped event - using Cancellable in send_gdb and send_gdb_with_response to wrap the posted event - in CancellationHandler.cancel, only call gdb.interrupt if req == self.in_flight_gdb_thread. This makes the test-case pass 100/100, also when adding the extra stressor of "taskset -c 0", which makes the fail more likely without the patch. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR dap/31275 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31275
2024-02-29[gdb/dap] Move send_gdb and send_gdb_with_response to server moduleTom de Vries3-50/+48
Move functions send_gdb and send_gdb_with_response, as well as class Invoker to server module. Separated out to make the following patch easier to read. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-02-28Fix gdb.interrupt raceTom Tromey1-0/+4
gdb.interrupt was introduced to implement DAP request cancellation. However, because it can be run from another thread, and because I didn't look deeply enough at the implementation, it turns out to be racy. The fix here is to lock accesses to certain globals in extension.c. Note that this won't work in the case where configure detects that the C++ compiler doesn't provide thread support. This version of the patch disables DAP entirely in this situation. Regression tested on x86-64 Fedora 38. I also ran gdb.dap/pause.exp in a thread-sanitizer build tree to make sure the reported race is gone. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31263
2024-02-27Explicitly quit gdb from DAP server threadTom Tromey1-0/+1
This changes the DAP code to explicitly request that gdb exit. Previously this could cause crashes, but with the previous cleanups, this should no longer happen. This also adds a tests that ensures that gdb exits with status 0.
2024-02-27Add extension_language_ops::shutdownTom Tromey1-3/+3
Right now, Python is shut down via a final cleanup. However, it seems to me that it is better for extension languages to be shut down explicitly, after all the ordinary final cleanups are run. The main reason for this is that a subsequent patch adds another case like finalize_values; and rather than add a series of workarounds for Python shutdown, it seemed better to let these be done via final cleanups, and then have Python shutdown itself be the special case.
2024-02-27Rewrite final cleanupsTom Tromey1-2/+2
This patch rewrites final cleanups to use std::function and otherwise be more C++-ish.
2024-02-27Rewrite "python" command exception handlingTom Tromey2-91/+45
The "python" command (and the Python implementation of the gdb "source" command) does not handle Python exceptions in the same way as other gdb-facing Python code. In particular, exceptions are turned into a generic error rather than being routed through gdbpy_handle_exception, which takes care of converting to 'quit' as appropriate. I think this was done this way because PyRun_SimpleFile and friends do not propagate the Python exception -- they simply indicate that one occurred. This patch reimplements these functions to respect the general gdb convention here. As a bonus, some Windows-specific code can be removed, as can the _execute_file function. The bulk of this change is tweaking the test suite to match the new way that exceptions are displayed. These changes are largely uninteresting. However, it's worth pointing out the py-error.exp change. Here, the failure changes because the test changes the host charset to something that isn't supported by Python. This then results in a weird error in the new setup. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31354 Acked-By: Tom de Vries <tdevries@suse.de> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-02-27Fix formatting buglet in python.cTom Tromey1-1/+1
python.c has a split string that is missing a space. There's also a stray backslash in this code. Reviewed-By: Tom de Vries <tdevries@suse.de>
2024-02-23Remove unused importTom Tromey1-1/+1
flake8 points out that dap/io.py does not use send_gdb. This patch removes the unused import.
2024-02-22[gdb/dap] Fix race between dap exit and gdb exitTom de Vries1-1/+9
When DAP shuts down due to an EOF event, there's a race between: - gdb's main thread handling a SIGHUP, and - the DAP main thread exiting. Fix this by waiting for DAP's main thread exit during the gdb_exiting event. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR dap/31380 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31380
2024-02-22[gdb/dap] Fix race between dap startup and dap log fileTom de Vries2-4/+39
In dap_gdb_start we do: ... append GDBFLAGS " -iex \"set debug dap-log-file $logfile\" -q -i=dap" ... While the dap log file setting comes before the dap interpreter setting, the order is the other way around: - first, the dap interpreter is started - second, the -iex commands are executed and the log file is initialized. Consequently, there's a race between dap interpreter startup and dap log file initialization. This cannot be fixed by using -eiex instead. Before the interpreter is started, the "set debug dap-log-file" command is not yet registered. Fix this by postponing the start of the DAP server until GDB has processed all command files. Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR dap/31386 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31386
2024-02-22[gdb/dap] Factor out thread_logTom de Vries1-3/+12
In thread_wrapper I used a style where a message is prefixed with the thread name. Factor this out into a new function thread_log. Also treat the GDB main thread special, because it's usual name is MainThread: ... MainThread: <msg> ... which is the default name assigned by python, so instead use the more explicit: ... GDB main: <msg> ... Tested on aarch64-linux. Approved-By: Tom Tromey <tom@tromey.com>