aboutsummaryrefslogtreecommitdiff
path: root/gdb/python/python-internal.h
AgeCommit message (Collapse)AuthorFilesLines
2026-02-23Return gdbpy_ref<> from gdbpy_registry::lookupTom Tromey1-4/+3
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>
2026-02-23Return gdbpy_ref<> from gdbarch_to_arch_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from symtab_to_linetable_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from frame_info_to_frame_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from type_to_type_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from value_to_value_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from block_to_block_objectTom Tromey1-2/+2
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>
2026-02-23Return gdbpy_ref<> from symtab_to_symtab_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from symbol_to_symbol_objectTom Tromey1-1/+1
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>
2026-02-23Return gdbpy_ref<> from symtab_and_line_to_sal_objectTom Tromey1-1/+1
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>
2026-02-09gdb/registry: add registry::key::try_emplaceSimon Marchi1-7/+1
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>
2026-01-29gdb: cast all Python extension objects passed to gdbpy_ref_policy to PyObject*Matthieu Longo1-3/+1
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>
2026-01-29gdb: new setters and getters for __dict__, and attributesMatthieu Longo1-9/+25
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>
2026-01-29gdbpy_registry: cast C extension type object to PyObject * before Py_XINCREFMatthieu Longo1-1/+4
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>
2026-01-28Python limited API: migrate Py_CompileStringExFlags and PyRun_SimpleStringMatthieu Longo1-0/+3
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>
2026-01-05Update copyright dates to include 2026Tom Tromey1-1/+1
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.
2025-12-18Don't use "module" nameTom Tromey1-1/+1
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
2025-11-26gdb: fix some whitespace issuesSimon Marchi1-4/+4
Replace 8 spaces with a tab. Change-Id: Ie8f942ce4b4ba4a83c2ee83cb904153b2e58cf8c
2025-10-23Remove Python API checker definesTom Tromey1-48/+10
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>
2025-10-23Remove Py_TPFLAGS_CHECKTYPESTom Tromey1-2/+0
According to 'git annotate', the Py_TPFLAGS_CHECKTYPES was added to python-internal.h way back when gdb was first ported to Python 3. It was a compatibility fix for Python 2. This is not needed any more, because Python 2 is no longer supported. This patch removes the vestiges. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-10-20gdb, gdbserver, gdbsupport: trim trailing whitespacesSimon Marchi1-12/+12
I noticed my IDE (VSCode) starting to automatically trim trailing whitespaces on save, despite the setting for it being disabled. I realized that this is because the .editorconfig file now has trim_trailing_whitespace = true for many file types. If we have this EditorConfig setting forcing editors to trim trailing whitespaces, I think it would make sense to clean up trailing whitespaces from our files. Otherwise, people will always get spurious whitespace changes when editing these files. I did a mass cleanup using this command: $ find gdb gdbserver gdbsupport -type f \( \ -name "*.c" -o \ -name "*.h" -o \ -name "*.cc" -o \ -name "*.texi" -o \ -name "*.exp" -o \ -name "*.tcl" -o \ -name "*.py" -o \ -name "*.s" -o \ -name "*.S" -o \ -name "*.asm" -o \ -name "*.awk" -o \ -name "*.ac" -o \ -name "Makefile*" -o \ -name "*.sh" -o \ -name "*.adb" -o \ -name "*.ads" -o \ -name "*.d" -o \ -name "*.go" -o \ -name "*.F90" -o \ -name "*.f90" \ \) -exec sed -ri 's/[ \t]+$//' {} + I then did an autotools regen, because we don't actually want to change the Makefile and Makefile.in files that are generated. Change-Id: I6f91b83e3b8c4dc7d5d51a2ebf60706120efe691
2025-10-06gdb/python: introduce gdb.Corefile APIAndrew Burgess1-0/+8
This commit starts adding some core file related features to the Python API. In this initial commit I've tried to keep the changes as small as possible for easy review. There's a new Python class gdb.Corefile, which represents a loaded core file. This API doesn't allow the user to create their own gdb.Corefile objects, a core file must be loaded using the 'core-file' command, then a gdb.Corefile object can be obtained by querying the inferior in which the core file was loaded. There's a new attribute gdb.Inferior.corefile, this is None when no core file is loaded, or contains a gdb.Corefile object if a core file has been loaded. Currently, the gdb.Corefile object has one attribute, and one method, these are: gdb.Corefile.filename -- the file name of the loaded core file. gdb.Corefile.is_valid() -- indicates if a gdb.Corefile object is valid or not. See notes below. A gdb.Corefile object is only valid while the corresponding core file is loaded into an inferior. Unloading the core file, or loading a different one will cause a gdb.Corefile object to become invalid. For example: (gdb) core-file /tmp/core.54313 ... snip ... (gdb) python core=gdb.selected_inferior().corefile (gdb) python print(core) <gdb.Corefile inferior=1 filename='/tmp/core.54313'> (gdb) python print(core.is_valid()) True (gdb) core-file No core file now. (gdb) python print(core) <gdb.Corefile (invalid)> (gdb) python print(core.is_valid()) False (gdb) In order to track changes to the core file, there is a new observable 'core_file_changed', which accounts for the changes in corelow.c, observable,c, and observable.h. Currently, this observable is not visible as a Python event. I chose to access the core file via the inferior even though the core file BFD object is actually stored within the program_space. As such, it might seem that the natural choice would be to add the attribute as gdb.Progspace.corefile. For background reading on my choice, please see: https://inbox.sourceware.org/gdb-patches/577f2c47793acb501c2611c0e6c7ea379f774830.1668789658.git.aburgess@redhat.com This patch was never merged, it is still on my backlog, but the observation in that work is that some targets are not really shareable. For example, the core_target (corelow.c) stores information about the loaded core file within the target instance. As such, each target instance represents a single loaded core file. Except that the BFD part of the core file is stored in the program_space, which is a little weird. During review, Tom made the observation, that maybe we should investigate moving the core file BFD into the core_target. I'm inclined to agree with this as a direction of travel. All this leaves us with two observations: 1. Currently, loading a core file into an inferior, then using 'add-inferior' will try to share the core_target between inferiors. This is broken, and can trigger GDB crashes. The obvious fix, without reworking core_target, is just to prevent this sharing, making core_target per-inferior. 2. Having the core file information split between the core_target instance, and the BFD stored in the program_space is a little weird, and is really just historical. Planning for a future where the BFD is also stored in the core_target might be wise. So, if we imagine that the BFD is (one day) moved into the core_target, and that the core_target really becomes non-shareable, then it is, I think, clearer that the corefile attribute should live on the gdb.Inferior object, not the gdb.Progspace object. There's testing for all the functionality added in this commit. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32844 Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2025-10-05gdb/python: extend gdb.write to support styled outputAndrew Burgess1-0/+14
It is already possible to produce styled output from Python by converting the gdb.Style to its escape code sequence, and writing that to the output stream. But this commit adds an alternative option to the mix by extending the existing gdb.write() function to accept a 'style' argument. The value of this argument can be 'None' to indicate no style change should be performed, this is the default, and matches the existing behaviour. Or the new 'style' argument can be a gdb.Style object, in which case the specified style is applied only for the string passed to gdb.write, after which the default style is re-applied. Using gdb.write with a style object more closely matches how GDB handles styling internally, and has the benefit that the user doesn't need to remember to restore the default style when they are done. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
2025-08-26gdb/python: return gdbpy_ref<> from gdbpy_create_ptid_objectAndrew Burgess1-1/+6
Update gdbpy_create_ptid_object (python/py-infthread.c) to return a gdbpy_ref<> rather than a 'PyObject *'. This reduces the chances that a caller will leak an object, though no such memory leaks are fixed in this commit, this is just a code improvement patch. There should be no user visible changes after this commit. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-06-04gdb/python/guile: fix segfault from nested prefix command creationAndrew Burgess1-1/+2
A commit I recently pushed: commit 0b5023cc71d3af8b18e10e6599a3f9381bc15265 Date: Sat Apr 12 09:15:53 2025 +0100 gdb/python/guile: user created prefix commands get help list can trigger a segfault if a user tries to create nested prefix commands. For example, this will trigger a crash: (gdb) python gdb.ParameterPrefix("prefix-1", gdb.COMMAND_NONE) (gdb) python gdb.ParameterPrefix("prefix-1 prefix-2", gdb.COMMAND_NONE) Fatal signal: Segmentation fault ... etc ... If the user adds an actual parameter under 'prefix-1' before creating 'prefix-2', then everything is fine: (gdb) python gdb.ParameterPrefix("prefix-1", gdb.COMMAND_NONE) (gdb) python gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) (gdb) python gdb.ParameterPrefix("prefix-1 prefix-2", gdb.COMMAND_NONE) The mistake in the above patch is in how gdbpy_parse_command_name is used. The BASE_LIST output argument from this function points to the list of commands for the prefix, not to the prefix command itself. So when gdbpy_parse_command_name is called for 'prefix-1 prefix-2', BASE_LIST points to the list of commands associated with 'prefix-1', not to the actual 'prefix-1' cmd_list_element. Back in cmdpy_init, from where gdbpy_parse_command_name was called, I was walking back from the first entry in BASE_LIST to figure out if this was a "show" prefix command or not. However, if BASE_LIST is empty then there is no first item, and this would trigger the segfault. The solution it to extend gdbpy_parse_command_name to also return the prefix cmd_list_element in addition to the existing values. With this done, and cmdpy_init updated, the segfault is now avoided. There's a new test that would trigger the crash without the patch. And, of course, the above commit also broke guile in the exact same way. And the fix is exactly the same. And there's a guile test too. NOTE: We should investigate possibly sharing some of this boiler plate helper code between Python and Guile. But not in this commit. Approved-By: Tom Tromey <tom@tromey.com>
2025-05-30Require Python 3.4Tom Tromey1-11/+2
I believe we previously agreed that the minimum supported Python version should be 3.4. This patch makes this change, harmonizing the documentation (which was inconsistent about the minimum version) and the code. New in v2: rebased, and removed a pre-3.4 workaround from __init__.py. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-by: Kevin Buettner <kevinb@redhat.com> Acked-By: Tom de Vries <tdevries@suse.de> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31870
2025-04-08Update copyright dates to include 2025Tom Tromey1-1/+1
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>
2025-03-20[gdb/build] Fix build with gcc 9Tom de Vries1-1/+1
Since commit a691853148f ("gdb/python: introduce gdbpy_registry"), when building gdb with gcc 9, I run into: ... In file included from gdb/varobj.c:38:0: gdb/python/python-internal.h:1211:47: error: expected ‘;’ before ‘<’ token using StorageKey = typename registry<O>::key<Storage>; ^ ... due to this code: ... template <typename Storage> class gdbpy_registry { ... template<typename O> using StorageKey = typename registry<O>::key<Storage>; template<typename O> Storage *get_storage (O *owner, const StorageKey<O> &key) const { ... } ... } ... As an experiment, I tried out eliminating the type alias: ... template<typename O> Storage *get_storage (O *owner, const typename registry<O>::key<Storage> &key) const { ... } ... and got instead: ... In file included from gdb/varobj.c:38:0: gdb/python/python-internal.h:1211:63: error: non-template ‘key’ used as template Storage *get_storage (O *owner, const typename registry<O>::key<Storage> &key) const ^~~ gdb/python/python-internal.h:1211:63: note: use ‘registry<O>::template key’ \ to indicate that it is a template ... Following that suggestion, I tried: ... template<typename O> Storage * get_storage (O *owner, const typename registry<O>::template key<Storage> &key) const { ... } ... which fixed the problem. Likewise, adding the template keyword in the type alias fixes the original problem, so fix it like that. Tested on x86_64-linux.
2025-03-19gdb/python: introduce gdbpy_registryJan Vrany1-0/+195
This commit introduces new template class gdbpy_registry to simplify Python object lifecycle management. As of now, each of the Python object implementations contain its own (copy of) lifecycle management code that is largely very similar. The aim of gdbpy_registry is to factor out this code into a common (template) class in order to simplify the code. Approved-By: Tom Tromey <tom@tromey.com>
2024-12-18Run check-include-guards.pyTom Tromey1-3/+3
This patch is the result of running check-include-guards.py on the current tree. Running it a second time causes no changes. Reviewed-By: Tom de Vries <tdevries@suse.de>
2024-11-25Convert type copying to new hash tableSimon Marchi1-1/+1
This converts the type copying code to use the new hash map. Change-Id: I35f0a4946dcc5c5eb84820126cf716b600f3302f Co-Authored-By: Tom Tromey <tom@tromey.com> Approved-By: Tom Tromey <tom@tromey.com>
2024-09-24[gdb/python] Eliminate GDB_PY_SET_HANDLE_EXCEPTIONTom de Vries1-7/+0
Result of: ... $ search="GDB_PY_SET_HANDLE_EXCEPTION (" $ replace="return gdbpy_handle_gdb_exception (-1, " $ sed -i \ "s/$search/$replace/" \ gdb/python/*.c ... Also remove the now unused GDB_PY_SET_HANDLE_EXCEPTION. No functional changes. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-09-24[gdb/python] Eliminate GDB_PY_HANDLE_EXCEPTIONTom de Vries1-7/+0
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>
2024-09-24[gdb/python] Add gdbpy_handle_gdb_exceptionTom de Vries1-9/+19
I've recently committed two patches: - commit 2f8cd40c37a ("[gdb/python] Use GDB_PY_HANDLE_EXCEPTION more often") - commit fbf8e4c35c2 ("[gdb/python] Use GDB_PY_SET_HANDLE_EXCEPTION more often") which use the macros GDB_PY_HANDLE_EXCEPTION and GDB_PY_SET_HANDLE_EXCEPTION more often, with the goal of making things more consistent. Having done that, I wondered if a better approach could be possible. Consider GDB_PY_HANDLE_EXCEPTION: ... /* Use this in a 'catch' block to convert the exception to a Python exception and return nullptr. */ #define GDB_PY_HANDLE_EXCEPTION(Exception) \ do { \ gdbpy_convert_exception (Exception); \ return nullptr; \ } while (0) ... The macro nicely codifies how python handles exceptions: - setting an error condition using some PyErr_Set* variant, and - returning a value implying that something went wrong presumably with the goal that using the macro will mean not accidentally: - forgetting to return on error, or - returning the wrong value on error. The problems are that: - the macro hides control flow, specifically the return statement, and - the macro hides the return value. For example, when reading somewhere: ... catch (const gdb_exception &except) { GDB_PY_HANDLE_EXCEPTION (except); } ... in order to understand what this does, you have to know that the macro returns, and that it returns nullptr. Add a template gdbpy_handle_gdb_exception: ... template<typename T> [[nodiscard]] T gdbpy_handle_gdb_exception (T val, const gdb_exception &e) { gdbpy_convert_exception (e); return val; } ... which can be used instead: ... catch (const gdb_exception &except) { return gdbpy_handle_gdb_exception (nullptr, except); } ... [ Initially I tried this: ... template<auto val> [[nodiscard]] auto gdbpy_handle_gdb_exception (const gdb_exception &e) { gdbpy_convert_exception (e); return val; } ... with which the usage is slightly better looking: ... catch (const gdb_exception &except) { return gdbpy_handle_gdb_exception<nullptr> (except); } ... but I ran into trouble with older gcc compilers. ] While still a single statement, we now have it clear: - that the statement returns, - what value the statement returns. [ FWIW, this could also be handled by say: ... - GDB_PY_HANDLE_EXCEPTION (except); + GDB_PY_HANDLE_EXCEPTION_AND_RETURN_VAL (except, nullptr); ... but I still didn't find the fact that it returns easy to spot. Alternatively, this is the simplest form we could use: ... return gdbpy_convert_exception (e), nullptr; ... but the pairing would not necessarily survive a copy/paste/edit cycle. ] Also note how making the value explicit makes it easier to check for consistency: ... catch (const gdb_exception &except) { return gdbpy_handle_gdb_exception (-1, except); } if (PyErr_Occurred ()) return -1; ... given that we do use the explicit constants almost everywhere else. Compared to using GDB_PY_HANDLE_EXCEPTION, there is the burden now to specify the return value, but I assume that this will be generally copy-pasted and therefore present no problem. Also, there's no longer a guarantee that there's an immediate return, but I assume that nodiscard making sure that the return value is not silently ignored is sufficient mitigation. For now, re-implement GDB_PY_HANDLE_EXCEPTION and GDB_PY_SET_HANDLE_EXCEPTION in terms of gdbpy_handle_gdb_exception. Follow-up patches will eliminate the macros. No functional changes. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
2024-09-23Automatically add types to Python modulesTom Tromey1-0/+30
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>
2024-08-14btrace, python: Enable ptwrite filter registration.Felix Willgerodt1-0/+3
By default GDB will be printing the hex payload of the ptwrite package as auxiliary information. To customize this, the user can register a ptwrite filter function in python, that takes the payload and the PC as arguments and returns a string which will be printed instead. Registering the filter function is done using a factory pattern to make per-thread filtering easier. Approved-By: Markus Metzger <markus.t.metzger@intel.com>
2024-07-16gdb, gdbserver, gdbsupport: use [[noreturn]] instead of ATTRIBUTE_NORETURNSimon Marchi1-3/+2
C++ 11 has a built-in attribute for this, no need to use a compat macro. Change-Id: I90e4220d26e8f3949d91761f8a13cd9c37da3875 Reviewed-by: Lancelot Six <lancelot.six@amd.com>
2024-06-19[gdb/build] Redo poisoning of PyObject_CallMethodTom de Vries1-3/+5
In commit 764af878259 ("[gdb/python] Add typesafe wrapper around PyObject_CallMethod") I added poisoning of PyObject_CallMethod: ... /* Poison PyObject_CallMethod. The typesafe wrapper gdbpy_call_method should be used instead. */ template<typename... Args> PyObject * PyObject_CallMethod (Args...); ... The idea was that subsequent code would be forced to use gdbpy_call_method instead of PyObject_CallMethod. However, that caused build issues with gcc 14 and python 3.13: ... /usr/bin/ld: python/py-disasm.o: in function `gdb::ref_ptr<_object, gdbpy_ref_policy<_object> > gdbpy_call_method<unsigned int, long long>(_object*, char const*, unsigned int, long long)': /data/vries/gdb/src/gdb/python/python-internal.h:207:(.text+0x384f): undefined reference to `_object* PyObject_CallMethod<_object*, char*, char*, unsigned int, long long>(_object*, char*, char*, unsigned int, long long)' /usr/bin/ld: python/py-tui.o: in function `gdb::ref_ptr<_object, gdbpy_ref_policy<_object> > gdbpy_call_method<int>(_object*, char const*, int)': /data/vries/gdb/src/gdb/python/python-internal.h:207:(.text+0x1235): undefined reference to `_object* PyObject_CallMethod<_object*, char*, char*, int>(_object*, char*, char*, int)' /usr/bin/ld: python/py-tui.o: in function `gdb::ref_ptr<_object, gdbpy_ref_policy<_object> > gdbpy_call_method<int, int, int>(_object*, char const*, int, int, int)': /data/vries/gdb/src/gdb/python/python-internal.h:207:(.text+0x12b0): undefined reference to `_object* PyObject_CallMethod<_object*, char*, char*, int, int, int>(_object*, char*, char*, int, int, int)' collect2: error: ld returned 1 exit status ... Fix this by poisoning without using templates. Tested on x86_64-linux.
2024-06-19gdb/python/python-internal.h: avoid uninitialized constexprLancelot SIX1-6/+18
The following recent change introduced a regression when building using clang++: commit 764af878259768bb70c65bdf3f3285c2d6409bbd Date: Wed Jun 12 18:58:49 2024 +0200 [gdb/python] Add typesafe wrapper around PyObject_CallMethod The error message is: ../../gdb/python/python-internal.h:151:16: error: default initialization of an object of const type 'const char' constexpr char gdbpy_method_format; ^ = '\0' CXX python/py-block.o 1 error generated. make[2]: *** [Makefile:1959: python/py-arch.o] Error 1 make[2]: *** Waiting for unfinished jobs.... In file included from ../../gdb/python/py-auto-load.c:25: ../../gdb/python/python-internal.h:151:16: error: default initialization of an object of const type 'const char' constexpr char gdbpy_method_format; ^ = '\0' 1 error generated. make[2]: *** [Makefile:1959: python/py-auto-load.o] Error 1 In file included from ../../gdb/python/py-block.c:23: ../../gdb/python/python-internal.h:151:16: error: default initialization of an object of const type 'const char' constexpr char gdbpy_method_format; ^ = '\0' 1 error generated. This patch fixes this by changing gdbpy_method_format to be a templated struct, and only have its specializations define the static constexpr member "format". This way, we avoid having an uninitialized constexpr expression, regardless of it being instantiated or not. Reviewed-By: Tom de Vries <tdevries@suse.de> Change-Id: I5bec241144f13500ef78daea30f00d01e373692d
2024-06-13Add gdbpy_call_method overloads for gdbpy_ref<>Tom Tromey1-0/+9
This adds an overload of gdbpy_call_method that accepts a gdbpy_ref<>. This is just a small convenience. Reviewed-By: Tom de Vries <tdevries@suse.de>
2024-06-13Return gdbpy_ref<> from gdbpy_call_methodTom Tromey1-9/+9
This changes gdbpy_call_method to return a gdbpy_ref<>. This is slightly safer because it makes it simpler to correctly handle reference counts. Reviewed-By: Tom de Vries <tdevries@suse.de>
2024-06-12[gdb/python] Add typesafe wrapper around PyObject_CallMethodTom Tromey1-11/+59
In gdb/python/py-tui.c we have code like this: ... gdbpy_ref<> result (PyObject_CallMethod (m_window.get(), "hscroll", "i", num_to_scroll, nullptr)); ... The nullptr is superfluous, the format string already indicates that there's only one method argument. OTOH, passing no method args does use a nullptr: ... gdbpy_ref<> result (PyObject_CallMethod (m_window.get (), "render", nullptr)); ... Furthermore, choosing the right format string chars can be tricky. Add a typesafe wrapper around PyObject_CallMethod that hides these details, such that we can use the more intuitive: ... gdbpy_ref<> result (gdbpy_call_method (m_window.get(), "hscroll", num_to_scroll)); ... and: ... gdbpy_ref<> result (gdbpy_call_method (m_window.get (), "render")); ... Tested on x86_64-linux. Co-Authored-By: Tom de Vries <tdevries@suse.de> Approved-By: Tom Tromey <tom@tromey.com>
2024-06-10[gdb/python] Fix GDB_PY_{LL,LLU}_ARG on platform without long longTom de Vries1-2/+2
If in gdb/python/python-internal.h, we pretend to have a platform that doesn't support long long: ... -#ifdef HAVE_LONG_LONG +#if 0 ... I get on arm-linux: ... (gdb) placement_candidate() disassemble test^M Dump of assembler code for function test:^M 0x004004d8 <+0>: push {r11} @ (str r11, [sp, #-4]!)^M 0x004004dc <+4>: Python Exception <class 'ValueError'>: \ Buffer returned from read_memory is sized 0 instead of the expected 4^M ^M unknown disassembler error (error = -1)^M (gdb) FAIL: $exp: memory source api: second disassembler pass ... The problem is that gdb_py_longest is typedef-ed to long, but the corresponding format character GDB_PY_LL_ARG is defined to "L", meaning "long long" [1]. Fix this by using "l", meaning long instead. Likewise for GDB_PY_LLU_ARG. Tested on arm-linux. Approved-By: Tom Tromey <tom@tromey.com> PR python/31845 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31845 [1] https://docs.python.org/3/c-api/arg.html
2024-06-10[gdb/python] Note that python 3.6 assumes long long supportTom de Vries1-2/+13
Starting with python 3.6, support for platforms without long long support has been removed [1]. HAVE_LONG_LONG and PY_LONG_LONG are still defined, but only for compatibility, so stop relying on them. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> [1] https://github.com/python/cpython/issues/72148
2024-03-14Remove 'if' from GDB_PY_HANDLE_EXCEPTIONTom Tromey1-14/+8
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 Vries1-2/+10
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-02-20gdb: pass frames as `const frame_info_ptr &`Simon Marchi1-2/+2
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>
2024-01-12Update copyright year range in header of all files managed by GDBAndrew Burgess1-1/+1
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.