f2e2493b1f892bd377b772307c5ad37bdcda4e12
348 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6b09f1342c |
gdb: Replace gdb::optional with std::optional
Since GDB now requires C++17, we don't need the internally maintained gdb::optional implementation. This patch does the following replacing: - gdb::optional -> std::optional - gdb::in_place -> std::in_place - #include "gdbsupport/gdb_optional.h" -> #include <optional> This change has mostly been done automatically. One exception is gdbsupport/thread-pool.* which did not use the gdb:: prefix as it already lives in the gdb namespace. Change-Id: I19a92fa03e89637bab136c72e34fd351524f65e9 Approved-By: Tom Tromey <tom@tromey.com> Approved-By: Pedro Alves <pedro@palves.net> |
||
|
|
7d21600b31 |
Check gdb_python_module in gdbpy_handle_missing_debuginfo
If you run gdb in the build tree without --data-directory, on a program that does not have debug info, it will crash, because gdbpy_handle_missing_debuginfo unconditionally uses gdb_python_module. Other code in gdb using gdb_python_module checks it first and it seemes harmless to do the same thing here. (gdb_python_initialized does not cover this case so that python can be partially initialized and still somewhat work.) |
||
|
|
8f6c452b5a |
gdb: implement missing debug handler hook for Python
This commit builds on the previous commit, and implements the
extension_language_ops::handle_missing_debuginfo function for Python.
This hook will give user supplied Python code a chance to help find
missing debug information.
The implementation of the new hook is pretty minimal within GDB's C++
code; most of the work is out-sourced to a Python implementation which
is modelled heavily on how GDB's Python frame unwinders are
implemented.
The following new commands are added as commands implemented in
Python, this is similar to how the Python unwinder commands are
implemented:
info missing-debug-handlers
enable missing-debug-handler LOCUS HANDLER
disable missing-debug-handler LOCUS HANDLER
To make use of this extension hook a user will create missing debug
information handler objects, and registers these handlers with GDB.
When GDB encounters an objfile that is missing debug information, each
handler is called in turn until one is able to help. Here is a
minimal handler that does nothing useful:
import gdb
import gdb.missing_debug
class MyFirstHandler(gdb.missing_debug.MissingDebugHandler):
def __init__(self):
super().__init__("my_first_handler")
def __call__(self, objfile):
# This handler does nothing useful.
return None
gdb.missing_debug.register_handler(None, MyFirstHandler())
Returning None from the __call__ method tells GDB that this handler
was unable to find the missing debug information, and GDB should ask
any other registered handlers.
By extending the __call__ method it is possible for the Python
extension to locate the debug information for objfile and return a
value that tells GDB how to use the information that has been located.
Possible return values from a handler:
- None: This means the handler couldn't help. GDB will call other
registered handlers to see if they can help instead.
- False: The handler has done all it can, but the debug information
for the objfile still couldn't be found. GDB will not call
any other handlers, and will continue without the debug
information for objfile.
- True: The handler has installed the debug information into a
location where GDB would normally expect to find it. GDB
should look again for the debug information.
- A string: The handler can return a filename, which is the file
containing the missing debug information. GDB will load
this file.
When a handler returns True, GDB will look again for the debug
information, but only using the standard built-in build-id and
.gnu_debuglink based lookup strategies. It is not possible for an
extension to trigger another debuginfod lookup; the assumption is that
the debuginfod server is remote, and out of the control of extensions
running within GDB.
Handlers can be registered globally, or per program space. GDB checks
the handlers for the current program space first, and then all of the
global handles. The first handler that returns a value that is not
None, has "handled" the objfile, at which point GDB continues.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
||
|
|
093c25c488 |
[gdb/python] Only include gdbsupport/selftest.h if GDB_SELF_TEST
I noticed that gdb/python/python.c unconditionally includes gdbsupport/selftest.h. Make this conditional on GDB_SELF_TEST. Tested on x86_64-linux. |
||
|
|
99d9c3b92c |
gdb: remove target_gdbarch
This function is just a wrapper around the current inferior's gdbarch. I find that having that wrapper just obscures where the arch is coming from, and that it's often used as "I don't know which arch to use so I'll use this magical target_gdbarch function that gets me an arch" when the arch should in fact come from something in the context (a thread, objfile, symbol, etc). I think that removing it and inlining `current_inferior ()->arch ()` everywhere will make it a bit clearer where that arch comes from and will trigger people into reflecting whether this is the right place to get the arch or not. Change-Id: I79f14b4e4934c88f91ca3a3155f5fc3ea2fadf6b Reviewed-By: John Baldwin <jhb@FreeBSD.org> Approved-By: Andrew Burgess <aburgess@redhat.com> |
||
|
|
27b1f19f8f |
gdb: add inferior::{arch, set_arch}
Make the inferior's gdbarch field private, and add getters and setters. This helped me by allowing putting breakpoints on set_arch to know when the inferior's arch was set. A subsequent patch in this series also adds more things in set_arch. Change-Id: I0005bd1ef4cd6b612af501201cec44e457998eec Reviewed-By: John Baldwin <jhb@FreeBSD.org> Approved-By: Andrew Burgess <aburgess@redhat.com> |
||
|
|
4825fd2d35 |
gdb/python: implement support for sending custom MI async notifications
This commit adds a new Python function, gdb.notify_mi, that can be used to emit custom async notification to MI channel. This can be used, among other things, to implement notifications about events MI does not support, such as remote connection closed or register change. Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Andrew Burgess <aburgess@redhat.com> |
||
|
|
0c8a0b88d1 |
Re-acquire GIL earlier in gdbpy_parse_and_eval
Tom de Vries filed a bug about an intermittent gdb DAP failure -- and coincidentally, at the same time, Alexandra Hájková sent email about a somewhat similar failure. After looking into this for a while (with no results) using ASan and valgrind, I found that setting PYTHONMALLOC=malloc_debug found the bug instantly. The problem is that gdbpy_parse_and_eval releases the GIL while calling parse_and_eval, but fails to re-acquire it before calling value_to_value_object. This is easily fixed by introducing a new scope. I wonder whether the test suite should unconditionally set PYTHONMALLOC=malloc_debug. Tested-by: Tom de Vries <tdevries@suse.de> Reviewed-By: Tom de Vries <tdevries@suse.de> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30686 |
||
|
|
33b5899fc0 |
[gdb] Fix typos
Fix a few typos: - implemention -> implementation - convertion(s) -> conversion(s) - backlashes -> backslashes - signoring -> ignoring - (un)ambigious -> (un)ambiguous - occured -> occurred - hidding -> hiding - temporarilly -> temporarily - immediatelly -> immediately - sillyness -> silliness - similiar -> similar - porkuser -> pokeuser - thats -> that - alway -> always - supercede -> supersede - accomodate -> accommodate - aquire -> acquire - priveleged -> privileged - priviliged -> privileged - priviledges -> privileges - privilige -> privilege - recieve -> receive - (p)refered -> (p)referred - succesfully -> successfully - successfuly -> successfully - responsability -> responsibility - wether -> whether - wich -> which - disasbleable -> disableable - descriminant -> discriminant - construcstor -> constructor - underlaying -> underlying - underyling -> underlying - structureal -> structural - appearences -> appearances - terciarily -> tertiarily - resgisters -> registers - reacheable -> reachable - likelyhood -> likelihood - intepreter -> interpreter - disassemly -> disassembly - covnersion -> conversion - conviently -> conveniently - atttribute -> attribute - struction -> struct - resonable -> reasonable - popupated -> populated - namespaxe -> namespace - intialize -> initialize - identifer(s) -> identifier(s) - expection -> exception - exectuted -> executed - dungerous -> dangerous - dissapear -> disappear - completly -> completely - (inter)changable -> (inter)changeable - beakpoint -> breakpoint - automativ -> automatic - alocating -> allocating - agressive -> aggressive - writting -> writing - reguires -> requires - registed -> registered - recuding -> reducing - opeartor -> operator - ommitted -> omitted - modifing -> modifying - intances -> instances - imbedded -> embedded - gdbaarch -> gdbarch - exection -> execution - direcive -> directive - demanged -> demangled - decidely -> decidedly - argments -> arguments - agrument -> argument - amespace -> namespace - targtet -> target - supress(ed) -> suppress(ed) - startum -> stratum - squence -> sequence - prompty -> prompt - overlow -> overflow - memember -> member - languge -> language - geneate -> generate - funcion -> function - exising -> existing - dinking -> syncing - destroh -> destroy - clenaed -> cleaned - changep -> changedp (name of variable) - arround -> around - aproach -> approach - whould -> would - symobl -> symbol - recuse -> recurse - outter -> outer - freeds -> frees - contex -> context Tested on x86_64-linux. Reviewed-By: Tom Tromey <tom@tromey.com> |
||
|
|
125862f0f2 |
Add global_context parameter to gdb.parse_and_eval
This adds a 'global_context' parse_and_eval to gdb.parse_and_eval. This lets users request a parse that is done at "global scope". I considered letting callers pass in a block instead, with None meaning "global" -- but then there didn't seem to be a clean way to express the default for this parameter. Reviewed-By: Eli Zaretskii <eliz@gnu.org> |
||
|
|
c97d123d67 |
Implement gdb.execute_mi
This adds a new Python function, gdb.execute_mi, that can be used to invoke an MI command but get the output as a Python object, rather than a string. This is done by implementing a new ui_out subclass that builds a Python object. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=11688 Reviewed-By: Eli Zaretskii <eliz@gnu.org> |
||
|
|
3965bff5b9 |
gdb/python: add mechanism to manage Python initialization functions
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. |
||
|
|
13d03262f2 |
gdb: move struct ui and related things to ui.{c,h}
I'd like to move some things so they become methods on struct ui. But
first, I think that struct ui and the related things are big enough to
deserve their own file, instead of being scattered through top.{c,h} and
event-top.c.
Change-Id: I15594269ace61fd76ef80a7b58f51ff3ab6979bc
|
||
|
|
55af06a70e |
Use unique_xmalloc_ptr in apply_ext_lang_type_printers
This changes apply_ext_lang_type_printers to use unique_xmalloc_ptr, removing some manual memory management. Regression tested on x86-64 Fedora 36. Approved-By: Simon Marchi <simon.marchi@efficios.com> |
||
|
|
287de65625 |
gdb, gdbserver, gdbsupport: fix whitespace issues
Replace spaces with tabs in a bunch of places. Change-Id: If0f87180f1d13028dc178e5a8af7882a067868b0 |
||
|
|
f3d3bbbcdd |
Fix value chain use-after-free
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 |
||
|
|
4e08903f67 |
gdb, python: do minor modernization in execute_gdb_command
Use nullptr instead of NULL and boolify two local variables in execute_gdb_command. Approved-By: Tom Tromey <tom@tromey.com> |
||
|
|
9ae4519da9 |
gdb/python: deallocate tui window factories at Python shut down
The previous commit relied on spotting when a Python defined TUI
window factory was deleted. I spotted that the window factories are
not deleted when GDB shuts down its Python environment, they are only
deleted when one window factory replaces another. Consider this
example Python script:
class TestWindowFactory:
def __init__(self, msg):
self.msg = msg
print("Entering TestWindowFactory.__init__: %s" % self.msg)
def __call__(self, tui_win):
print("Entering TestWindowFactory.__call__: %s" % self.msg)
return TestWindow(tui_win, self.msg)
def __del__(self):
print("Entering TestWindowFactory.__del__: %s" % self.msg)
gdb.register_window_type("test_window", TestWindowFactory("A"))
gdb.register_window_type("test_window", TestWindowFactory("B"))
And this GDB session:
(gdb) source tui.py
Entering TestWindowFactory.__init__: A
Entering TestWindowFactory.__init__: B
Entering TestWindowFactory.__del__: B
(gdb) quit
Notice that when the 'B' window replaces the 'A' window we see the 'A'
object being deleted. But, when Python is shut down (after the
'quit') the 'B' object is never deleted.
Instead, GDB retains a reference to the window factory object, which
forces the Python object to remain live even after the Python
interpreter itself has been shut down.
The references themselves are held in a dynamically allocated
std::unordered_map (in tui/tui-layout.c) which is never deallocated,
thus the underlying Python references are never decremented to zero,
and so GDB never tries to delete these Python objects.
This commit is the first half of the work to clean up this edge case.
All gdbpy_tui_window_maker objects (the objects that implement the
TUI window factory callback for Python defined TUI windows), are now
linked together into a global list using the intrusive list mechanism.
When GDB shuts down the Python interpreter we can now walk this global
list and release the reference that is held to the underlying Python
object. By releasing this reference the Python object will now be
deleted.
I've added a new assert in gdbpy_tui_window_maker::operator(), this
will catch the case where we somehow end up in here after having
reset the reference to the underlying Python object. I don't think
this should ever happen though as we only clear the references when
shutting down the Python interpreter, and the ::operator() function is
only called when trying to apply a new TUI layout - something that
shouldn't happen while GDB itself is shutting down.
This commit does not update the std::unordered_map in tui-layout.c,
that will be done in the next commit.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
||
|
|
7aeb03e2d4 |
GDB: Allow arbitrary keywords in integer set commands
Rather than just `unlimited' allow the integer set commands (or command
options) to define arbitrary keywords for the user to use, removing
hardcoded arrangements for the `unlimited' keyword.
Remove the confusingly named `var_zinteger', `var_zuinteger' and
`var_zuinteger_unlimited' `set'/`show' command variable types redefining
them in terms of `var_uinteger', `var_integer' and `var_pinteger', which
have the range of [0;UINT_MAX], [INT_MIN;INT_MAX], and [0;INT_MAX] each.
Following existing practice `var_pinteger' allows extra negative values
to be used, however unlike `var_zuinteger_unlimited' any number of such
values can be defined rather than just `-1'.
The "p" in `var_pinteger' stands for "positive", for the lack of a more
appropriate unambiguous letter, even though 0 obviously is not positive;
"n" would be confusing as to whether it stands for "non-negative" or
"negative".
Add a new structure, `literal_def', the entries of which define extra
keywords allowed for a command and numerical values they correspond to.
Those values are not verified against the basic range supported by the
underlying variable type, allowing extra values to be allowed outside
that range, which may or may not be individually made visible to the
user. An optional value translation is possible with the structure to
follow the existing practice for some commands where user-entered 0 is
internally translated to UINT_MAX or INT_MAX. Such translation can now
be arbitrary. Literals defined by this structure are automatically used
for completion as necessary.
So for example:
const literal_def integer_unlimited_literals[] =
{
{ "unlimited", INT_MAX, 0 },
{ nullptr }
};
defines an extra `unlimited' keyword and a user-visible 0 value, both of
which get translated to INT_MAX for the setting to be used with.
Similarly:
const literal_def zuinteger_unlimited_literals[] =
{
{ "unlimited", -1, -1 },
{ nullptr }
};
defines the same keyword and a corresponding user-visible -1 value that
is used for the requested setting. If the last member were omitted (or
set to `{}') here, then only the keyword would be allowed for the user
to enter and while -1 would still be used internally trying to enter it
as a part of a command would result in an "integer -1 out of range"
error.
Use said error message in all cases (citing the invalid value requested)
replacing "only -1 is allowed to set as unlimited" previously used for
`var_zuinteger_unlimited' settings only rather than propagating it to
`var_pinteger' type. It could only be used for the specific case where
a single extra `unlimited' keyword was defined standing for -1 and the
use of numeric equivalents is discouraged anyway as it is for historical
reasons only that they expose GDB internals, confusingly different
across variable types. Similarly update the "must be >= -1" Guile error
message.
Redefine Guile and Python parameter types in terms of the new variable
types and interpret extra keywords as Scheme keywords and Python strings
used to communicate corresponding parameter values. Do not add a new
PARAM_INTEGER Guile parameter type, however do handle the `var_integer'
variable type now, permitting existing parameters defined by GDB proper,
such as `listsize', to be accessed from Scheme code.
With these changes in place it should be trivial for a Scheme or Python
programmer to expand the syntax of the `make-parameter' command and the
`gdb.Parameter' class initializer to have arbitrary extra literals along
with their internal representation supplied.
Update the testsuite accordingly.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
||
|
|
213516ef31 |
Update copyright year range in header of all files managed by GDB
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. |
||
|
|
f8631e5e04 |
gdb: remove static buffer in command_line_input
[I sent this earlier today, but I don't see it in the archives.
Resending it through a different computer / SMTP.]
The use of the static buffer in command_line_input is becoming
problematic, as explained here [1]. In short, with this patch [2] that
attempt to fix a post-hook bug, when running gdb.base/commands.exp, we
hit a case where we read a "define" command line from a script file
using command_command_line_input. The command line is stored in
command_line_input's static buffer. Inside the define command's
execution, we read the lines inside the define using command_line_input,
which overwrites the define command, in command_line_input's static
buffer. After the execution of the define command, execute_command does
a command look up to see if a post-hook is registered. For that, it
uses a now stale pointer that used to point to the define command, in
the static buffer, causing a use-after-free. Note that the pointer in
execute_command points to the dynamically-allocated buffer help by the
static buffer in command_line_input, not to the static object itself,
hence why we see a use-after-free.
Fix that by removing the static buffer. I initially changed
command_line_input and other related functions to return an std::string,
which is the obvious but naive solution. The thing is that some callees
don't need to return an allocated string, so this this an unnecessary
pessimization. I changed it to passing in a reference to an std::string
buffer, which the callee can use if it needs to return
dynamically-allocated content. It fills the buffer and returns a
pointers to the C string inside. The callees that don't need to return
dynamically-allocated content simply don't use it.
So, it started with modifying command_line_input as described above, all
the other changes derive directly from that.
One slightly shady thing is in handle_line_of_input, where we now pass a
pointer to an std::string's internal buffer to readline's history_value
function, which takes a `char *`. I'm pretty sure that this function
does not modify the input string, because I was able to change it (with
enough massaging) to take a `const char *`.
A subtle change is that we now clear a UI's line buffer using a
SCOPE_EXIT in command_line_handler, after executing the command.
This was previously done by this line in handle_line_of_input:
/* We have a complete command line now. Prepare for the next
command, but leave ownership of memory to the buffer . */
cmd_line_buffer->used_size = 0;
I think the new way is clearer.
[1] https://inbox.sourceware.org/gdb-patches/becb8438-81ef-8ad8-cc42-fcbfaea8cddd@simark.ca/
[2] https://inbox.sourceware.org/gdb-patches/20221213112241.621889-1-jan.vrany@labware.com/
Change-Id: I8fc89b1c69870c7fc7ad9c1705724bd493596300
Reviewed-By: Tom Tromey <tom@tromey.com>
|
||
|
|
85933f7c91 |
gdb, python: use gdbarch_iterate_over_objfiles_in_search_order
The implementation of gdb.lookup_objfile() iterates over all objfiles and compares their name or build id to the user-provided search string. This will cause problems when supporting linker namespaces as the first objfile in any namespace will be found. Instead, use gdbarch_iterate_over_objfiles_in_search_order to only consider the namespace of gdb.current_objfile() for the search, which defaults to the initial namespace when gdb.current_objfile() is None. |
||
|
|
e5213e2c85 |
gdb/python: Add BreakpointLocation type
PR python/18385 v7: This version addresses the issues pointed out by Tom. Added nullchecks for Python object creations. Changed from using PyLong_FromLong to the gdb_py-versions. Re-factored some code to make it look more cohesive. Also added the more safe Python reference count decrement PY_XDECREF, even though the BreakpointLocation type is never instantiated by the user (explicitly documented in the docs) decrementing < 0 is made impossible with the safe call. Tom pointed out that using the policy class explicitly to decrement a reference counted object was not the way to go, so this has instead been wrapped in a ref_ptr that handles that for us in blocpy_dealloc. Moved macro from py-internal to py-breakpoint.c. Renamed section at the bottom of commit message "Patch Description". v6: This version addresses the points Pedro gave in review to this patch. Added the attributes `function`, `fullname` and `thread_groups` as per request by Pedro with the argument that it more resembles the output of the MI-command "-break-list". Added documentation for these attributes. Cleaned up left overs from copy+paste in test suite, removed hard coding of line numbers where possible. Refactored some code to use more c++-y style range for loops wrt to breakpoint locations. Changed terminology, naming was very inconsistent. Used a variety of "parent", "owner". Now "owner" is the only term used, and the field in the gdb_breakpoint_location_object now also called "owner". v5: Changes in response to review by Tom Tromey: - Replaced manual INCREF/DECREF calls with gdbpy_ref ptrs in places where possible. - Fixed non-gdb style conforming formatting - Get parent of bploc increases ref count of parent. - moved bploc Python definition to py-breakpoint.c The INCREF of self in bppy_get_locations is due to the individual locations holding a reference to it's owner. This is decremented at de-alloc time. The reason why this needs to be here is, if the user writes for instance; py loc = gdb.breakpoints()[X].locations[Y] The breakpoint owner object is immediately going out of scope (GC'd/dealloced), and the location object requires it to be alive for as long as it is alive. Thanks for your review, Tom! v4: Fixed remaining doc issues as per request by Eli. v3: Rewritten commit message, shortened + reworded, added tests. Patch Description Currently, the Python API lacks the ability to query breakpoints for their installed locations, and subsequently, can't query any information about them, or enable/disable individual locations. This patch solves this by adding Python type gdb.BreakpointLocation. The type is never instantiated by the user of the Python API directly, but is produced by the gdb.Breakpoint.locations attribute returning a list of gdb.BreakpointLocation. gdb.Breakpoint.locations: The attribute for retrieving the currently installed breakpoint locations for gdb.Breakpoint. Matches behavior of the "info breakpoints" command in that it only returns the last known or currently inserted breakpoint locations. BreakpointLocation contains 7 attributes 6 read-only attributes: owner: location owner's Python companion object source: file path and line number tuple: (string, long) / None address: installed address of the location function: function name where location was set fullname: fullname where location was set thread_groups: thread groups (inferiors) where location was set. 1 writeable attribute: enabled: get/set enable/disable this location (bool) Access/calls to these, can all throw Python exceptions (documented in the online documentation), and that's due to the nature of how breakpoint locations can be invalidated "behind the scenes", either by them being removed from the original breakpoint or changed, like for instance when a new symbol file is loaded, at which point all breakpoint locations are re-created by GDB. Therefore this patch has chosen to be non-intrusive: it's up to the Python user to re-request the locations if they become invalid. Also there's event handlers that handle new object files etc, if a Python user is storing breakpoint locations in some larger state they've built up, refreshing the locations is easy and it only comes with runtime overhead when the Python user wants to use them. gdb.BreakpointLocation Python type struct "gdbpy_breakpoint_location_object" is found in python-internal.h Its definition, layout, methods and functions are found in the same file as gdb.Breakpoint (py-breakpoint.c) 1 change was also made to breakpoint.h/c to make it possible to enable and disable a bp_location* specifically, without having its LOC_NUM, as this number also can change arbitrarily behind the scenes. Updated docs & news file as per request. Testsuite: tests the .source attribute and the disabling of individual locations. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=18385 Change-Id: I302c1c50a557ad59d5d18c88ca19014731d736b0 |
||
|
|
24d2cbc42c |
set/show python dont-write-bytecode fixes
GDB uses the environment variable PYTHONDONTWRITEBYTECODE to
determine whether or not to write the result of byte-compiling
python modules when the "python dont-write-bytecode" setting
is "auto". Simon noticed that GDB's implementation doesn't
follow the Python documentation.
At present, GDB only checks for the existence of this environment
variable. That is not sufficient though. Regarding
PYTHONDONTWRITEBYTECODE, this document...
https://docs.python.org/3/using/cmdline.html
...says:
If this is set to a non-empty string, Python won't try to write
.pyc files on the import of source modules.
This commit fixes GDB's handling of PYTHONDONTWRITEBYTECODE by adding
an empty string check.
This commit also corrects the set/show command documentation for
"python dont-write-bytecode". The current doc was just a copy
of that for set/show python ignore-environment.
During his review of an earlier version of this patch, Eli Zaretskii
asked that the help text that I proposed for "set/show python
dont-write-bytecode" be expanded. I've done that in addition to
clarifying the documentation of this option in the GDB manual.
|
||
|
|
5c3392f981 |
[gdb/python] Fix typo in test_python
Fix typo in ref_output_0 variable in test_python. Tested by running the selftest on x86_64-linux with python 3.11. |
||
|
|
c57ac51086 |
[gdb/python] Fix python selftest with python 3.11
With python 3.11 I noticed: ... $ gdb -q -batch -ex "maint selftest python" Running selftest python. Self test failed: self-test failed at gdb/python/python.c:2246 Ran 1 unit tests, 1 failed ... In more detail: ... (gdb) p output $5 = "Traceback (most recent call last):\n File \"<string>\", line 0, \ in <module>\nKeyboardInterrupt\n" (gdb) p ref_output $6 = "Traceback (most recent call last):\n File \"<string>\", line 1, \ in <module>\nKeyboardInterrupt\n" ... Fix this by also allowing line number 0. Tested on x86_64-linux. This should hopefully fix buildbot builder gdb-rawhide-x86_64. |
||
|
|
0679db2966 |
Wrap python_write_bytecode with HAVE_PYTHON ifdef
This commit fixes a build error on machines lacking python headers and/or libraries. |
||
|
|
fe587fc997 |
Handle Python 3.11 deprecation of PySys_SetPath and Py_SetProgramName
Python 3.11 deprecates PySys_SetPath and Py_SetProgramName. The
PyConfig API replaces these and other functions. This commit uses the
PyConfig API to provide equivalent functionality while also preserving
support for older versions of Python, i.e. those before Python 3.8.
A beta version of Python 3.11 is available in Fedora Rawhide. Both
Fedora 35 and Fedora 36 use Python 3.10, while Fedora 34 still used
Python 3.9. I've tested these changes on Fedora 34, Fedora 36, and
rawhide, though complete testing was not possible on rawhide due to
a kernel bug. That being the case, I decided to enable the newer
PyConfig API by testing PY_VERSION_HEX against 0x030a0000. This
corresponds to Python 3.10.
We could try to use the PyConfig API for Python versions as early as 3.8,
but I'm reluctant to do this as there may have been PyConfig related
bugs in earlier versions which have since been fixed. Recent linux
distributions should have support for Python 3.10. This should be
more than adequate for testing the new Python initialization code in
GDB.
Information about the PyConfig API as well as the motivation behind
deprecating the old interface can be found at these links:
https://github.com/python/cpython/issues/88279
https://peps.python.org/pep-0587/
https://docs.python.org/3.11/c-api/init_config.html
The v2 commit also addresses several problems that Simon found in
the v1 version.
In v1, I had used Py_DontWriteBytecodeFlag in the new initialization
code, but Simon pointed out that this global configuration variable
will be deprecated in Python 3.12. This version of the patch no longer
uses Py_DontWriteBytecodeFlag in the new initialization code.
Additionally, both Py_DontWriteBytecodeFlag and Py_IgnoreEnvironmentFlag
will no longer be used when building GDB against Python 3.10 or higher.
While it's true that both of these global configuration variables are
deprecated in Python 3.12, it makes sense to disable their use for
gdb builds against 3.10 and higher since those are the versions for
which the PyConfig API is now being used by GDB. (The PyConfig API
includes different mechanisms for making the same settings afforded
by use of the soon-to-be deprecated global configuration variables.)
Simon also noted that PyConfig_Clear() would not have be called for
one of the failure paths. I've fixed that problem and also made the
rest of the "bail out" code more direct. In particular,
PyConfig_Clear() will always be called, both for success and failure.
The v3 patch addresses some rebase conflicts related to module
initialization . Commit
|
||
|
|
c4a3dbaf11 |
Expose current 'print' settings to Python
PR python/17291 asks for access to the current print options. While I think this need is largely satisfied by the existence of Value.format_string, it seemed to me that a bit more could be done. First, while Value.format_string uses the user's settings, it does not react to temporary settings such as "print/x". This patch changes this. Second, there is no good way to examine the current settings (in particular the temporary ones in effect for just a single "print"). This patch adds this as well. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17291 |
||
|
|
3acd9a692d |
Make 'import gdb.events' work
Pierre-Marie noticed that, while gdb.events is a Python module, it
can't be imported. This patch changes how this module is created, so
that it can be imported, while also ensuring that the module is always
visible, just as it was in the past.
This new approach required one non-obvious change -- when running
gdb.base/warning.exp, where --data-directory is intentionally not
found, the event registries can now be nullptr. Consequently, this
patch probably also requires
https://sourceware.org/pipermail/gdb-patches/2022-June/189796.html
Note that this patch obsoletes
https://sourceware.org/pipermail/gdb-patches/2022-June/189797.html
|
||
|
|
264f98902f |
event_location -> location_spec
Currently, GDB internally uses the term "location" for both the
location specification the user input (linespec, explicit location, or
an address location), and for actual resolved locations, like the
breakpoint locations, or the result of decoding a location spec to
SaLs. This is expecially confusing in the breakpoints module, as
struct breakpoint has these two fields:
breakpoint::location;
breakpoint::loc;
"location" is the location spec, and "loc" is the resolved locations.
And then, we have a method called "locations()", which returns the
resolved locations as range...
The location spec type is presently called event_location:
/* Location we used to set the breakpoint. */
event_location_up location;
and it is described like this:
/* The base class for all an event locations used to set a stop event
in the inferior. */
struct event_location
{
and even that is incorrect... Location specs are used for finding
actual locations in the program in scenarios that have nothing to do
with stop events. E.g., "list" works with location specs.
To clean all this confusion up, this patch renames "event_location" to
"location_spec" throughout, and then all the variables that hold a
location spec, they are renamed to include "spec" in their name, like
e.g., "location" -> "locspec". Similarly, functions that work with
location specs, and currently have just "location" in their name are
renamed to include "spec" in their name too.
Change-Id: I5814124798aa2b2003e79496e78f95c74e5eddca
|
||
|
|
9d741cbedb |
Check for listeners in emit_exiting_event
I noticed that emit_exiting_event does not check whether there are any listeners before creating the event object. All other event emitters do this, so this patch updates this one as well. |
||
|
|
15e15b2d9c |
gdb/python: implement the print_insn extension language hook
This commit extends the Python API to include disassembler support.
The motivation for this commit was to provide an API by which the user
could write Python scripts that would augment the output of the
disassembler.
To achieve this I have followed the model of the existing libopcodes
disassembler, that is, instructions are disassembled one by one. This
does restrict the type of things that it is possible to do from a
Python script, i.e. all additional output has to fit on a single line,
but this was all I needed, and creating something more complex would,
I think, require greater changes to how GDB's internal disassembler
operates.
The disassembler API is contained in the new gdb.disassembler module,
which defines the following classes:
DisassembleInfo
Similar to libopcodes disassemble_info structure, has read-only
properties: address, architecture, and progspace. And has methods:
__init__, read_memory, and is_valid.
Each time GDB wants an instruction disassembled, an instance of
this class is passed to a user written disassembler function, by
reading the properties, and calling the methods (and other support
methods in the gdb.disassembler module) the user can perform and
return the disassembly.
Disassembler
This is a base-class which user written disassemblers should
inherit from. This base class provides base implementations of
__init__ and __call__ which the user written disassembler should
override.
DisassemblerResult
This class can be used to hold the result of a call to the
disassembler, it's really just a wrapper around a string (the text
of the disassembled instruction) and a length (in bytes). The user
can return an instance of this class from Disassembler.__call__ to
represent the newly disassembled instruction.
The gdb.disassembler module also provides the following functions:
register_disassembler
This function registers an instance of a Disassembler sub-class
as a disassembler, either for one specific architecture, or, as a
global disassembler for all architectures.
builtin_disassemble
This provides access to GDB's builtin disassembler. A common
use case that I see is augmenting the existing disassembler output.
The user code can call this function to have GDB disassemble the
instruction in the normal way. The user gets back a
DisassemblerResult object, which they can then read in order to
augment the disassembler output in any way they wish.
This function also provides a mechanism to intercept the
disassemblers reads of memory, thus the user can adjust what GDB
sees when it is disassembling.
The included documentation provides a more detailed description of the
API.
There is also a new CLI command added:
maint info python-disassemblers
This command is defined in the Python gdb.disassemblers module, and
can be used to list the currently registered Python disassemblers.
|
||
|
|
e4ae302562 |
gdb: add extension language print_insn hook
This commit is setup for the next commit. In the next commit I will add a Python API to intercept the print_insn calls within GDB, each print_insn call is responsible for disassembling, and printing one instruction. After the next commit it will be possible for a user to write Python code that either wraps around the existing disassembler, or even, in extreme situations, entirely replaces the existing disassembler. This commit does not add any new Python API. What this commit does is put the extension language framework in place for a print_insn hook. There's a new callback added to 'struct extension_language_ops', which is then filled in with nullptr for Python and Guile. Finally, in the disassembler, the code is restructured so that the new extension language function ext_lang_print_insn is called before we delegate to gdbarch_print_insn. After this, the next commit can focus entirely on providing a Python implementation of the new print_insn callback. There should be no user visible change after this commit. |
||
|
|
80fa4b2a60 |
Add gdb.current_language and gdb.Frame.language
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. |
||
|
|
4206d69e96 |
Replace symbol_symtab with symbol::symtab
This turns symbol_symtab into a method on symbol. It also replaces symbol_set_symtab with a method. |
||
|
|
6cb06a8cda |
Unify gdb printf functions
Now that filtered and unfiltered output can be treated identically, we can unify the printf family of functions. This is done under the name "gdb_printf". Most of this patch was written by script. |
||
|
|
5aee458796 |
gdb/python: remove Python 2/3 compatibility macros
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 |
||
|
|
edae3fd660 |
gdb/python: remove Python 2 support
New in this version: - Add a PY_MAJOR_VERSION check in configure.ac / AC_TRY_LIBPYTHON. If the user passes --with-python=python2, this will cause a configure failure saying that GDB only supports Python 3. Support for Python 2 is a maintenance burden for any patches touching Python support. Among others, the differences between Python 2 and 3 string and integer types are subtle. It requires a lot of effort and thinking to get something that behaves correctly on both. And that's if the author and reviewer of the patch even remember to test with Python 2. See this thread for an example: https://sourceware.org/pipermail/gdb-patches/2021-December/184260.html So, remove Python 2 support. Update the documentation to state that GDB can be built against Python 3 (as opposed to Python 2 or 3). Update all the spots that use: - sys.version_info - IS_PY3K - PY_MAJOR_VERSION - gdb_py_is_py3k ... to only keep the Python 3 portions and drop the use of some now-removed compatibility macros. I did not update the configure script more than just removing the explicit references to Python 2. We could maybe do more there, like check the Python version and reject it if that version is not supported. Otherwise (with this patch), things will only fail at compile time, so it won't really be clear to the user that they are trying to use an unsupported Python version. But I'm a bit lost in the configure code that checks for Python, so I kept that for later. Change-Id: I75b0f79c148afbe3c07ac664cfa9cade052c0c62 |
||
|
|
25209e2c69 |
gdb/python: add gdb.format_address function
Add a new function, gdb.format_address, which is a wrapper around GDB's print_address function. This method takes an address, and returns a string with the format: ADDRESS <SYMBOL+OFFSET> Where, ADDRESS is the original address, formatted as hexadecimal, SYMBOL is a symbol with an address lower than ADDRESS, and OFFSET is the offset from SYMBOL to ADDRESS in decimal. If there's no SYMBOL suitably close to ADDRESS then the <SYMBOL+OFFSET> part is not included. This is useful if a user wants to write a Python script that pretty-prints addresses, the user no longer needs to do manual symbol lookup, or worry about correctly formatting addresses. Additionally, there are some settings that effect how GDB picks SYMBOL, and whether the file name and line number should be included with the SYMBOL name, the gdb.format_address function ensures that the users Python script also benefits from these settings. The gdb.format_address by default selects SYMBOL from the current inferiors program space, and address is formatted using the architecture for the current inferior. However, a user can also explicitly pass a program space and architecture like this: gdb.format_address(ADDRESS, PROGRAM_SPACE, ARCHITECTURE) In order to format an address for a different inferior. Notes on the implementation: In py-arch.c I extended arch_object_to_gdbarch to add an assertion for the type of the PyObject being worked on. Prior to this commit all uses of arch_object_to_gdbarch were guaranteed to pass this function a gdb.Architecture object, but, with this commit, this might not be the case. So, with this commit I've made it a requirement that the PyObject be a gdb.Architecture, and this is checked with the assert. And in order that callers from other files can check if they have a gdb.Architecture object, I've added the new function gdbpy_is_architecture. In py-progspace.c I've added two new function, the first progspace_object_to_program_space, converts a PyObject of type gdb.Progspace to the associated program_space pointer, and gdbpy_is_progspace checks if a PyObject is a gdb.Progspace or not. |
||
|
|
6f3dfea03a |
gdb/python: remove gdb._mi_commands dict
The motivation for this patch is the fact that py-micmd.c doesn't build
with Python 2, due to PyDict_GetItemWithError being a Python 3-only
function:
CXX python/py-micmd.o
/home/smarchi/src/binutils-gdb/gdb/python/py-micmd.c: In function ‘int micmdpy_uninstall_command(micmdpy_object*)’:
/home/smarchi/src/binutils-gdb/gdb/python/py-micmd.c:430:20: error: ‘PyDict_GetItemWithError’ was not declared in this scope; did you mean ‘PyDict_GetItemString’?
430 | PyObject *curr = PyDict_GetItemWithError (mi_cmd_dict.get (),
| ^~~~~~~~~~~~~~~~~~~~~~~
| PyDict_GetItemString
A first solution to fix this would be to try to replace
PyDict_GetItemWithError equivalent Python 2 code. But I looked at why
we are doing this in the first place: it is to maintain the
`gdb._mi_commands` Python dictionary that we use as a `name ->
gdb.MICommand object` map. Since the `gdb._mi_commands` dictionary is
never actually used in Python, it seems like a lot of trouble to use a
Python object for this.
My first idea was to replace it with a C++ map
(std::unordered_map<std::string, gdbpy_ref<micmdpy_object>>). While
implementing this, I realized we don't really need this map at all. The
mi_command_py objects registered in the main MI command table can own
their backing micmdpy_object (that's a gdb.MICommand, but seen from the
C++ code). To know whether an mi_command is an mi_command_py, we can
use a dynamic cast. Since there's one less data structure to maintain,
there are less chances of messing things up.
- Change mi_command_py::m_pyobj to a gdbpy_ref, the mi_command_py is
now what keeps the MICommand alive.
- Set micmdpy_object::mi_command in the constructor of mi_command_py.
If mi_command_py manages setting/clearing that field in
swap_python_object, I think it makes sense that it also takes care of
setting it initially.
- Move a bunch of checks from micmdpy_install_command to
swap_python_object, and make them gdb_asserts.
- In micmdpy_install_command, start by doing an mi_cmd_lookup. This is
needed to know whether there's a Python MI command already registered
with that name. But we can already tell if there's a non-Python
command registered with that name. Return an error if that happens,
rather than waiting for insert_mi_cmd_entry to fail. Change the
error message to "name is already in use" rather than "may already be
in use", since it's more precise.
I asked Andrew about the original intent of using a Python dictionary
object to hold the command objects. The reason was to make sure the
objects get destroyed when the Python runtime gets finalized, not later.
Holding the objects in global C++ data structures and not doing anything
more means that the held Python objects will be decref'd after the
Python interpreter has been finalized. That's not desirable. I tried
it and it indeed segfaults.
Handle this by adding a gdbpy_finalize_micommands function called in
finalize_python. This is the mirror of gdbpy_initialize_micommands
called in do_start_initialization. In there, delete all Python MI
commands. I think it makes sense to do it this way: if it was somehow
possible to unload Python support from GDB in the middle of a session
we'd want to unregister any Python MI command. Otherwise, these MI
commands would be backed with a stale PyObject or simply nothing.
Delete tests that were related to `gdb._mi_commands`.
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I060d5ebc7a096c67487998a8a4ca1e8e56f12cd3
|
||
|
|
740b42ceb7 |
gdb/python/mi: create MI commands using python
This commit allows a user to create custom MI commands using Python similarly to what is possible for Python CLI commands. A new subclass of mi_command is defined for Python MI commands, mi_command_py. A new file, gdb/python/py-micmd.c contains the logic for Python MI commands. This commit is based on work linked too from this mailing list thread: https://sourceware.org/pipermail/gdb/2021-November/049774.html Which has also been previously posted to the mailing list here: https://sourceware.org/pipermail/gdb-patches/2019-May/158010.html And was recently reposted here: https://sourceware.org/pipermail/gdb-patches/2022-January/185190.html The version in this patch takes some core code from the previously posted patches, but also has some significant differences, especially after the feedback given here: https://sourceware.org/pipermail/gdb-patches/2022-February/185767.html A new MI command can be implemented in Python like this: class echo_args(gdb.MICommand): def invoke(self, args): return { 'args': args } echo_args("-echo-args") The 'args' parameter (to the invoke method) is a list containing (almost) all command line arguments passed to the MI command (--thread and --frame are handled before the Python code is called, and removed from the args list). This list can be empty if the MI command was passed no arguments. When used within gdb the above command produced output like this: (gdb) -echo-args a b c ^done,args=["a","b","c"] (gdb) The 'invoke' method of the new command must return a dictionary. The keys of this dictionary are then used as the field names in the mi command output (e.g. 'args' in the above). The values of the result returned by invoke can be dictionaries, lists, iterators, or an object that can be converted to a string. These are processed recursively to create the mi output. And so, this is valid: class new_command(gdb.MICommand): def invoke(self,args): return { 'result_one': { 'abc': 123, 'def': 'Hello' }, 'result_two': [ { 'a': 1, 'b': 2 }, { 'c': 3, 'd': 4 } ] } Which produces output like: (gdb) -new-command ^done,result_one={abc="123",def="Hello"},result_two=[{a="1",b="2"},{c="3",d="4"}] (gdb) I have required that the fields names used in mi result output must match the regexp: "^[a-zA-Z][-_a-zA-Z0-9]*$" (without the quotes). This restriction was never written down anywhere before, but seems sensible to me, and we can always loosen this rule later if it proves to be a problem. Much harder to try and add a restriction later, once people are already using the API. What follows are some details about how this implementation differs from the original patch that was posted to the mailing list. In this patch, I have changed how the lifetime of the Python gdb.MICommand objects is managed. In the original patch, these object were kept alive by an owned reference within the mi_command_py object. As such, the Python object would not be deleted until the mi_command_py object itself was deleted. This caused a problem, the mi_command_py were held in the global mi command table (in mi/mi-cmds.c), which, as a global, was not cleared until program shutdown. By this point the Python interpreter has already been shutdown. Attempting to delete the mi_command_py object at this point was causing GDB to try and invoke Python code after finalising the Python interpreter, and we would crash. To work around this problem, the original patch added code in python/python.c that would search the mi command table, and delete the mi_command_py objects before the Python environment was finalised. In contrast, in this patch, I have added a new global dictionary to the gdb module, gdb._mi_commands. We already have several such global data stores related to pretty printers, and frame unwinders. The MICommand objects are placed into the new gdb.mi_commands dictionary, and it is this reference that keeps the objects alive. When GDB's Python interpreter is shut down gdb._mi_commands is deleted, and any MICommand objects within it are deleted at this point. This change avoids having to make the mi_cmd_table global, and walk over it from within GDB's python related code. This patch handles command redefinition entirely within GDB's python code, though this does impose one small restriction which is not present in the original code (detailed below), I don't think this is a big issue. However, the original patch relied on being able to finish executing the mi_command::do_invoke member function after the mi_command object had been deleted. Though continuing to execute a member function after an object is deleted is well defined, it is also (IMHO) risky, its too easy for someone to later add a use of the object without realising that the object might sometimes, have been deleted. The new patch avoids this issue. The one restriction that is added to avoid this, is that an MICommand object can't be reinitialised with a different command name, so: (gdb) python cmd = MyMICommand("-abc") (gdb) python cmd.__init__("-def") can't reinitialize object with a different command name This feels like a pretty weird edge case, and I'm happy to live with this restriction. I have also changed how the memory is managed for the command name. In the most recently posted patch series, the command name is moved into a subclass of mi_command, the python mi_command_py, which inherits from mi_command is then free to use a smart pointer to manage the memory for the name. In this patch, I leave the mi_command class unchanged, and instead hold the memory for the name within the Python object, as the lifetime of the Python object always exceeds the c++ object stored in the mi_cmd_table. This adds a little more complexity in py-micmd.c, but leaves the mi_command class nice and simple. Next, this patch adds some extra functionality, there's a MICommand.name read-only attribute containing the name of the command, and a read-write MICommand.installed attribute that can be used to install (make the command available for use) and uninstall (remove the command from the mi_cmd_table so it can't be used) the command. This attribute will be automatically updated if a second command replaces an earlier command. This patch adds additional error handling, and makes more use the gdbpy_handle_exception function. Co-Authored-By: Jan Vrany <jan.vrany@labware.com> |
||
|
|
7b8c55afd0 |
gdb/python: move styling support to gdb.styling
This commit moves the two Python functions that are used for styling into a new module, gdb.styling, there's then a small update in python.c so GDB can find the functions in their new location. The motivation for this change is purely to try and reduce the clutter in the top-level gdb module, and encapsulate related functions into modules. I did ponder documenting these functions as part of the Python API, however, doing so would effectively "fix" the API, and I'm still wondering if there's improvements that could be made, also, the colorize function is only called in some cases now that GDB prefers libsource-highlight, so it's not entirely sure how this would work as part of a user facing API. Still, despite these functions never having been part of a documented API, it is possible that a user out there has overridden these to, in some way, customize how GDB performs styling. Moving the function as I propose in this patch could break things for that user, however, fixing this breakage is trivial, and, as these functions were never documented, I don't think we should be obliged to not break user code that relies on them. |
||
|
|
e867795e8b |
gdb: use python to colorize disassembler output
This commit adds styling support to the disassembler output, as such two new commands are added to GDB: set style disassembler enabled on|off show style disassembler enabled In this commit I make use of the Python Pygments package to provide the styling. I did investigate making use of libsource-highlight, however, I found the highlighting results to be inferior to those of Pygments; only some mnemonics were highlighted, and highlighting of register names such as r9d and r8d (on x86-64) was incorrect. To enable disassembler highlighting via Pygments, I've added a new extension language hook, which is then implemented for Python. This hook is very similar to the existing hook for source code colorization. One possibly odd choice I made with the new hook is to pass a gdb.Architecture through, even though this is currently unused. The reason this argument is not used is that, currently, styling is performed identically for all architectures. However, even though the Python function used to perform styling of disassembly output is not part of any documented API, I don't want to close the door on a user overriding this function to provide architecture specific styling. To do this, the user would inevitably require access to the gdb.Architecture, and so I decided to add this field now. The styling is applied within gdb_disassembler::print_insn, to achieve this, gdb_disassembler now writes its output into a temporary buffer, styling is then applied to the contents of this buffer. Finally the gdb_disassembler buffer is copied out to its final destination stream. There's a new test to check that the disassembler output includes some escape sequences, though I don't check for specific colours; the precise colors will depend on which instructions are in the disassembler output, and, I guess, how pygments is configured. The only negative change with this commit is how we currently style addresses in GDB. Currently, when the disassembler wants to print an address, we call back into GDB, and GDB prints the address value using the `address` styling, and the symbol name using `function` styling. After this commit, if pygments is used, then all disassembler styling is done through pygments, and this include the address and symbol name parts of the disassembler output. I don't know how much of an issue this will be for people. There's already some precedent for this in GDB when we look at source styling. For example, function names in styled source listings are not styled using the `function` style, but instead, either GNU Source Highlight, or pygments gets to decide how the function name should be styled. If the Python pygments library is not present then GDB will continue to behave as it always has, the disassembler output is mostly unstyled, but the address and symbols are styled using the `address` and `function` styles, as they are today. However, if the user does `set style disassembler enabled off`, then all disassembler styling is switched off. This obviously covers the use of pygments, but also includes the minimal styling done by GDB when pygments is not available. |
||
|
|
299953ca95 |
gdb/python: handle non utf-8 characters when source highlighting
This commit adds support for source files that contain non utf-8 characters when performing source styling using the Python pygments package. This does not change the behaviour of GDB when the GNU Source Highlight library is used. For the following problem description, assume that either GDB is built without GNU Source Highlight support, of that this has been disabled using 'maintenance set gnu-source-highlight enabled off'. The initial problem reported was that a source file containing non utf-8 characters would cause GDB to print a Python exception, and then display the source without styling, e.g.: Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xc0 in position 142: invalid start byte /* Source code here, without styling... */ Further, as the user steps through different source files, each time the problematic source file was evicted from the source cache, and then later reloaded, the exception would be printed again. Finally, this problem is only present when using Python 3, this issue is not present for Python 2. What makes this especially frustrating is that GDB can clearly print the source file contents, they're right there... If we disable styling completely, or make use of the GNU Source Highlight library, then everything is fine. So why is there an error when we try to apply styling using Python? The problem is the use of PyString_FromString (which is an alias for PyUnicode_FromString in Python 3), this function converts a C string into a either a Unicode object (Py3) or a str object (Py2). For Python 2 there is no unicode encoding performed during this function call, but for Python 3 the input is assumed to be a uft-8 encoding string for the purpose of the conversion. And here of course, is the problem, if the source file contains non utf-8 characters, then it should not be treated as utf-8, but that's what we do, and that's why we get an error. My first thought when looking at this was to spot when the PyString_FromString call failed with a UnicodeDecodeError and silently ignore the error. This would mean that GDB would print the source without styling, but would also avoid the annoying exception message. However, I also make use of `pygmentize`, a command line wrapper around the Python pygments module, which I use to apply syntax highlighting in the output of `less`. And this command line wrapper is quite happy to syntax highlight my source file that contains non utf-8 characters, so it feels like the problem should be solvable. It turns out that inside the pygments module there is already support for guessing the encoding of the incoming file content, if the incoming content is not already a Unicode string. This is what happens for Python 2 where the incoming content is of `str` type. We could try and make GDB smarter when it comes to converting C strings into Python Unicode objects; this would probably require us to just try a couple of different encoding schemes rather than just giving up after utf-8. However, I figure, why bother? The pygments module already does this for us, and the colorize API is not part of the documented external API of GDB. So, why not just change the colorize API, instead of the content being a Unicode string (for Python 3), lets just make the content be a bytes object. The pygments module can then take responsibility for guessing the encoding. So, currently, the colorize API receives a unicode object, and returns a unicode object. I propose that the colorize API receive a bytes object, and return a bytes object. |
||
|
|
30a87e90be |
gdb/python: add gdb.history_count function
Add a new function gdb.history_count to the Python api, this function returns an integer, the number of items in GDB's value history. This is useful if you want to pull items from the history by their absolute number, for example, if you wanted to show a complete history list. Previously we could figure out how many items are in the history list by trying to fetch the items, and then catching the exception when the item is not available, but having this function seems nicer. |
||
|
|
1da5d0e664 |
Change how Python architecture and language are handled
Currently, gdb's Python layer captures the current architecture and
language when "entering" Python code. This has some undesirable
effects, and so this series changes how this is handled.
First, there is code like this:
gdbpy_enter enter_py (python_gdbarch, python_language);
This is incorrect, because both of these are NULL when not otherwise
assigned. This can cause crashes in some cases -- I've added one to
the test suite. (Note that this crasher is just an example, other
ones along the same lines are possible.)
Second, when the language is captured in this way, it means that
Python code cannot affect the current language for its own purposes.
It's reasonable to want to write code like this:
gdb.execute('set language mumble')
... stuff using the current language
gdb.execute('set language previous-value')
However, this won't actually work, because the language is captured on
entry. I've added a test to show this as well.
This patch changes gdb to try to avoid capturing the current values.
The Python concept of the current gdbarch is only set in those few
cases where a non-default value is computed or needed; and the
language is not captured at all -- instead, in the cases where it's
required, the current language is temporarily changed.
|
||
|
|
61671e9792 |
gdb/python: add gdb.host_charset function
We already have gdb.target_charset and gdb.target_wide_charset. This commit adds gdb.host_charset along the same lines. |
||
|
|
4a94e36819 |
Automatic Copyright Year update after running gdb/copyright.py
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. |
||
|
|
0e3b7c25ee |
gdb/python: introduce gdb.TargetConnection object type
This commit adds a new object type gdb.TargetConnection. This new
type represents a connection within GDB (a connection as displayed by
'info connections').
There's three ways to find a gdb.TargetConnection, there's a new
'gdb.connections()' function, which returns a list of all currently
active connections.
Or you can read the new 'connection' property on the gdb.Inferior
object type, this contains the connection for that inferior (or None
if the inferior has no connection, for example, it is exited).
Finally, there's a new gdb.events.connection_removed event registry,
this emits a new gdb.ConnectionEvent whenever a connection is removed
from GDB (this can happen when all inferiors using a connection exit,
though this is not always the case, depending on the connection type).
The gdb.ConnectionEvent has a 'connection' property, which is the
gdb.TargetConnection being removed from GDB.
The gdb.TargetConnection has an 'is_valid()' method. A connection
object becomes invalid when the underlying connection is removed from
GDB (as discussed above, this might be when all inferiors using a
connection exit, or it might be when the user explicitly replaces a
connection in GDB by issuing another 'target' command).
The gdb.TargetConnection has the following read-only properties:
'num': The number for this connection,
'type': e.g. 'native', 'remote', 'sim', etc
'description': The longer description as seen in the 'info
connections' command output.
'details': A string or None. Extra details for the connection, for
example, a remote connection's details might be
'hostname:port'.
|