The FinishBreakpoint.return_value attribute will not be populated
correctly for tail call functions.
In bpfinishpy_init (python/py-finishbreakpoint.c) we use the function
get_frame_pc_if_available to return an address, and then use this
address to lookup a function symbol.
The problem is that, for tail call functions, the address returned by
get_frame_pc_if_available can be outside the bounds of the function,
as a result GDB might find no function symbol at all, or might find
the wrong function symbol, if the tail call function is immediately
adjacent to the next function.
Fix this by using get_frame_address_in_block_if_available instead.
For tail call functions this will return an address within the bounds
of the function, which means that GDB should find the correct function
symbol, and from this the correct return type.
I've extended the existing FinishBreakpoint with tail call test case
to include printing the return value, this test fails without this
patch, but now works.
Approved-By: Tom Tromey <tom@tromey.com>
This commit adds a new method gdb.Symtab.source_lines. This method
can be used to read the lines from a symtab's source file. This is
similar to GDB's internal source_cache::get_source_lines function.
Currently using the Python API, if a user wants to display source
lines then they need to use Symtab.fullname() to get the source file
name, then open this file and parse out the lines themselves.
This isn't too much effort, but the problem is that these lines will
not be styled. The user could style the source content themselves,
but will this be styled exactly as GDB would style it?
The new Symtab.source_lines() method returns source lines with styling
included (as ANSI terminal escape sequences), assuming of course, that
styling is currently enabled.
Of course, in some cases, a user of the Python API might want source
code without styling. That's supported too, the new method has an
'unstyled' argument. If this is True then the output is forced to be
unstyled. The argument is named 'unstyled' rather than 'styled'
because the API call cannot force styling on. If 'set style enabled
off' is in effect then making the API call will never return styled
source lines.
The new API call allows for a range of lines to be requested if
desired.
As part of this commit I've updated the host_string_to_python_string
utility function to take a std::string_view.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
This commit introduces a new Python event, selected_context. This
event is attached to the user_selected_context_changed observer, which
triggers when the user changes the currently selected inferior,
thread, or frame.
Adding this event allows a Python extension to update in response to
user driven changes without having to poll the state from a
before_prompt hook, which is what I currently do to achieve the same
results.
I did consider splitting the user_selected_context_changed observer
into 3 separate Python events, inferior_changed, thread_changed, and
frame_changed, but I couldn't see any significant advantage to doing
this, so in the end I went with just a single event, and the event
object contains the inferior, thread, and frame.
Additionally, the user isn't informed about which aspect of the
context changed. That is, every event carries the inferior, thread,
and frame, so an event triggered when switching frames will looks
identical to an event triggered when switching inferiors. If the user
wants to know what changed then they will have to track the current
state themselves, and then compare the event state to the stored
current state. In many cases though I suspect that just being told
something changed, and then updating everything will be sufficient,
which is why I've not bothered trying to inform the user what changed.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24482
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
In some spots the Python code will do an explicit upcast of gdbpy_ref,
like:
return gdbpy_ref<> ((PyObject *) color_obj.release ());
Now that ref_ptr allows upcasts, and because gdb's Python objects
derive from PyObject, these reshufflings can be expressed more simply.
Approved-By: Andrew Burgess <aburgess@redhat.com>
Now that gdb's Python types derive from PyObject, there's no need to
use a template for gdbpy_ref_policy. This simplifies the code a tiny
bit.
Approved-By: Andrew Burgess <aburgess@redhat.com>
* PyTuple_GET_ITEM -> PyTuple_GetItem
* PyTuple_SET_ITEM -> PyTuple_SetItem
* PyTuple_GET_SIZE -> PyTuple_Size
Unlike PyTuple_SET_ITEM(), PyTuple_SetItem() returns an integer: 0 on
success and -1 on error (e.g. IndexError). The existing code must therefore
be updated to handle this new behaviour.
Since processing now stops when PyTuple_SetItem() returns an error, some
resources (such as newly allocated tuples) must be properly deallocated in
error paths. To address this, this patch replaces the use of raw 'PyObject *'
pointers with gdbpy_ref<>, a reference-counted wrapper around 'PyObject *',
which automatically decrements the reference count on early exit.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
I noticed a few spots in the Python code that were decoding method
arguments and then immediately type-checking an argument. This can be
done more concisely using the "O!" format.
Reviewed-By: Tom de Vries <tdevries@suse.de>
They are unreachable because there is a return statement in all possible code
paths before.
Change-Id: I9db2f41f8017380c0c79f97af9bbf8734038ba9a
Approved-By: Tom Tromey <tom@tromey.com>
This changes gdbpy_registry::lookup to return a gdbpy_ref<>, using the
type system to convey that a new reference is always returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes gdbarch_to_arch_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes symtab_to_linetable_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes frame_info_to_frame_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes type_to_type_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes value_to_value_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes block_to_block_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes symtab_to_symtab_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes symbol_to_symbol_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes symtab_and_line_to_sal_object to return a gdbpy_ref<>,
using the type system to convey that a new reference is always
returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit removes some uses of gdb::argv_vec from GDB.
The gdb::argv_vec class exists in part due to our need to convert from
one container type to another in a few places, and I think by using
templates we can push this conversion down into
gdbsupport/common-inferior.{cc,h} and remove the conversion logic from
higher level code in GDB. This should make core GDB simpler.
For examples of this simplification, see python/py-inferior.c,
remote.c, and unittests/remote-arg-selftests.c, where this commit has
allowed for the removal of some code that only exists in order to
convert the container type.
Ideally I'd like to see all uses of gdb::argv_vec removed, but I'm
still not sure about the use in nat/fork-inferior.c, I think its use
there might be the best solution, so for now at least, I have no plans
to touch that code.
There should be no user visible changes after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
We have many times the pattern:
current_source_location *loc
= current_source_key.get (pspace);
if (loc == nullptr)
loc = current_source_key.emplace (pspace);
return loc;
I thought it would be nice to have it directly part of registry::key.
Add a try_emplace method, which is like emplace, except that it returns
the existing data, if any. The try_emplace name comes from similar
methods in std::map or gdb::unordered_map
(ankerl::unordered_dense::map).
Replace as many callers as I could find to use it.
Change-Id: I21f922ca065a354f041caaf70484d6cfbcbb76ed
Approved-By: Tom Tromey <tom@tromey.com>
Since we use C++ and not C, I think that we should gradually move to
using references for things that can never be nullptr. One example of
this is the return value of the emplace method.
Change it to return a reference, and (to keep the patch straightforward)
update all callers to take the address. More patches could follow to
propagate the use of references further.
Change-Id: I725539694cf496f8288918cc29d7aaae9aca2292
Approved-By: Tom Tromey <tom@tromey.com>
This patch changes how gdb output redirection is done.
Currently, output is done via the UI. gdb_stdout, for example, is a
define the expands to an lvalue referencing a field in the current UI.
When redirecting, this field may temporarily be reset; and when
logging is enabled or disabled, this is also done.
This has lead to bugs where the combination of redirection and logging
results in use-after-free. Crashes are readily observable; see the
new test cases.
This patch upends this. Now, gdb_stdout is simply an rvalue, and
refers to the current interpreter. The interpreter provides ui_files
that do whatever rewriting is needed (mostly for MI); then output is
forward to the current UI via an indirection (see the new
ui::passthrough_file).
The ui provides paging, logging, timestamps, and the final stream that
writes to an actual file descriptor.
Redirection is handled at the ui layer. Rather than changing the
output pipeline, new ui_files are simply swapped in by rewriting
pointers, hopefully with a scoped_restore.
Redirecting at the ui layer means that interpreter rewriting is still
applied when capturing output. This fixes one of the reported bugs.
Not changing the pipeline means that the problems with the combination
of redirect and logging simply vanish. Logging just changes a flag
and doesn't involve object destruction.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17697
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28620
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28798
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28948
Approved-By: Andrew Burgess <aburgess@redhat.com>
While working on this series, I found a number of odd styling issues
recurred. For instance, the issue where the pager would lose track
and style subsequent output incorrectly reappeared.
It turned out that different ui_file objects in the output pipeline
would get confused about their current style. And, looking deeper at
this, I realized that mainly it is the pager that really needs to
track the current style at all. All the other file implementations
can be purely reactive (except the buffered stream code, as Andrew
pointed out).
This patch moves m_applied_style from ui_file and into pager_file.
This necessitated making ui_file::vprintf virtual, so that the base
class could pass in the "plain" style as the starting point, whereas
the pager could use the applied style. (I did not investigate whether
this was truly necessary, and I somewhat suspect it might not be.)
This straightforward approach caused some regressions, mostly
involving extra ANSI escapes being emitted. I fixed most of these by
arranging for ui_out::call_do_message to track styles a little more
thoroughly.
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
Fix a whitespace problem pre-commit complains about:
...
check-whitespace........................................................Failed
- hook id: check-whitespace
- exit code: 2
gdb/python/py-ref.h:58: indent with spaces.
+ "The __dict__ for this object.", nullptr },
...
Previous patches made some Python extension objects ipublicly inherit
directly or indirectly from PyObject.
In the interest of consistency, this patch makes all remaining Python
extension objects still not inheriting from PyObject do so.
Approved-By: Tom Tromey <tom@tromey.com>
When enabling the Python limited API, pointers to Python C extension
objects can no longer be implicitly converted to 'PyObject *' by the
compiler.
gdbpy_ref_policy is a templated class that provides a generic interface
for incrementing and decrementing the reference counter on the given
object. It is used as a specialisation of the policy parameter in
gdb::ref_ptr, together with PyObject as the parameter type. As a result,
gdbpy_ref_policy always expects an argument derived from PyObject.
This patch fixes the resulting compilation issue by adding an explicit
static_cast to 'PyObject *' before passing the value to Py_INCREF and
Py_DECREF. As a side effect, these casts enforce, at compile time, that
the template type passed to gdbpy_ref_policy is a subclass of PyObject.
To provide a clearer diagnostic when an incorrect type is used, a
static_assert is added to gdbpy_ref_policy, avoiding obscure errors
originating from the static_cast. Finally, all C Python extension types
passed to gdbpy_ref_policy are updated to inherit from PyObject.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
GDB is currently using the Python unlimited API. Migrating the codebase
to the Python limited API would have for benefit to make a GDB build
artifacts compatible with older and newer versions of Python that they
were built with.
This patch prepares the ground for migrating the existing C extension
types from static types to heap-allocated ones, by removing the
dependency on tp_dictoffset, which is unavailable when using the limited
API.
One of the most common incompatibilities in the current static type
declarations is the tp_dictoffset slot, which specifies the dictionary
offset within the instance structure. Historically, the unlimited
API has provided two approaches to supply a dictionary for __dict__:
* A managed dictionary.
Setting Py_TPFLAGS_MANAGED_DICT in tp_flags indicates that the
instances of the type have a __dict__ attribute, and that the
dictionary is managed by Python.
According to the Python documentation, this is the recommended approach.
However, this flag was introduced in 3.12, together with
PyObject_VisitManagedDict() and PyObject_ClearManagedDict(), neither
of which is part of the limited API (at least for now). As a result,
this recommended approach is not viable in the context of the limited
API.
* An instance dictionary, for which the offset in the instance is
provided via tp_dictoffset.
According to the Python documentation, this "tp slot" is on the
deprecation path, and Py_TPFLAGS_MANAGED_DICT should be used instead.
Given the age of the GDB codebase and the requirement to support older
Python versions (>= 3.4), no need to argue that today, the implementation
of __dict__ relies on tp_dictoffset. However, in the context of the
limited API, PyType_Slot does not provide a Py_tp_dictoffset member, so
another approach is needed to provide __dict__ to instances of C extension
types.
Given the constraints of the limited API, the proposed solution consists
in providing a dictionary through a common base class, gdbpy__dict__wrapper.
This helper class owns a dictionary member corresponding to __dict__, and
any C extension type requiring a __dict__ must inherit from it. Since
extension object must also be convertible to PyObject, this wrapper class
publicly inherits from PyObject as well.
Access to the dictionary is provided via a custom getter defined in a
PyGetSetDef, similarily to what was previously done with gdb_py_generic_dict().
Because __dict__ participates in attribute look-up, and since this dictionary
is neither managed by Python nor exposed via tp_dictoffset, custom
implementations of tp_getattro and tp_setattro are required to correctly
redirect attribute look-ups to the dictionary. These custom implementations
— equivalent to PyObject_GenericGetAttr() and PyObject_GenericSetAttr() —
must be installed via tp_getattro / tp_setattro for static types, or
Py_tp_getattro / Py_tp_setattro for heap-allocated types.
- gdbpy__dict__wrapper: a base class for C extension objects that own a
__dict__.
- gdb_py_generic_dict_getter: a __dict__ getter for extension types
derived from gdbpy__dict__wrapper.
- gdb_py_generic_getattro: equivalent of PyObject_GenericGetAttr, but
fixes the look-up of __dict__.
- gdb_py_generic_setattro: equivalent of PyObject_GenericSetAttr, but
fixes the look-up of __dict__.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
When enabling the Python limited API, pointers to Python C extension
objects can no longer be implicitly converted to 'PyObject *' by the
compiler.
The lookup() method of gbdpy_registry returns a new reference to the
type object of the looked-up entry. It does so by calling Py_XINCREF()
to increment the reference counter of the returned type object. The
template parameter obj_type corresponds to the type of C extension
object type. With the Python limited API enabled, obj_type can no longer
be implicitly converted to 'PyObject *' when passed to Py_XINCREF().
This patch fixes the resulting compilation issue by adding an explicit
static_cast to 'PyObject *' before passing the value to Py_XINCREF().
As a side effect, this cast enforces, at compile time, that the template
type 'Storage::obj_type' passed to gdbpy_registry is a subclass of
PyObject. To provide a clearer diagnostic when an incorrect type is used,
a static_assert is added to gdbpy_registry, avoiding obscure errors
originating from the static_cast. Finally, the relevant C extension types
passed to gdbpy_registry are updated to inherit publicly from PyObject.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
This patch replaces PyImport_ExtendInittab () with its limited C
API equivalent, PyImport_AppendInittab (), a convenience wrapper
around PyImport_ExtendInittab ().
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
This patch replaces Py_CompileStringExFlags () with its limited C API
equivalent, Py_CompileString (). The eval_python_command () helper is
now exposed through the private GDB Python API as a utility function.
PyRun_SimpleString () is replaced with eval_python_command () to avoid
code duplication.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
"pre-commit autoupdate" suggests a new version of black. This version
seems to want to change how destructuring assignments are formatted.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This replaces a number of uses of 'ptr.reset (xstrdup ())'
with 'ptr = make_unique_xstrdup ()'.
The main motivation for this is that, IMO, it's better to avoid the
reset method when possible.
Approved-By: Andrew Burgess <aburgess@redhat.com>
A previous patch [1] enabled readline in Python in a GDB-specific way
and blocked the standard Python readline module to prevent conflicts
with GDB by adding a custom importer raising an exception for the readline
module.
This custom importer was written back in 2012 for old Python versions,
and does not seem to work anymore with Python 3.x. find_module() and
load_module() have been deprecated since Python 3.4, and the first one
has been removed since 3.12, and the second will be removed in 3.15.
The GDB testsuite does not cover this use case, and the removal of
find_module() was not detected by the testsuite. This issue is tracked
in bug 32473.
importlib.abc.MetaPathFinder:
find_module(fullname, path)
Deprecated since version 3.4: Use find_spec() instead.
Changed in version 3.10: Use of find_module() by the import
system now raises ImportWarning.
Changed in version 3.12: find_module() has been removed. Use
find_spec() instead.
find_spec(fullname, path, target=None)
New in version 3.4, as a replacement for find_module.
importlib.abc.Loader:
load_module(fullname):
Deprecated since version 3.4, will be removed in version 3.15
The recommended API for loading a module is exec_module()
(and create_module()).
This patch uses Patryk Sondej's approach detailed in bug 32473, but with
a slight variation regarding the finder insertion in sys.meta_path.
It also adds a new test to prevent future regression.
[1]: 037bbc8eea
Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32473
This changes the DAP code so that constants will now be returned by a
DAP scopes request. This is perhaps slightly strange with Ada
enumerators, but on the other hand this is consistent with what the
CLI does.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
A co-worker reported that certain symbols weren't appearing in the DAP
'scopes' response. In particular, symbols with non-ASCII names didn't
appear; though further research showed that this was in fact a result
of the variable in question actually being a constant.
Unfortunately Ada still requires the user to set the Ada source
character set in order to properly display symbol names. For DAP, it
seemed to make sense to allow this as a launch parameter. This patch
implements this.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
This changes some DAP code to explicitly use a symbol's print name.
Some places were using '.name'; and while 'str' does use the print
name, it seems better to be both consistent and explicit.
interp::inited is currently public, because interp_set does the task
of making sure the interpreter is only initialized a single time.
However, the interpreter can do this job itself, and this member can
be private.
This updates the copyright headers to include 2026. I did this by
running gdb/copyright.py and then manually modifying a few files as
noted by the script.
This adds a way for DAP clients to catch unhandled Ada exceptions,
similar to the "catch exception unhandled" CLI command.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
In PR dap/33228, we changed gdb to gracefully report an error if a DAP
'variables' request asked for more variables than had been reported.
This behavior was clarified in the spec, see
https://github.com/microsoft/debug-adapter-protocol/issues/571
This patch changes gdb to conform to the specified approach, namely
truncating the list rather than erroring.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33228
Approved-By: Andrew Burgess <aburgess@redhat.com>
gdb's implementation of the DAP 'disconnect' request was incorrect in
a few ways.
First, the 'terminateDebuggee' field is optional, and has a special
meaning when not supplied: it should do whatever the default is.
Second, if the inferior was attached, it should detach rather than
terminate by default.
Finally, if the inferior was not started at all, it seems reasonable
for this request to simply succeed silently -- currently it returns
"success: false" with the reason being that the inferior isn't
running.
Approved-By: Andrew Burgess <aburgess@redhat.com>
This changes user_reg_map_name_to_regnum to use std::string_view.
This pointed out some dead code in that function: the "len < 0" test
in the loop can never be true, because earlier code changes 'len' in
this case.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
In C++20, "module" is an "identifier with special meaning". While it
can be used as a variable name, it highlights as a keyword in Emacs,
and I think it's nicer to just avoid it.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32660
Some Debug Adapter Protocol clients like Helix set the optional
"arguments" field of the ConfigurationDone request to null, which is a
bit odd but seems to be allowed by the protocol specification. Before
this patch, Python exceptions would be raised on such requests. This
patch makes it so these requests are treated as if the "arguments"
field was absent.
This changes DAP to ignore the case where a pretty-printer returns a
negative number from the num_children method. It didn't seem worth
writing a test case for this.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33594
Reviewed-By: Ciaran Woodward <ciaranwoodward@xmos.com>