Remove the frame_object::frame_id_is_next field. This has been part
of how Python handles frames since this code was first added in commit
f8f6f20b6e back in 2009. The motivation
for this field can be found in a couple of comments, there's this one
on frame_id_is_next:
/* Marks that the FRAME_ID member actually holds the ID of the frame next
to this, and not this frames' ID itself. This is a hack to permit Python
frame objects which represent invalid frames (i.e., the last frame_info
in a corrupt stack). The problem arises from the fact that this code
relies on FRAME_ID to uniquely identify a frame, which is not always true
for the last "frame" in a corrupt stack (it can have a null ID, or the same
ID as the previous frame). Whenever get_prev_frame returns NULL, we
record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
And this one in frame_info_to_frame_object:
/* Try to get the previous frame, to determine if this is the last frame
in a corrupt stack. If so, we need to store the frame_id of the next
frame and not of this one (which is possibly invalid). */
This field is dealing with a problem that was present in older
versions of GDB where not every stack frame had a valid frame-id, if
the stack was corrupted in some way then the last frame might have an
invalid frame-id. However, that is no longer the case. With current
GDB there is a promise that every frame has a valid frame-id. I don't
have a single commit to point to where this became the reality, but it
is my understanding of current GDB.
As an example, the frame-id of every frame (except #0) is computed as
the frame is created, any frames with a duplicate frame-id, or any
errors during computation of the frame-id, and the new frame is
discarded.
Additionally, our frame_info_ptr::reinflate mechanism relies on unique
and valid frame-ids.
The problem with the existing code is that the last frame in a
corrupted stack will hold the frame-id of the next frame, that is, the
more inner frame. This means we have two frames holding the same
frame-id, and the only difference is the frame_id_is_next flag.
However, the frapy_str function, which prints a string representation
of the frame, doesn't take frame_id_is_next into account, so printing
the last two frames in a corrupted stack, will print the same
frame-id.
We could fix this in frapy_str and also frapy_repr by checking the
frame_id_is_next flag and then fetching the previous frame-id, but
this would still assume that the previous frame has a valid-id, so we
might as well just drop the frame_id_is_next flag and make everything
simpler.
There's a new test which exposes the incorrectly printed frame-id
problem.
While testing I needed to "fix" the results for two existing tests.
In frame_info_to_frame_object, in order to figure out if we should use
the next frame, we called get_prev_frame. This would cause GDB to
always unwind 1 extra level of the stack.
What this means is that, if there is an error, or some diagnostic
output, when unwinding frame #1, then this will show up when trying to
access frame #0 via the Python API as frame_info_to_frame_object on
frame #0 would call get_prev_frame, which would then unwind frame #1.
After this commit this is no longer the case. We only see
output (either errors, or diagnostic output) associated with frame #1
when we actually try to unwind to frame #1. The two tests that needed
updating were expecting output associated with frame #1 while printing
frame #0. This is now fixed and the output for frame #1 occurs later
on. I think this is an improvement.
The current implementation of gdb_py_tp_name() leaks a reference to the
object returned by PyType_GetFullyQualifiedName() for Python >= 3.13, and
PyType_GetQualName() for Python >= 3.11.
Managing the strong reference on the returned PyObject* with a gdbpy_ref<>
fixes the reference count, but also causes the temporary object to be
deallocated on function exit. As a consequence, the 'const char *' returned
by PyUnicode_AsUTF8AndSize() becomes dangling and can no longer safely be
returned.
The proposed approach consists in changing gdb_py_tp_name() to return a
std::string, and forcing a copy of the 'const char *' value, statically
or dynamically allocated, stored in a temporary or non-temporary PyObject,
depending on the version of Python it was compiled with.
An unfortunate side effect of this fix is that every call sites where the
tp_name is printed, must now use `.c_str()' because PyErr_Format()
and its siblings cannot handle std::string.
Approved-By: Andrew Burgess <aburgess@redhat.com>
All of our custom Python types are created as structs, like this:
struct some_new_type : public PyObject
{
... various fields ...
};
Then instances of this struct are created by calling PyObject_New,
either directly within GDB's C++ code, or within Python when a user's
Python script creates an instance of that class.
The problem is that Python is written in C, and PyObject_New doesn't
call any constructors for `some_new_type`, nor for any of the fields
within `some_new_type`.
If `some_new_type` is Plain Old Data (POD), then this is fine. Or, to
be more C++ specific, if `some_new_type` is trivially default
constructable, then we're fine.
But if a field within `some_new_type` has a non-trivial constructor,
then we're in trouble as that constructor will never be run.
An example of a problematic field type is frame_info_ptr. The
constructor for this type registers the new object with a central
management object, recording the `this` pointer, using this type within
`some_new_type` will not work as expected; frame invalidation will not
show up within the frame_info_ptr as you might expect.
And so, this type trait exists. Whenever a struct is created to define
a new Python type we should add a line like:
static_assert (gdb::is_python_allocatable_v<some_new_type>);
This will fail if any field of `some_new_type` are unsuitable for this
use.
We don't actually check is_trivially_default_constructible here. Some
types, e.g. ui_file_style::color, have non-trivial (or no default)
constructors, but are still safe to use within `some_new_type` because
their constructors just initialise data fields; there's nothing
"special" that the constructor does that cannot be achieved by
assigning the fields after creation with PyObject_New.
What actually matters is that the type is trivially destructible
(Python won't call C++ destructors, so destructors with side effects,
like deregistering from a list, would be skipped) and trivially
copyable (Python may copy objects with memcpy). Types like
frame_info_ptr, whose constructors and destructors have side effects
such as registering with a central management object, will be caught
because they are neither trivially destructible nor trivially copyable.
Simple POD types like ui_file_style are trivially destructible and
copyable, so pass this trait.
This commit adds the new type trait, and makes use of it in all cases
but one, pending_frame_object in python/py-unwind.c, has a field of
type frame_info_ptr, which is currently broken. This will be fixed,
and the static_assert added, in the next commit.
Approved-By: Tom Tromey <tom@tromey.com>
Result of:
...
$ sed -i 's/Py_RETURN_NONE/return py_none ().release ()/' gdb/python/*.{c,h}
...
with the changes in py_none reverted.
Likewise for Py_RETURN_TRUE,Py_RETURN_FALSE and Py_RETURN_NOTIMPLEMENTED.
Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34145
Py_TYPE (self)->tp_name is the traditional idiomatic way to get a Python
type's fully qualified name. However, in the context of the Python
limited API, PyTypeObject is opaque, so the 'tp_name' attribute is no
longer accessible. Additionally, retrieving the type of a Python object
requires Py_TYPE, which is only available as part of the stable API
starting with Python 3.14.
This patch increases minimal Python limited API version from 3.11 to 3.14.
It also introduces two new helpers to retrieve a type's fully qualified
name: gdb_py_tp_name() and gdbpy_py_obj_tp_name(), which extract the fully
qualified name from a PyTypeObject and a PyObject, respectively. Ifdefery
allows these wrappers to select the appropriate API depending on the Python
version and whether the Python limited API is enabled. For any Python
version less than 3.13, gdb_py_tp_name() fallbacks using __qualname__
instead. However, the result may differ slightly in some cases, e.g. the
module name may be missing.
Finally, this patch adapts the existing code to use these wrappers, and
adjusts some test expectations to use the fully qualified name (or
__qualname__ for versions <= 3.13) where it was not previously used.
Note that the corner case where the module name would be missing does not
appear in the testsuite.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
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>
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 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 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 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 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>
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>
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.
The GCC plugin that implements the Python API checker does not appear
to really be maintained. And, as far as I know, it never really
worked for C++ code anyway. Considering those factors, and that no
one has tried to run it in years, I think it's time to remove the
macros from the gdb source.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This updates the copyright headers to include 2025. I did this by
running gdb/copyright.py and then manually modifying a few files as
noted by the script.
Approved-By: Eli Zaretskii <eliz@gnu.org>
Result of:
...
$ search="GDB_PY_HANDLE_EXCEPTION ("
$ replace="return gdbpy_handle_gdb_exception (nullptr, "
$ sed -i \
"s/$search/$replace/" \
gdb/python/*.c
...
Also remove the now unused GDB_PY_HANDLE_EXCEPTION.
No functional changes.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR python/32163 points out that various types provided by gdb are not
added to the gdb module, so they aren't available for interactive
inspection. I think this is just an oversight.
This patch fixes the problem by introducing a new helper function that
both readies the type and then adds it to the appropriate module. The
patch also poisons PyType_Ready, the idea being to avoid this bug in
the future.
v2:
* Fixed a bug in original patch in gdb.Architecture registration
* Added regression test for the types mentioned in the bug
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32163
Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
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>
We currently pass frames to function by value, as `frame_info_ptr`.
This is somewhat expensive:
- the size of `frame_info_ptr` is 64 bytes, which is a bit big to pass
by value
- the constructors and destructor link/unlink the object in the global
`frame_info_ptr::frame_list` list. This is an `intrusive_list`, so
it's not so bad: it's just assigning a few points, there's no memory
allocation as if it was `std::list`, but still it's useless to do
that over and over.
As suggested by Tom Tromey, change many function signatures to accept
`const frame_info_ptr &` instead of `frame_info_ptr`.
Some functions reassign their `frame_info_ptr` parameter, like:
void
the_func (frame_info_ptr frame)
{
for (; frame != nullptr; frame = get_prev_frame (frame))
{
...
}
}
I wondered what to do about them, do I leave them as-is or change them
(and need to introduce a separate local variable that can be
re-assigned). I opted for the later for consistency. It might not be
clear why some functions take `const frame_info_ptr &` while others take
`frame_info_ptr`. Also, if a function took a `frame_info_ptr` because
it did re-assign its parameter, I doubt that we would think to change it
to `const frame_info_ptr &` should the implementation change such that
it doesn't need to take `frame_info_ptr` anymore. It seems better to
have a simple rule and apply it everywhere.
Change-Id: I59d10addef687d157f82ccf4d54f5dde9a963fd0
Approved-By: Andrew Burgess <aburgess@redhat.com>
This changes lookup_symbol and associated APIs to accept
domain_search_flags rather than a domain_enum.
Note that this introduces some new constants to Python and Guile. I
chose to break out the documentation patch for this, because the
internals here do not change until a later patch, and it seemed
simpler to patch the docs just once, rather than twice.
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
Add a gdb.Frame.__repr__() method. Before this patch we would see
output like this:
(gdb) pi
>>> gdb.selected_frame()
<gdb.Frame object at 0x7fa8cc2df270>
After this patch, we now see:
(gdb) pi
>>> gdb.selected_frame()
<gdb.Frame level=0 frame-id={stack=0x7ffff7da0ed0,code=0x000000000040115d,!special}>
More verbose, but, I hope, more useful.
If the gdb.Frame becomes invalid, then we will see:
(gdb) pi
>>> invalid_frame_variable
<gdb.Frame (invalid)>
which is inline with how other invalid objects are displayed.
Approved-By: Tom Tromey <tom@tromey.com>
Some functions related to the handling of registers in frames accept
"this frame", for which we want to read or write the register values,
while other functions accept "the next frame", which is the frame next
to that. The later is needed because we sometimes need to read register
values for a frame that does not exist yet (usually when trying to
unwind that frame-to-be).
value_of_register and value_of_register_lazy both take "this frame",
even if what they ultimately want internally is "the next frame". This
is annoying if you are in a spot that currently has "the next frame" and
need to call one of these functions (which happens later in this
series). You need to get the previous frame only for those functions to
get the next frame again. This is more manipulations, more chances of
mistake.
I propose to change these functions (and a few more functions in the
subsequent patches) to operate on "the next frame". Things become a bit
less awkward when all these functions agree on which frame they take.
So, in this patch, change value_of_register_lazy and value_of_register
to take "the next frame" instead of "this frame". This adds a lot of
get_next_frame_sentinel_okay, but if we convert the user registers API
to also use "the next frame" instead of "this frame", it will get simple
again.
Change-Id: Iaa24815e648fbe5ae3c214c738758890a91819cd
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
This adds a new gdb.Frame.static_link method to the gdb Python layer.
This can be used to find the static link frame for a given frame.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Currently, when we add a new python sub-system to GDB,
e.g. py-inferior.c, we end up having to create a new function like
gdbpy_initialize_inferior, which then has to be called from the
function do_start_initialization in python.c.
In some cases (py-micmd.c and py-tui.c), we have two functions
gdbpy_initialize_*, and gdbpy_finalize_*, with the second being called
from finalize_python which is also in python.c.
This commit proposes a mechanism to manage these initialization and
finalization calls, this means that adding a new Python subsystem will
no longer require changes to python.c or python-internal.h, instead,
the initialization and finalization functions will be registered
directly from the sub-system file, e.g. py-inferior.c, or py-micmd.c.
The initialization and finalization functions are managed through a
new class gdbpy_initialize_file in python-internal.h. This class
contains a single global vector of all the initialization and
finalization functions.
In each Python sub-system we create a new gdbpy_initialize_file
object, the object constructor takes care of registering the two
callback functions.
Now from python.c we can call static functions on the
gdbpy_initialize_file class which take care of walking the callback
list and invoking each callback in turn.
To slightly simplify the Python sub-system files I added a new macro
GDBPY_INITIALIZE_FILE, which hides the need to create an object. We
can now just do this:
GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers);
One possible problem with this change is that there is now no
guaranteed ordering of how the various sub-systems are initialized (or
finalized). To try and avoid dependencies creeping in I have added a
use of the environment variable GDB_REVERSE_INIT_FUNCTIONS, this is
the same environment variable used in the generated init.c file.
Just like with init.c, when this environment variable is set we
reverse the list of Python initialization (and finalization)
functions. As there is already a test that starts GDB with the
environment variable set then this should offer some level of
protection against dependencies creeping in - though for full
protection I guess we'd need to run all gdb.python/*.exp tests with
the variable set.
I have tested this patch with the environment variable set, and saw no
regressions, so I think we are fine right now.
One other change of note was for gdbpy_initialize_gdb_readline, this
function previously returned void. In order to make this function
have the correct signature I've updated its return type to int, and we
now return 0 to indicate success.
All of the other initialize (and finalize) functions have been made
static within their respective sub-system files.
There should be no user visible changes after this commit.
This commit allows Frame.read_var to accept named arguments, and also
improves (I think) some of the error messages emitted when values of
the wrong type are passed to this function.
The read_var method takes two arguments, one a variable, which is
either a gdb.Symbol or a string, while the second, optional, argument
is always a gdb.Block.
I'm now using 'O!' as the format specifier for the second argument,
which allows the argument type to be checked early on. Currently, if
the second argument is of the wrong type then we get this error:
(gdb) python print(gdb.selected_frame().read_var("a1", "xxx"))
Traceback (most recent call last):
File "<string>", line 1, in <module>
RuntimeError: Second argument must be block.
Error while executing Python code.
(gdb)
After this commit, we now get an error like this:
(gdb) python print(gdb.selected_frame().read_var("a1", "xxx"))
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: argument 2 must be gdb.Block, not str
Error while executing Python code.
(gdb)
Changes are:
1. Exception type is TypeError not RuntimeError, this is unfortunate
as user code _could_ be relying on this, but I think the improvement
is worth the risk, user code relying on the exact exception type is
likely to be pretty rare,
2. New error message gives argument position and expected argument
type, as well as the type that was passed.
If the first argument, the variable, has the wrong type then the
previous exception was already a TypeError, however, I've updated the
text of the exception to more closely match the "standard" error
message we see above. If the first argument has the wrong type then
before this commit we saw this:
(gdb) python print(gdb.selected_frame().read_var(123))
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: Argument must be a symbol or string.
Error while executing Python code.
(gdb)
And after we see this:
(gdb) python print(gdb.selected_frame().read_var(123))
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: argument 1 must be gdb.Symbol or str, not int
Error while executing Python code.
(gdb)
For existing code that doesn't use named arguments and doesn't rely on
exceptions, there will be no changes after this commit.
Reviewed-By: Tom Tromey <tom@tromey.com>
Following on from the previous commit, this updates
Frame.read_register to accept named arguments. As with the previous
commit there's no huge benefit for the users in accepting named
arguments here -- this function only takes a single argument after
all.
But I do think it is worth keeping Frame.read_register method in sync
with the PendingFrame.read_register method, this allows for the
possibility that the user has some code that can operate on either a
Frame or a Pending frame.
Minor update to allow for named arguments, and an extra test to check
the new functionality.
Reviewed-By: Tom Tromey <tom@tromey.com>
Spotted a redundant nullptr check in python/py-frame.c in the function
frapy_block. This was introduced in commit 57126e4a45 when we
expanded an earlier check in return early if the pointer in question
is nullptr.
There should be no user visible changes after this commit.
Reviewed-By: Tom Tromey <tom@tromey.com>
Hannes filed a bug showing a crash, where a pretty-printer written in
Python could cause a use-after-free. He sent a patch, but I thought a
different approach was needed.
In a much earlier patch (see bug #12533), we changed the Python code
to release new values from the value chain when constructing a
gdb.Value. The rationale for this is that if you write a command that
does a lot of computations in a loop, all the values will be kept live
by the value chain, resulting in gdb using a large amount of memory.
However, suppose a value is passed to Python from some code in gdb
that needs to use the value after the call into Python. In this
scenario, value_to_value_object will still release the value -- and
because gdb code doesn't generally keep strong references to values (a
consequence of the ancient decision to use the value chain to avoid
memory management), this will result in a use-after-free.
This scenario can happen, as it turns out, when a value is passed to
Python for pretty-printing. Now, normally this route boxes the value
via value_to_value_object_no_release, avoiding the problematic release
from the value chain. However, if you then call Value.cast, the
underlying value API might return the same value, when is then
released from the chain.
This patch fixes the problem by changing how value boxing is done.
value_to_value_object no longer removes a value from the chain.
Instead, every spot in gdb that might construct new values uses a
scoped_value_mark to ensure that the requirements of bug #12533 are
met. And, because incoming values aren't ever released from the chain
(the Value.cast one comes earlier on the chain than the
scoped_value_mark), the bug can no longer occur. (Note that many
spots in the Python layer already take this approach, so not many
places needed to be touched.)
In the future I think we should replace the use of raw "value *" with
value_ref_ptr pretty much everywhere. This will ensure lifetime
safety throughout gdb.
The test case in this patch comes from Hannes' original patch. I only
made a trivial ("require") change to it. However, while this fails
for him, I can't make it fail on this machine; nevertheless, he tried
my patch and reported the bug as being fixed.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30044
This helps resolve some cyclic include problem later in the series.
The only language-related thing frame.h needs is enum language, and that
is in defs.h.
Doing so reveals that a bunch of files were relying on frame.h to
include language.h, so fix the fallouts here and there.
Change-Id: I178a7efec1953c2d088adb58483bade1f349b705
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
This replaces frame_id_eq with operator== and operator!=. I wrote
this for a version of this series that I later abandoned; but since it
simplifies the code, I left this patch in.
Approved-by: Tom Tomey <tom@tromey.com>
I noticed that gdbpy_parse_register_id would assert if passed a Python
object of a type it was not expecting. The included test case shows
this crash. This patch fixes the problem and also changes
gdbpy_parse_register_id to be more "Python-like" -- it always ensures
the Python error is set when it fails, and the callers now simply
propagate the existing exception.
This adds the gdb.current_language function, which can be used to find
the current language without (1) ever having the value "auto" or (2)
having to parse the output of "show language".
It also adds the gdb.Frame.language, which can be used to find the
language of a given frame. This is normally preferable if one has a
Frame object handy.
New in this version:
- Rebase on master, fix a few more issues that appeared.
python-internal.h contains a number of macros that helped make the code
work with both Python 2 and 3. Remove them and adjust the code to use
the Python 3 functions.
Change-Id: I99a3d80067fb2d65de4f69f6473ba6ffd16efb2d
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.
For the avoidance of doubt, all changes in this commits were
performed by the script.
Add new methods to the PendingFrame and Frame classes to obtain the
stack frame level for each object.
The use of 'level' as the method name is consistent with the existing
attribute RecordFunctionSegment.level (though this is an attribute
rather than a method).
For Frame/PendingFrame I went with methods as these classes currently
only use methods, including for simple data like architecture, so I
want to be consistent with this interface.
gdb/ChangeLog:
* NEWS: Mention the two new methods.
* python/py-frame.c (frapy_level): New function.
(frame_object_methods): Register 'level' method.
* python/py-unwind.c (pending_framepy_level): New function.
(pending_frame_object_methods): Register 'level' method.
gdb/doc/ChangeLog:
* python.texi (Unwinding Frames in Python): Mention
PendingFrame.level.
(Frames In Python): Mention Frame.level.
gdb/testsuite/ChangeLog:
* gdb.python/py-frame.exp: Add Frame.level tests.
* gdb.python/py-pending-frame-level.c: New file.
* gdb.python/py-pending-frame-level.exp: New file.
* gdb.python/py-pending-frame-level.py: New file.
Replace fprint_frame_id with a member function frame_id::to_string
that returns a std::string. Convert all of the previous users of
fprint_frame_id to use the new member function. This means that
instead of writing things like this:
fprintf_unfiltered (file, " id=");
fprint_frame_id (file, s->id.id);
We can write this:
fprintf_unfiltered (file, " id=%s", s->id.id.to_string ().c_str ());
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dummy-frame.c (fprint_dummy_frames): Convert use of
fprint_frame_id to use frame_id::to_string.
* frame.c (fprint_field): Delete.
(fprint_frame_id): Moved to...
(frame_id::to_string): ...this, rewritten to return a string.
(fprint_frame): Convert use of fprint_frame_id to use
frame_id::to_string.
(compute_frame_id): Likewise.
(frame_id_p): Likewise.
(frame_id_eq): Likewise.
(frame_id_inner): Likewise.
* frame.h (struct frame_id) <to_string>: New member function.
(fprint_frame_id): Delete declaration.
* guile/scm-frame.c (frscm_print_frame_smob): Convert use of
fprint_frame_id to use frame_id::to_string.
* python/py-frame.c (frame_object_to_frame_info): Likewise.
* python/py-unwind.c (unwind_infopy_str): Likewise.
(pyuw_this_id): Likewise.
The last frame in a corrupt stack stores the frame_id of the next frame,
so these two frames currently compare as equal.
So if you have a backtrace where the oldest frame is corrupt, this happens:
(gdb) py
>f = gdb.selected_frame()
>while f.older():
> f = f.older()
>print(f == f.newer())
>end
True
With this change, that same example returns False.
gdb/ChangeLog:
2021-02-07 Hannes Domani <ssbssa@yahoo.de>
* python/py-frame.c (frapy_richcompare): Compare frame_id_is_next.
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.