| Age | Commit message (Collapse) | Author | Files | Lines |
|
Replace 8 spaces with a tab.
Change-Id: Ie8f942ce4b4ba4a83c2ee83cb904153b2e58cf8c
|
|
This changes DAP to ignore the case where a pretty-printer returns a
negative number from the num_children method. It didn't seem worth
writing a test case for this.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33594
Reviewed-By: Ciaran Woodward <ciaranwoodward@xmos.com>
|
|
A user pointed out that if multiple breakpoints are set at the same
spot, in DAP mode, then changing the breakpoints won't reset all of
them.
The problem here is that the breakpoint map only stores a single
breakpoint, so if two breakpoints have the same key, only one will be
stored. Then, when breakpoints are changed, the "missing" breakpoint
will not be deleted.
The fix is to change the map to store a list of breakpoints.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33467
Reviewed-By: Ciaran Woodward <ciaranwoodward@xmos.com>
|
|
This renames the variable 'breakpoint_map' in DAP's breakpoint.py,
adding an underscore to make it clear that it is private to the
module.
Reviewed-By: Ciaran Woodward <ciaranwoodward@xmos.com>
|
|
A user pointed out that the Python API can't create a type that is
both const and volatile.
The bug is that the calls to make_cv_type did not preserve the "other"
flag.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33585
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
I noticed that when printing a gdb.Block object in Python, I would
occasionally get corrupted, nonsensical output, like this:
<gdb.Block <anonymous> {intintyinty_1inty_3inty_5... (-5 more symbols)}>
The symbol list is missing commas, it should be:
int, inty, inty_1, inty_3, inty_5, ...
And the '-5 more symbols' is clearly not right.
The problem is in python/py-block.c, we use this line to calculate the
number of symbols in a block:
const int len = mdict_size (block->multidict ());
Then we loop over the symbols in the block like this:
for (struct symbol *symbol : block_iterator_range (block))
...
The problem here is that 'block_iterator_range (block)' can loop over
more symbols than just those within 'block'. For global and static
blocks, block_iterator_range() takes into account included CUs; and so
can step through multiple global or static blocks. See
block_iterator_step and find_iterator_compunit_symtab in block.c for
more details.
In contrast, 'mdict_size (block->multidict ())' only counts the
symbols contained within 'block' itself.
I could fix this by either fixing LEN, or by only iterating over the
symbols within 'block'.
I assume that printing a gdb.Block object is used mostly for debug
purposes; the output isn't really user friendly, so I cannot imagine a
user script that is relying on printing a gdb.Block as a way to inform
the user about blocks in their program. As such, I think it makes
more sense if the symbols listed are restricted to those strictly held
within the block.
And so, instead of block_iterator_range, I've switched to iterating
over the multidict symbols. Now the calculated LEN will match the
number of symbols being printed, which fixes the output seen above.
However, as we're now only printing symbols that are within the block
being examined, the output above becomes:
<gdb.Block <anonymous> {}>
All the symbols that GDB previously tried to print, are coming from an
included CU.
For testing, I've made use of an existing DWARF test that tests
DW_AT_import. In the wild I saw this in an inferior that used
multiple shared libraries that has their debug information stored in a
separate debug file, and then parts of that debug information was
combined into a third separate file using the DWZ tool. I made a few
attempts to craft a simpler reproducer, but failed. In the end it was
easier to just use a DWARF assembler test to reproduce the issue.
I have added some more typedef symbols into the DWARF test, I don't
believe that this will impact the existing test, but makes the
corrupted output more obvious.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Currently, there is no way for a new user to have an idea of common
useful commands and behaviors from the GDB interface itself, without
checking the example session in the documentation. This command class
aims to close that gap by providing a set of quickstart commands that
allows for any simple debug session to happen without anything too
egregious missing.
The set of commands was chosen somewhat arbitrarily, based on what I
used or missed the most. The one overarching important thing, however,
is that the list is kept short, so as to not overwhelm new users. This
is confirmed by the newly introduced selftest, essential_command_count,
which ensures there are 20 or fewer essential commands.
Here's the reasoning for some of the choices:
* The command "start" was picked over "run" because combining it with
"continue" achieves the same effect, and I prefer it over needing to set
a breakpoint on main to stop at the start of the inferior.
* The command "ptype" is chosen because I believe it is important to
provide a way for the user to check a variable's type from inside GDB,
and ptype is a more complete command than the alternative, "whatis".
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Convert symtab to use obstack_new, and have a real constructor. The
filename, filename_for_id and m_compunit, members should really not
change once the symtab has been created, so make these members private
(m_compunit was already private) and set them just once from the
constructor. The set_compunit function has been deleted, and new
getter functions for filename and filename_for_id have been added.
The language is also set at construction time, but can be updated
later, so set the language in the constructor, but retain
symtab::set_language for when the language needs to be updated.
Prior to this patch the symtab was allocated with OBSTACK_ZALLOC which
would zero out the symtab object. With the call to objstack_new
fields in the symtab would no longer be initialised, so I've added
default member initialisation for everything not set in the
constructor.
The interesting changes are in symtab.h, and symfile.c. Everything
else is just updating to handle symfile::filename and
symfile::filename_for_id becoming methods.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Add gdb_rl_tilde_expand, a wrapper around readline's tilde_expand that
returns a gdb::unique_xmalloc_ptr<char>. Change all callers of
tilde_expand to use gdb_rl_tilde_expand (even the couple of spots that
release it immediatly, for consistency). This simplifies a few callers.
The name gdb_tilde_expand is already taken by a home-made implementation
in gdbsupport/gdb_tilde_expand.{h.cc}. I wonder if we could just use
that one instead of readline's tilde_expand, but that's an orthogonal
question. I don't know how they differ, and I don't want to introduce
behavior changes in this patch.
Change-Id: I6d34eef19f86473226df4ae56d07dc01912e3131
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This commit changes find_pcs_for_symtab_line() to return complete
linetable entries instead of just PCs. This is a preparation for adding
more attributes to gdb.LinetableEntry objects.
I also renamed the function to find_linetable_entries_for_symtab_line()
to better reflect what it does.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
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>
|
|
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>
|
|
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
|
|
Change-Id: I293b655e8753fc650f3ec10bb4e34a9632d8e377
Approved-by: Kevin Buettner <kevinb@redhat.com>
|
|
Change-Id: I6eef5db4ae55f3eb0415768207ae3c26b305f773
Approved-by: Kevin Buettner <kevinb@redhat.com>
|
|
Change-Id: I2069be1a6d7c3250cf330574c941bf851c89bab4
Approved-by: Kevin Buettner <kevinb@redhat.com>
|
|
On ppc64le-linux (AlmaLinux 9.6) with python 3.9 and test-case
gdb.python/py-failed-init.exp I run into:
...
builtin_spawn $gdb -nw -nx -q -iex set height 0 -iex set width 0 \
-data-directory $build/gdb/data-directory -iex set interactive-mode on^M
Python path configuration:^M
PYTHONHOME = 'foo'^M
PYTHONPATH = (not set)^M
program name = '/usr/bin/python'^M
isolated = 0^M
environment = 1^M
user site = 1^M
import site = 1^M
sys._base_executable = '/usr/bin/python'^M
sys.base_prefix = 'foo'^M
sys.base_exec_prefix = 'foo'^M
sys.platlibdir = 'lib64'^M
sys.executable = '/usr/bin/python'^M
sys.prefix = 'foo'^M
sys.exec_prefix = 'foo'^M
sys.path = [^M
'foo/lib64/python39.zip',^M
'foo/lib64/python3.9',^M
'foo/lib64/python3.9/lib-dynload',^M
]^M
Fatal Python error: init_fs_encoding: failed to get the Python codec of the \
filesystem encoding^M
Python runtime state: core initialized^M
ModuleNotFoundError: No module named 'encodings'^M
^M
Current thread 0x00007fffabe18480 (most recent call first):^M
<no Python frame>^M
ERROR: (eof) GDB never initialized.
Couldn't send python print (1) to GDB.
UNRESOLVED: gdb.python/py-failed-init.exp: gdb-command<python print (1)>
Couldn't send quit to GDB.
UNRESOLVED: gdb.python/py-failed-init.exp: quit
...
The test-case expects gdb to present a prompt, but instead gdb calls exit
with this back trace:
...
(gdb) bt
#0 0x00007ffff6e4bfbc in exit () from /lib64/glibc-hwcaps/power10/libc.so.6
#1 0x00007ffff7873fc4 in fatal_error.lto_priv () from /lib64/libpython3.9.so.1.0
#2 0x00007ffff78aae60 in Py_ExitStatusException () from /lib64/libpython3.9.so.1.0
#3 0x00007ffff78c0e58 in Py_InitializeEx () from /lib64/libpython3.9.so.1.0
#4 0x0000000010b6cab4 in py_initialize_catch_abort () at gdb/python/python.c:2456
#5 0x0000000010b6cfac in py_initialize () at gdb/python/python.c:2540
#6 0x0000000010b6d104 in do_start_initialization () at gdb/python/python.c:2595
#7 0x0000000010b6eaac in gdbpy_initialize (extlang=0x11b7baf0 <extension_language_python>)
at gdb/python/python.c:2968
#8 0x000000001069d508 in ext_lang_initialization () at gdb/extension.c:319
#9 0x00000000108f9280 in captured_main_1 (context=0x7fffffffe870)
at gdb/main.c:1100
#10 0x00000000108fa3cc in captured_main (context=0x7fffffffe870)
at gdb/main.c:1372
#11 0x00000000108fa4d8 in gdb_main (args=0x7fffffffe870) at gdb/main.c:1401
#12 0x000000001001d1d8 in main (argc=3, argv=0x7fffffffece8) at gdb/gdb.c:38
...
This may be a python issue [1].
The problem doesn't happen if we use the PyConfig approach instead of the
py_initialize_catch_abort approach.
Fix this by using the PyConfig approach starting 3.9 (previously, starting
3.10 to avoid Py_SetProgramName deprecation in 3.11).
It's possible that we have the same problem and need the same fix for 3.8, but
I don't have a setup to check that. Add a todo in a comment.
Tested on ppc64le-linux.
Approved-By: Tom Tromey <tom@tromey.com>
[1] https://github.com/python/cpython/issues/107827
|
|
When GDB is built with undefined behavior sanitizer,
gdb.python/py-style.exp fails because of this:
$ ./gdb -q -nx --data-directory=data-directory -ex "python filename_style = gdb.Style('filename')" -ex "python filename_style.intensity = -3"
/home/simark/src/binutils-gdb/gdb/python/py-style.c:239:11: runtime error: load of value 4294967293, which is not a valid value for type 'intensity'
Fix it by casting the value to ui_file_style::intensity only after
validating the raw value.
Change-Id: I38eb471a9cb3bfc3bb8b2c88afa76b8025e4e893
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This commit moves the 'gdb_bfd_ref_ptr cbfd' out of program_space and
into core_target, where it is now called m_core_bfd.
I believe this change makes sense as the core_target instance holds
additional information that is parsed from the core file BFD, and so
storing the parsed information separately from the BFD doesn't make
much sense to me.
To minimise the churn in this commit, I have retained the
program_space::core_bfd member function as a temporary hack. This
function forwards the request to the new function
get_inferior_core_bfd. This works fine for now as
program_space::core_bfd is, after this commit, only called on the
current_program_space. If this all seems like a total hack, then it
is, but don't worry too much, the next commit will clean this all up.
I was tempted to make the new function get_inferior_core_bfd, a member
function of the inferior class, inferior::core_bfd. In fact, that
would have been my preferred change. However, the new function needs
visibility of the core_target class, which, right now is private
within the corelow.c file.
This shouldn't be a problem, we could just declare the member function
in inferior.h, and implement the function in corelow.c. But this
would mean the implementation of inferior::core_bfd, would not live in
inferior.c. Previously when I've implemented member functions outside
their natural home (e.g. an inferior function not in inferior.c) I've
received review feedback that this is not desirable. So, for now,
I've gone with a free function.
I also needed to change get_current_core_target, renaming it to
get_core_target, and taking an inferior as an argument. Existing call
sites are updated to pass 'current_inferior ()', but
get_inferior_core_bfd passes something that might not be the current
inferior.
There should be no user visible changes after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Same rationale as the previous patches.
Change-Id: I4673cedaa902c9a327d24d73508b18cf60a2cd02
Approved-By: Tom Tromey <tom@tromey.com>
|
|
pre-commit (really flake8) points out that a recent change to
frame_filters.py left an unused import. This patch fixes the problem.
|
|
With the recent addition of the gdb.Style Python API, this commit goes
through the gdb.Command sub-classes which we ship with GDB and adds
some styling support.
This adds 'title' style in a couple of places where we layout tables.
And uses 'filename' style where we are printing filenames.
While I was making these changes I've made a couple of related fixes.
In 'info frame-filter', 'info missing-objfile-handlers', 'info
pretty-printer', and 'info xmethod', we would sometimes print the
gdb.Progspace.filename unconditionally, even though this field can
sometimes be None. To better handle this case, I now check for None,
and print '<no-file>' instead. We already printed that same string
for the program space name in at least one other case, so this change
makes things a little more consistent.
I don't format the '<no-file>' string with the filename style, only if
we have an actual filename does the string get formatted.
The other fix I made was in 'maint info python-disassemblers'. Here
I've added an extra space between the two columns in the output
table. The two columns are 'Architecture' and 'Disassembler Name'.
Given that one column contains a white space, it was rather confusing
having a single space between columns. Luckily the tests don't depend
on a single space, so nothing needs updating for this change.
Additionally, in 'info frame-filter' I've updated the exception
handling to use the gdb.warning function, rather than just printing a
line of output. This means that should this case occur we get the
neat little emoji. We have no tests that trigger this warning, and I
couldn't figure out how to write one. In this end, I just hacked the
Python code to raise an exception and checked the output looked
reasonable. I suspect this warning might be a hard one to trigger!
Approved-By: Tom Tromey <tom@tromey.com>
|
|
The DAP breakpoint code has some helper functions that don't really
provide much value any more. This patch removes them.
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Add a new Corefile.mapped_files method which returns a list of
gdb.CorefileMappedFile objects.
Each gdb.CorefileMappedFile object represents a file that was mapped
into the process when the core file was created.
A gdb.CorefileMappedFile has attributes:
+ filename -- A string, the name of the mapped file.
+ build_id -- A string or None, the build-id of the mapped file if
GDB could find it (None if not).
+ is_main_executable -- A boolean, True if this mapping is the main
executable.
+ regions -- A list containing the regions of this file that were
mapped into the process.
The 'regions' list is a list of gdb.CorefileMappedFileRegion objects,
each of these objects has the following attributes:
+ start -- the start address within the inferior.
+ end -- the end address within the inferior.
+ file_offset -- the offset within the mapped file for this mapping.
There are docs and tests.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32844
Approved-By: Tom Tromey <tom@tromey.com>
|
|
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>
|
|
"pre-commit run --all" shows some flake8 warnings coming from a recent
patch. There was no real bug here, but this fix silences the
warnings.
|
|
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>
|
|
Add a new helper class gdb.StyleParameterSet. This new class can be
used to simplify creation of new style parameter sets. A style
parameter set is the 'foreground', 'background', and (optionally), the
'intensity' settings, all grouped under a single prefix command.
And example usage is:
(gdb) python s = gdb.StyleParameterSet("my-style")
(gdb) show style my-style
style my-style background: The "my-style" style background color is: none
style my-style foreground: The "my-style" style foreground color is: none
style my-style intensity: The "my-style" style display intensity is: normal
(gdb)
Having created a gdb.StyleParameterSet, the object itself can be used
to access a named style corresponding to the setting group, like this:
(gdb) python print(s.style)
<gdb.Style name='my-style', fg=none, bg=none, intensity=normal>
(gdb)
Of course, having access to the gdb.Style makes it easy to change the
settings, or the settings can be adjusted via the normal CLI 'set'
commands.
As gdb.StyleParameterSet manages a set of parameters, and the
gdb.Parameter class uses Parameter.value as the attribute to read the
parameter's value, there is also StyleParameterSet.value, but this is
just an alias for StyleParameterSet.style, that is, it allows the
gdb.Style object to be read and written too.
It is worth noting that this class only creates a single level of
prefix command. As an example GDB has style 'disassembler mnemonic',
where the 'disassembler' part is a group of related styles. If a user
wanted to create:
style
my-style-group
style-1
style-2
style-3
Where each of 'style-1', 'style-2', and 'style-3' will have the full
set of 'foreground', 'background', and 'intensity', then the
gdb.StyleParameterSet can be used to create the 'style-N' part, but
the user will have to create the 'my-style-group' prefix themselves,
possibly using gdb.ParameterPrefix, e.g.:
gdb.ParameterPrefix("style my-style-group", gdb.COMMAND_NONE)
gdb.StyleParameterSet("my-style-group style-1")
gdb.StyleParameterSet("my-style-group style-2")
gdb.StyleParameterSet("my-style-group style-3")
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This commit adds a new gdb.Style class. This class represents a
complete style within GDB. A complete style is a collection of
foreground color, background color, and an intensity.
A gdb.Style comes in two flavours, named, and unnamed.
A named style is one that is based on an existing style within GDB.
For example, we have 'set style filename ...', the name of this style
is 'filename'. We also have 'set style disassembler mnemonic ...',
the name of this style is 'disassembler mnemonic'. A named style is
created by passing the name of the style, like this:
(gdb) python s1 = gdb.Style("filename")
(gdb) python s2 = gdb.Style("disassembler mnemonic")
The other type of style is an unnamed style. An unnamed style is
created using a foreground and background color, along with an
intensity. Colors are specified using gdb.Color objects. An example
of creating an unnamed style is:
(gdb) python s3 = gdb.Style(foreground=gdb.Color('red'),
background=gdb.Color('green'),
intensity=gdb.INTENSITY_BOLD)
We can see here an example of the new intensity constants that have
been added in this commit, there is gdb.INTENSITY_NORMAL,
gdb.INTENSITY_BOLD, and gdb.INTENSITY_DIM. All of the arguments are
optional, the default for the colors is gdb.Color(), which will apply
the terminal default, and the default intensity is
gdb.INTENSITY_NORMAL.
Having created a gdb.Style object there are two ways that it can be
used to style GDB's output. The Style.escape_sequence() method
returns the escape sequence needed to apply this style, this can be
used as in:
(gdb) python print(s1.escape_sequence() + "Filename Style")
The problem with this approach is that it is the users responsibility
to restore the style to the default when they are done. In the above
example, all output after the escape sequence is printed, including
the next GDB prompt, will be in the s1 (filename) style. Which is why
the Style.apply method exists. This method takes a string and returns
the same string with escape sequences added before and after. The
before sequence switches to the style, while the after escape sequence
restores the terminal default style. This can be used like:
(gdb) python print(s1.apply("Filename Style"))
Now only the 'Filename Style' text will be styled. The next GDB
prompt will be in the default terminal style. Personally, I think the
apply method is the more useful, but having 'escape_sequence' matches
what gdb.Color offers, though if/when this patch is merged, I might
propose a similar 'apply' type method for the gdb.Color class.
The gdb.Style class has 'foreground', 'background', and 'intensity'
attributes which, when read, return the obvious values. These
attributes can also be written too.
When writing to an attribute of an unnamed Style object then the Style
object itself is updated, as you might expect.
When writing to an attribute of a named Style then the style setting
itself is updated as the following example shows:
(gdb) python s1 = gdb.Style("filename")
(gdb) python print(s1.foreground)
green
(gdb) show style filename foreground
The "filename" style foreground color is: green
(gdb) python s1.foreground=gdb.Color("red")
(gdb) python print(s1.foreground)
red
(gdb) show style filename foreground
The "filename" style foreground color is: red
(gdb)
We can see that a gdb.Style object is connected to the underlying
style settings, it doesn't take a copy of the style settings at
creation time. And the relationship works both ways. Continuing the
above example:
(gdb) set style filename foreground blue
(gdb) python print(s1.foreground)
blue
(gdb)
Here we see that changing the setting value causes the gdb.Style
object to update. And this is what you would want. I imagine this
being used in a Python extension to GDB, where a user might create
global objects for some named styles, and then use these globals to
format output from some custom commands. If a user of an extension
changes a style setting then the extension wants to adapt to that
change.
Both the Style.escape_sequence and Style.apply methods take the global
style enabled setting into consideration. If styling is disabled then
Style.escape_sequence will return an empty string, and Style.apply
will return an unmodified copy of the original string object (actually
the input object with Py_INCREF applied).
There is also support for representing a gdb.Style as a string:
(gdb) python s1 = gdb.Style("filename")
(gdb) python print(s1)
<gdb.Style name='filename', fg=green, bg=none, intensity=normal>
(gdb)
Unnamed styles are similar, but don't have a 'name' field.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
gdb.lookup_type accepts a 'block' argument, but in some cases does not
use it. This can cause the wrong type to be returned.
This patch fixes the problem by simply passing the block through. I
have no idea why it worked the way it did, and there weren't any tests
for the 'block' parameter. (I didn't look at git blame out of fear
that it was my patch back in the day.)
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16942
|
|
Some code in next.py avoids exec_and_log due to its exception
behavior. Now that exec_and_log always forwards exceptions, this is
easily fixed.
|
|
This changes the DAP exec_and_log function to always transform an
exception into a DAPException and propagate it.
As the bug points out, we haven't always wrapped calls when
appropriate. I think it's better to cause the request to fail by
default; if any spot truly needs to ignore errors, that is readily
done at the point of call.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33346
|
|
The Invoker used to be more convenient, before DAP requests were run
on the gdb thread by default. Now it is barely used and easily
replaced by a couple of lambdas.
|
|
Currently, the gdb DAP implementation doesn't provide a way to filter
based on the thrown Ada exception.
There isn't really an ideal way to handle this in DAP:
* Requiring an IDE to use an expression checking $_ada_exception
exposes the IDE to any workarounds needed to get this correct (see
ada-lang.c).
* The setExceptionBreakpoint "filterOptions" field doesn't allow a
special kind of condition to be set. (We could add one but we've
generally avoided gdb-specific extensions.)
* The "exceptionOptions" approach is under-documented. It could be
used but it would have to be in a somewhat gdb-specific way anyway
-- and this approach does not allow a separate condition that is an
expression.
So, after some internal discussion, we agreed that it isn't all that
useful to have conditions on Ada exception catchpoints. This patch
changes the implementation to treat the condition as an exception name
here.
|
|
This changes gdb.printing.make_visualizer to treat an optimized-out
pointer as a scalar variable -- that is, one that does not advertise
any children. This makes sense because such a pointer cannot be
dereferenced.
The test case checks this case, plus it ensures that synthetic
pointers still continue to work.
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
The documentation says that ThreadExitedEvent is derived from
ThreadEvent, but the code does not actually implement this.
This patch fixes the problem. I propose applying this to gdb 17 as
well.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33444
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
After this series, expand_symtabs_matching is now misnamed. This
patch renames it, renames some associated types, and also fixes up
some comments that I previously missed.
Acked-By: Simon Marchi <simon.marchi@efficios.com>
|
|
This changes gdbpy_lookup_static_symbols to the callback approach,
merging the search loop and the call to expand_symtabs_matching.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16994
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16998
Acked-By: Simon Marchi <simon.marchi@efficios.com>
|
|
gdb currently crashes if you try to get the dynamic_type from a
gdb.Value of a POD struct:
(gdb) py print(gdb.parse_and_eval('pod').dynamic_type)
Fatal signal: Segmentation fault
It happens because value_rtti_type() returns NULL for them, and this is
not handled correctly.
Fixed by using val->type() as a fallback in this case.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
PR ada/33217 points out that gdb incorrectly calls the <ctype.h>
functions. In particular, gdb feels free to pass a 'char' like:
char *str = ...;
... isdigit (*str)
This is incorrect as isdigit only accepts EOF and values that can be
represented as 'unsigned char' -- that is, a cast is needed here to
avoid undefined behavior when 'char' is signed and a character in the
string might be sign-extended. (As an aside, I think this API seems
obviously bad, but unfortunately this is what the standard says, and
some systems check this.)
Rather than adding casts everywhere, this changes all the code in gdb
that uses any <ctype.h> API to instead call the corresponding c-ctype
function.
Now, c-ctype has some limitations compared to <ctype.h>. It works as
if the C locale is in effect, so in theory some non-ASCII characters
may be misclassified. This would only affect a subset of character
sets, though, and in most places I think ASCII is sufficient -- for
example the many places in gdb that check for whitespace.
Furthermore, in practice most users are using UTF-8-based locales,
where these functions aren't really informative for non-ASCII
characters anyway; see the existing workarounds in gdb/c-support.h.
Note that safe-ctype.h cannot be used because it causes conflicts with
readline.h. And, we canot poison the <ctype.h> identifiers as this
provokes errors from some libstdc++ headers.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33217
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Currently, trying to convert a 128-bit integer from a gdb.Value to a
Python integer will fail. This is surprising because Python uses
bigints internally.
The bug here is that valpy_long uses value_as_long, which fails for
anything wider than LONGEST. This patch fixes the problem by using
the recommended Python API.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33366
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
In VariableReference.to_object, we try to convert a gdb.Value to an
int without checking if the value is actually available. This came to
light in PR gdb/33345, after the x86 CET shadow stack patches were
merged.
If the x86 CET shadow stack register is available on the machine,
but the shadow stack feature is not enabled at run time, then the
register will show as "<unavailable>".
As the register is of type 'void *', then in the DAP code we try to
add a 'memoryReference' attribute with the value of the register
formatted as hex. This will fail if the register is unavailable.
To test this change you'll need:
(a) a machine which support the shadow stack feature, and
(b) to revert the changes from commit 63b862be762e1e6e7 in the file
gdb.dap/scopes.exp.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33345
Reviewed-By: Christina Schimpe <christina.schimpe@intel.com>
|
|
Add a new gdb.Value.is_unavailable attribute. This is similar to the
existing Value.is_optimized_out attribute, but returns True if any
part of the value is <unavailable>.
The existing Value.is_optimized_out attribute returns true if any part
of the value is optimized out, so I thought that Value.is_unavailable
should work the same way.
There's also a test.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33345
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Christina Schimpe <christina.schimpe@intel.com>
|
|
For background, see this thread:
https://inbox.sourceware.org/gdb-patches/20250612144607.27507-1-tdevries@suse.de
Tom describes the issue clearly in the above thread, here's what he
said:
Once in a while, when running test-case gdb.base/bp-cmds-continue-ctrl-c.exp,
I run into:
...
Breakpoint 2, foo () at bp-cmds-continue-ctrl-c.c:23^M
23 usleep (100);^M
^CFAIL: $exp: run: stop with control-c (unexpected) (timeout)
FAIL: $exp: run: stop with control-c
...
This is PR python/32167, observed both on x86_64-linux and powerpc64le-linux.
This is not a timeout due to accidental slowness, gdb actually hangs.
The backtrace at the hang is (on cfarm120 running AlmaLinux 9.6):
...
(gdb) bt
#0 0x00007fffbca9dd94 in __lll_lock_wait () from
/lib64/glibc-hwcaps/power10/libc.so.6
#1 0x00007fffbcaa6ddc in pthread_mutex_lock@@GLIBC_2.17 () from
/lib64/glibc-hwcaps/power10/libc.so.6
#2 0x000000001067aee8 in __gthread_mutex_lock ()
at /usr/include/c++/11/ppc64le-redhat-linux/bits/gthr-default.h:749
#3 0x000000001067afc8 in __gthread_recursive_mutex_lock ()
at /usr/include/c++/11/ppc64le-redhat-linux/bits/gthr-default.h:811
#4 0x000000001067b0d4 in std::recursive_mutex::lock ()
at /usr/include/c++/11/mutex:108
#5 0x000000001067b380 in std::lock_guard<std::recursive_mutex>::lock_guard ()
at /usr/include/c++/11/bits/std_mutex.h:229
#6 0x0000000010679d3c in set_quit_flag () at gdb/extension.c:865
#7 0x000000001066b6dc in handle_sigint () at gdb/event-top.c:1264
#8 0x00000000109e3b3c in handler_wrapper () at gdb/posix-hdep.c:70
#9 <signal handler called>
#10 0x00007fffbcaa6d14 in pthread_mutex_lock@@GLIBC_2.17 () from
/lib64/glibc-hwcaps/power10/libc.so.6
#11 0x000000001067aee8 in __gthread_mutex_lock ()
at /usr/include/c++/11/ppc64le-redhat-linux/bits/gthr-default.h:749
#12 0x000000001067afc8 in __gthread_recursive_mutex_lock ()
at /usr/include/c++/11/ppc64le-redhat-linux/bits/gthr-default.h:811
#13 0x000000001067b0d4 in std::recursive_mutex::lock ()
at /usr/include/c++/11/mutex:108
#14 0x000000001067b380 in std::lock_guard<std::recursive_mutex>::lock_guard ()
at /usr/include/c++/11/bits/std_mutex.h:229
#15 0x00000000106799cc in set_active_ext_lang ()
at gdb/extension.c:775
#16 0x0000000010b287ac in gdbpy_enter::gdbpy_enter ()
at gdb/python/python.c:232
#17 0x0000000010a8e3f8 in bpfinishpy_handle_stop ()
at gdb/python/py-finishbreakpoint.c:414
...
What happens here is the following:
- the gdbpy_enter constructor attempts to set the current extension language
to python using set_active_ext_lang
- set_active_ext_lang attempts to lock ext_lang_mutex
- while doing so, it is interrupted by sigint_wrapper (the SIGINT handler),
handling a SIGINT
- sigint_wrapper calls handle_sigint, which calls set_quit_flag, which also
tries to lock ext_lang_mutex
- since std::recursive_mutex::lock is not async-signal-safe, things go wrong,
resulting in a hang.
The hang bisects to commit 8bb8f834672 ("Fix gdb.interrupt race"), which
introduced the lock, making PR python/32167 a regression since gdb 15.1.
Commit 8bb8f834672 fixes PR dap/31263, a race reported by ThreadSanitizer:
...
WARNING: ThreadSanitizer: data race (pid=615372)
Read of size 1 at 0x00000328064c by thread T19:
#0 set_active_ext_lang(extension_language_defn const*) gdb/extension.c:755
#1 scoped_disable_cooperative_sigint_handling::scoped_disable_cooperative_sigint_handling()
gdb/extension.c:697
#2 gdbpy_interrupt gdb/python/python.c:1106
#3 cfunction_vectorcall_NOARGS <null>
Previous write of size 1 at 0x00000328064c by main thread:
#0 scoped_disable_cooperative_sigint_handling::scoped_disable_cooperative_sigint_handling()
gdb/extension.c:704
#1 fetch_inferior_event() gdb/infrun.c:4591
...
Location is global 'cooperative_sigint_handling_disabled' of size 1 at 0x00000328064c
...
SUMMARY: ThreadSanitizer: data race gdb/extension.c:755 in \
set_active_ext_lang(extension_language_defn const*)
...
The problem here is that gdb.interrupt is called from a worker thread, and its
implementation, gdbpy_interrupt races with the main thread on some variable.
The fix presented here is based on the fix that Tom proposed, but
fills in the missing Mingw support.
The problem is basically split into two: hosts that support unix like
signals, and Mingw, which doesn't support signals.
For signal supporting hosts, I've adopted the approach that Tom
suggests, gdbpy_interrupt uses kill() to send SIGINT to the GDB
process. This is then handled in the main thread as if the user had
pressed Ctrl+C. For these hosts no locking is required, so the
existing lock is removed. However, everywhere the lock currently
exists I've added an assert:
gdb_assert (is_main_thread ());
If this assert ever triggers then we're setting or reading the quit
flag on a worker thread, this will be a problem without the mutex.
For Mingw, the current mutex is retained. This is fine as there are
no signals, so no chance of the mutex acquisition being interrupted by
a signal, and so, deadlock shouldn't be an issue.
To manage the complexity of when we need an assert, and when we need
the mutex, I've created 'struct ext_lang_guard', which can be used as
a RAII object. This object either performs the assertion check, or
acquires the mutex, depending on the host.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32167
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
In this commit:
commit dbd05b9edcf760a7001985f89bc760358a3c19d7
Date: Wed Aug 20 10:45:09 2025 +0100
gdb/python: check return value of PyObject_New in all cases
I missed a call to PyObject_New in python/py-disasm.c, which this
commit addresses.
Unlike the previous commit, the call to PyObject_New in py-disasm.c is
contained within the scoped_disasm_info_object class, which makes it
harder to check for NULL and return.
So in this commit I've rewritten the scoped_disasm_info_object class,
moving the call to PyObject_New out into gdbpy_print_insn, which is
the only place that scoped_disasm_info_object was being used.
As scoped_disasm_info_object is no longer responsible for creating the
underlying Python object, I figured that I might as well move the
initialisation of that object out of scoped_disasm_info_object too.
With that done, the scoped_disasm_info_object now has just one task,
invalidating the existing disasm_info_object at the end of the scope.
So I renamed scoped_disasm_info_object to
scoped_invalidate_disasm_info, which reflects its only task.
I made a couple of other small adjustments that were requested during
review, these are both in the same code area: updating
disasm_info_fill to take an object reference rather than a pointer,
and removing the local variable insn_disas_obj from gdbpy_print_insn,
and inline its value at the one place it was used.
There should be no user visible changes after this commit. Except for
the PyObject_New call, which now has proper error checking. But in
the working case, nothing should have changed.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
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>
|
|
I noticed a possible memory leak in gdbpy_create_ptid_object, in
py-infthread.c. We create a Tuple, and hold the reference in a
'PyObject*' local.
If we then fail to create any of the tuple contents we perform an
early exit, returning nullptr, this will leak the Tuple object.
Currently, we create the Tuple as the first action in the function,
but we don't really need the tuple until the end of the function.
In this commit I have:
1. Moved creation of the Tuple until the end of the function, just
before we need it.
2. Stored the Tuple reference in a gdbpy_ref<>. This is not
strictly needed any more, but is (I think) good practice as
future changes to the function will not need to worry about
releasing the Tuple object.
3. Taken the opportunity to replace a NULL with nullptr in this
function.
4. Inlined the local variable declarations to the point of first
use.
There should be no user visible changes after this commit.
No tests as I have no idea how to make gdb_py_object_from_longest (and
friends) fail, and so trigger the memory leak. I suspect we'd never
actually see this leak in the real world, but it doesn't hurt to clean
these things up.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
This commit allows gdb.Color objects to be used to style output from
GDB commands written in Python, and the styled output should work
correctly with pagination.
There are two parts to fixing this:
First, GDB needs to be able to track the currently applied style
within the page_file class. This means that style changes need to be
achieved with calls to pager_file::emit_style_escape.
Now usually, GDB does this by calling something like fprintf_styled,
which takes care to apply the style for us. However, that's not
really an option here as a gdb.Color isn't a full style, and as the
gdb.Color object is designed to be converted directly into escape
sequences that can then be printed, we really need a solution that
works with this approach.
However pager_file::puts already has code in place to handle escape
sequences. Right now all this code does is spot the escape sequence
and append it to the m_wrap_buffer. But in this commit I propose that
we go one step further, parse the escape sequence back into a
ui_file_style object in pager_file::puts, and then we can call
pager_file::emit_style_escape.
If the parsing doesn't work then we can just add the escape sequence
to m_wrap_buffer as we did before.
But wait, how can this work if a gdb.Color isn't a full style? Turns
out that's not a problem. We only ever emit the escape sequence for
those parts of a style that need changing, so a full style that sets
the foreground color will emit the same escape sequence as a gdb.Color
for the foreground. When we convert the escape sequence back into a
ui_file_style, then we get a style with everything set to default,
except the foreground color.
I had hoped that this would be all that was needed. But unfortunately
this doesn't work because of the second problem...
... the implementation of the Python function gdb.write() calls
gdb_printf(), which calls gdb_vprintf(), which calls ui_file::vprintf,
which calls ui_out::vmessage, which calls ui_out::call_do_message, and
finally we reach cli_ui_out::do_message. This final do_message
function does this:
ui_file *stream = m_streams.back ();
stream->emit_style_escape (style);
stream->puts (str.c_str ());
stream->emit_style_escape (ui_file_style ());
If we imagine the case where we are emitting a style, triggered from
Python like this:
gdb.write(gdb.Color('red').escape_sequence(True))
the STYLE in this case will be the default ui_file_style(), and STR
will hold the escape sequence we are writing.
After the first change, where pager_file::puts now calls
pager_file::emit_style_escape, the current style of STREAM will have
been updated. But this means that the final emit_style_escape will
now restore the default style.
The fix for this is to avoid using the high level gdb_printf from
gdb.write(), and instead use gdb_puts instead. The gdb_puts function
doesn't restore the default style, which means our style modification
survives.
There's a new test included. This test includes what appears like a
pointless extra loop (looping over a single value), but this makes
sense given the origin of this patch. I've pulled this commit from a
longer series:
https://inbox.sourceware.org/gdb-patches/cover.1755080429.git.aburgess@redhat.com
I want to get this bug fix merged before GDB 17 branches, but the
longer series is not getting reviews, so for now I'm just merging this
one fix. Once the rest of the series gets merged, I'll be extending
the test, and the loop (mentioned above) will now loop over more
values.
|
|
solib_ops
Change the "iterate over objfiles in search order" operation from a
gdbarch method to methods on both program_space and solib_ops.
The first motivation for this is that I want to encapsulate solib-svr4's
data into svr4_solib_ops (in a subsequent series), instead of it being
in a separate structure (svr4_info). It is awkward to do so as long as
there are entry points that aren't the public solib_ops interface.
The second motivation is my project of making it able to have multiple
solib_ops per program space (which should be the subject of said
subsequent series), to better support heterogenousa systems (like ROCm,
with CPU and GPU in the same inferior). When we have this, when stopped
in GPU code, it won't make sense to ask the host's architecture to do
the iteration, as the logic could be different for the GPU architecture.
Instead, program_space::iterate_over_objfiles_in_search_order will be
responsible to delegate to the various solib_ops using a logic that is
yet to be determined.
I included this patch in this series (rather than the following one)
so that svr4_solib_ops::iterate_over_objfiles_in_search_order can access
svr4_solib_ops::default_debug_base, introduced in a later patch in this
series.
default_iterate_over_objfiles_in_search_order becomes the default
implementation of solib_ops::iterate_over_objfiles_in_search_order.
As far as I know, all architectures using
svr4_iterate_over_objfiles_in_search_order also use solib_ops_svr4, so I
don't expect this patch to cause behavior changes.
Change-Id: I71f8a800b8ce782ab973af2f2eb5fcfe4e06ec76
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
|
|
I spotted a few cases where the return value of PyObject_New was not
being checked against nullptr, but we were dereferencing the result.
All fixed here. The fixed functions can now return NULL, so I checked
all the callers, and I believe there will handle a return of NULL
correctly.
Assuming calls to PyObject_New never fail, there should be no user
visible changes after this commit.
No tests here as I don't know how we'd go about causing a Python
object allocation to fail.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|