Commit graph

1857 commits

Author SHA1 Message Date
Tom Tromey
f20c97f00d Remove Py_TPFLAGS_CHECKTYPES
According to 'git annotate', the Py_TPFLAGS_CHECKTYPES was added to
python-internal.h way back when gdb was first ported to Python 3.  It
was a compatibility fix for Python 2.

This is not needed any more, because Python 2 is no longer supported.
This patch removes the vestiges.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-10-23 07:43:00 -06:00
Simon Marchi
a5cbe67512 gdb, gdbserver, gdbsupport: trim trailing whitespaces
I noticed my IDE (VSCode) starting to automatically trim trailing
whitespaces on save, despite the setting for it being disabled.  I
realized that this is because the .editorconfig file now has

    trim_trailing_whitespace = true

for many file types.  If we have this EditorConfig setting forcing
editors to trim trailing whitespaces, I think it would make sense to
clean up trailing whitespaces from our files.  Otherwise, people will
always get spurious whitespace changes when editing these files.

I did a mass cleanup using this command:

$ find gdb gdbserver gdbsupport -type f \( \
    -name "*.c" -o \
    -name "*.h" -o \
    -name "*.cc" -o \
    -name "*.texi" -o \
    -name "*.exp" -o \
    -name "*.tcl" -o \
    -name "*.py" -o \
    -name "*.s" -o \
    -name "*.S" -o \
    -name "*.asm" -o \
    -name "*.awk" -o \
    -name "*.ac" -o \
    -name "Makefile*" -o \
    -name "*.sh" -o \
    -name "*.adb" -o \
    -name "*.ads" -o \
    -name "*.d" -o \
    -name "*.go" -o \
    -name "*.F90" -o \
    -name "*.f90" \
\) -exec sed -ri 's/[ \t]+$//' {} +

I then did an autotools regen, because we don't actually want to change
the Makefile and Makefile.in files that are generated.

Change-Id: I6f91b83e3b8c4dc7d5d51a2ebf60706120efe691
2025-10-20 15:44:08 -04:00
Simon Marchi
2fe07655c6 gdb: rename find_pc_line -> find_sal_for_pc
Change-Id: I293b655e8753fc650f3ec10bb4e34a9632d8e377
Approved-by: Kevin Buettner <kevinb@redhat.com>
2025-10-20 15:12:40 -04:00
Simon Marchi
3845baa0c6 gdb: rename find_pc_compunit_symtab -> find_compunit_symtab_for_pc
Change-Id: I6eef5db4ae55f3eb0415768207ae3c26b305f773
Approved-by: Kevin Buettner <kevinb@redhat.com>
2025-10-20 15:11:39 -04:00
Simon Marchi
dffd081f7f gdb: rename find_pc_function -> find_symbol_for_pc
Change-Id: I2069be1a6d7c3250cf330574c941bf851c89bab4
Approved-by: Kevin Buettner <kevinb@redhat.com>
2025-10-20 15:11:39 -04:00
Tom de Vries
421086df8f [gdb/python] Use PyConfig for python 3.9
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
2025-10-17 20:27:40 +02:00
Simon Marchi
4cab44595e gdb/python: cast to ui_file_style::intensity after validating value
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>
2025-10-08 14:57:57 -04:00
Andrew Burgess
c97e57bc9d gdb: move core file bfd from program_space into core_target
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>
2025-10-08 13:29:06 +01:00
Simon Marchi
f772ad29ab gdb: change objfiles_iterator to yield references
Same rationale as the previous patches.

Change-Id: I4673cedaa902c9a327d24d73508b18cf60a2cd02
Approved-By: Tom Tromey <tom@tromey.com>
2025-10-07 16:22:15 -04:00
Tom Tromey
7f1cdb3e37 Remove 'sys' import from frame_filters.py
pre-commit (really flake8) points out that a recent change to
frame_filters.py left an unused import.  This patch fixes the problem.
2025-10-07 13:08:19 -06:00
Andrew Burgess
01040a24d9 gdb/python: make use of gdb.Style for shipped Python commands
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>
2025-10-07 16:35:44 +01:00
Tom Tromey
6d3af8c9f6 Remove some helper functions from DAP breakpoint code
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>
2025-10-07 08:18:30 -06:00
Andrew Burgess
f69c1d03c4 gdb/python: add Corefile.mapped_files method
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>
2025-10-06 16:56:56 +01:00
Andrew Burgess
7862554bcf gdb/python: introduce gdb.Corefile API
This commit starts adding some core file related features to the
Python API.

In this initial commit I've tried to keep the changes as small as
possible for easy review.

There's a new Python class gdb.Corefile, which represents a loaded
core file.  This API doesn't allow the user to create their own
gdb.Corefile objects, a core file must be loaded using the 'core-file'
command, then a gdb.Corefile object can be obtained by querying the
inferior in which the core file was loaded.

There's a new attribute gdb.Inferior.corefile, this is None when no
core file is loaded, or contains a gdb.Corefile object if a core file
has been loaded.

Currently, the gdb.Corefile object has one attribute, and one method,
these are:

  gdb.Corefile.filename -- the file name of the loaded core file.

  gdb.Corefile.is_valid() -- indicates if a gdb.Corefile object is
  valid or not.  See notes below.

A gdb.Corefile object is only valid while the corresponding core file
is loaded into an inferior.  Unloading the core file, or loading a
different one will cause a gdb.Corefile object to become invalid.  For
example:

  (gdb) core-file /tmp/core.54313
  ... snip ...
  (gdb) python core=gdb.selected_inferior().corefile
  (gdb) python print(core)
  <gdb.Corefile inferior=1 filename='/tmp/core.54313'>
  (gdb) python print(core.is_valid())
  True
  (gdb) core-file
  No core file now.
  (gdb) python print(core)
  <gdb.Corefile (invalid)>
  (gdb) python print(core.is_valid())
  False
  (gdb)

In order to track changes to the core file, there is a new observable
'core_file_changed', which accounts for the changes in corelow.c,
observable,c, and observable.h.  Currently, this observable is not
visible as a Python event.

I chose to access the core file via the inferior even though the core
file BFD object is actually stored within the program_space.  As such,
it might seem that the natural choice would be to add the attribute as
gdb.Progspace.corefile.

For background reading on my choice, please see:

  https://inbox.sourceware.org/gdb-patches/577f2c47793acb501c2611c0e6c7ea379f774830.1668789658.git.aburgess@redhat.com

This patch was never merged, it is still on my backlog, but the
observation in that work is that some targets are not really
shareable.  For example, the core_target (corelow.c) stores
information about the loaded core file within the target instance.  As
such, each target instance represents a single loaded core file.

Except that the BFD part of the core file is stored in the
program_space, which is a little weird.

During review, Tom made the observation, that maybe we should
investigate moving the core file BFD into the core_target.  I'm
inclined to agree with this as a direction of travel.

All this leaves us with two observations:

  1. Currently, loading a core file into an inferior, then using
     'add-inferior' will try to share the core_target between
     inferiors.  This is broken, and can trigger GDB crashes.  The
     obvious fix, without reworking core_target, is just to prevent
     this sharing, making core_target per-inferior.

  2. Having the core file information split between the core_target
     instance, and the BFD stored in the program_space is a little
     weird, and is really just historical.  Planning for a future
     where the BFD is also stored in the core_target might be wise.

So, if we imagine that the BFD is (one day) moved into the
core_target, and that the core_target really becomes non-shareable,
then it is, I think, clearer that the corefile attribute should live
on the gdb.Inferior object, not the gdb.Progspace object.

There's testing for all the functionality added in this commit.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32844

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
2025-10-06 16:56:55 +01:00
Tom Tromey
484f699d21 Fix some flake8 warnings
"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.
2025-10-05 11:49:12 -06:00
Andrew Burgess
3c72459681 gdb/python: extend gdb.write to support styled output
It is already possible to produce styled output from Python by
converting the gdb.Style to its escape code sequence, and writing that
to the output stream.

But this commit adds an alternative option to the mix by extending the
existing gdb.write() function to accept a 'style' argument.  The value
of this argument can be 'None' to indicate no style change should be
performed, this is the default, and matches the existing behaviour.

Or the new 'style' argument can be a gdb.Style object, in which case
the specified style is applied only for the string passed to
gdb.write, after which the default style is re-applied.

Using gdb.write with a style object more closely matches how GDB
handles styling internally, and has the benefit that the user doesn't
need to remember to restore the default style when they are done.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
2025-10-05 13:48:06 +01:00
Andrew Burgess
d5214580a5 gdb/python: new class gdb.StyleParameterSet
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>
2025-10-05 13:47:18 +01:00
Andrew Burgess
49e4d0cdca gdb/python: add gdb.Style class
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>
2025-10-05 13:40:46 +01:00
Tom Tromey
7d43a7afc1 Fix bug in gdb.lookup_type
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
2025-09-30 08:08:30 -06:00
Tom Tromey
efdb47cc20 Use exec_and_log in next.py
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.
2025-09-26 09:29:14 -06:00
Tom Tromey
ecac42af73 Always propagate exceptions in DAP
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
2025-09-26 09:29:13 -06:00
Tom Tromey
e14efc5bf7 Remove Invoker class from DAP
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.
2025-09-26 09:29:13 -06:00
Tom Tromey
e957baea20 Change DAP condition for Ada exception catchpoint
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.
2025-09-19 11:33:30 -06:00
Tom Tromey
fba8ff16a1 Handle optimized-out values in gdb.printing.make_visualizer
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>
2025-09-19 09:26:45 -06:00
Tom Tromey
3a9f5df6ea Have gdb.ThreadExitedEvent inherit from gdb.ThreadEvent
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>
2025-09-18 08:07:49 -06:00
Tom Tromey
ae912a65f9 Rename expand_symtabs_matching
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>
2025-09-10 16:07:58 -06:00
Tom Tromey
1696b45a63 Convert gdbpy_lookup_static_symbols
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>
2025-09-10 16:05:28 -06:00
Hannes Domani
b7e3459d2c Fix gdb.Value.dynamic_type attribute
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>
2025-09-09 21:11:27 +02:00
Tom Tromey
3719472095 Use gnulib c-ctype module in gdb
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>
2025-09-09 11:59:04 -06:00
Tom Tromey
2769710301 Allow conversion of 128-bit integers to Python
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>
2025-09-05 11:28:42 -06:00
Andrew Burgess
650400cb53 gdb/dap: check values are available before converting to int
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 63b862be76 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>
2025-09-04 22:18:59 +01:00
Andrew Burgess
b652ce7b80 gdb/python: add gdb.Value.is_unavailable attribute
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>
2025-09-04 22:18:59 +01:00
Andrew Burgess
7f15a94e65 gdb: use kill() in gdbpy_interrupt for hosts with signal support
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 8bb8f83467 ("Fix gdb.interrupt race"), which
  introduced the lock, making PR python/32167 a regression since gdb 15.1.

  Commit 8bb8f83467 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>
2025-08-29 15:41:08 +01:00
Andrew Burgess
8d9a7d8914 gdb/python: check return from final PyObject_New in py-disasm.c
In this commit:

  commit dbd05b9edc
  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>
2025-08-28 15:51:16 +01:00
Andrew Burgess
f5493d6c96 gdb/python: return gdbpy_ref<> from gdbpy_create_ptid_object
Update gdbpy_create_ptid_object (python/py-infthread.c) to return a
gdbpy_ref<> rather than a 'PyObject *'.  This reduces the chances that
a caller will leak an object, though no such memory leaks are fixed in
this commit, this is just a code improvement patch.

There should be no user visible changes after this commit.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-08-26 22:02:40 +01:00
Andrew Burgess
0a50707947 gdb/python: fix an unlikely memory leak
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>
2025-08-26 15:52:05 +01:00
Andrew Burgess
3825c972a6 gdb: allow gdb.Color to work correctly with pagination
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.
2025-08-24 16:57:32 +01:00
Simon Marchi
fbb487b451 gdb: make iterate_over_objfiles_in_search_order methods of program_space and 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>
2025-08-22 10:45:47 -04:00
Andrew Burgess
dbd05b9edc gdb/python: check return value of PyObject_New in all cases
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>
2025-08-21 11:47:17 +01:00
Simon Marchi
4260abb7a7 gdb: rename address_class -> location_class
The enum address_class and related fields and methods seem misnamed to
me.  Generalize it to "location_class".  The enumerators in
address_class are already prefixed with LOC, so the new name seems
logical to me.  Rename related fields and methods as well.

Plus, address_class could easily be mistaken for other unrelated things
named "address class" in GDB or DWARF.

Tested by rebuilding.

Change-Id: I0dca3738df412b350715286c608041b08e9b4d82
Approved-by: Kevin Buettner <kevinb@redhat.com>
2025-08-19 09:49:46 -04:00
Guinevere Larsen
a1be365e22 gdb: modernize get_frame_pc_if_available
The convenience function get_frame_pc_if_available would take a pointer
to a variable that should be set if available, and would return a
boolean indicating whether that action was successful or not.

Now that GDB supports C++17 features, this indirection of a pointer and
returning boolean is unnecessary, since the function can return an
optional, and code that calls it can check if the optional contains a
value.

This commit makes that modernization. It should have no visible
effects.

Approved-By: Tom Tromey <tom@tromey.com>
2025-08-14 13:40:19 -03:00
Tom Tromey
89495c3326 Change type::fields to return an array_view
This patch changes type::fields to return an array_view of the fields,
then fixes up the fallout.

More cleanups would be possible here (in particular in the field
initialization code) but I haven't done so.

The main motivation for this patch was to make it simpler to iterate
over the fields of a type.

Regression tested on x86-64 Fedora 41.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2025-08-12 08:30:37 -06:00
Tom Tromey
9ef3249a00 Emit DAPException when too many variable children are reqeusted
PR dap/33228 points out a failure that occurs when the DAP client
requests more children of a variable than actually exist.  Currently,
gdb throws a somewhat confusing exception.  This patch changes this
code to throw a DAPException instead, resulting in a more ordinary and
readable failure.

The spec seems to be silent on what to do in this case.  I chose an
exception on the theory that it's easier to be strict now and lift the
restriction later (if needed) than vice versa.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33228
2025-08-11 07:39:10 -06:00
Tom Tromey
ddd2795c52 Do not allow DAP clients to dereference "void *"
While investigating a different bug, I noticed that the DAP code would
report a "void *"-typed register as having children -- however,
requesting the children of this register would fail.

The issue here is that a plain "void *" can't be dereferenced.  This
patch changes the default visualizer to treat a "void *" as a scalar.

This adds a new test; but also arranges to examine all the returned
registers -- this was the first thing I attempted and it seemed
reasonable to have a test that double-checks that all the registers
really can be dereferenced as appropriate.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33228
2025-08-11 07:39:10 -06:00
Tom Tromey
5fe70629ce Change file initialization to use INIT_GDB_FILE macro
This patch introduces a new macro, INIT_GDB_FILE.  This is used to
replace the current "_initialize_" idiom when introducing a per-file
initialization function.  That is, rather than write:

    void _initialize_something ();
    void
    _initialize_something ()
    {
       ...
    }

... now you would write:

    INIT_GDB_FILE (something)
    {
       ...
    }

The macro handles both the declaration and definition of the function.

The point of this approach is that it makes it harder to accidentally
cause an initializer to be omitted; see commit 2711e475 ("Ensure
cooked_index_entry self-tests are run").  Specifically, the regexp now
used by make-init-c seems harder to trick.

New in v2: un-did some erroneous changes made by the script.

The bulk of this patch was written by script.
Regression tested on x86-64 Fedora 41.
2025-06-26 06:15:59 -06:00
Tom Tromey
744dabeb29 Allow DAP "threads" request when inferior is running
A user pointed out that DAP allows the "threads" request to work when
the inferior is running.  This is documented in the overview, not the
specification.

While looking into this, I found a few other issues:

* The _thread_name function was not marked @in_gdb_thread.
  This isn't very important but is still an oversight.

* DAP requires all threads to have a name -- the field is not optional
  in the "Thread" type.

* There was no test examining events resulting from the inferior
  printing to stdout.

This patch fixes all these problems.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33080
2025-06-24 08:38:09 -06:00
Andrew Burgess
d8e6b67b18 gdb/python: introduce gdb.warning() function
This commit adds a new gdb.warning() function.  This function takes a
string and then calls GDB's internal warning() function.  This will
display the string as a warning.

Using gdb.warning() means that the message will get the new emoji
prefix if the user has that feature turned on.  Also, the message will
be sent to gdb.STDERR without the user having to remember to print to
the correct stream.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
2025-06-19 10:31:14 +01:00
oltolm
de0590c561 gdb/dap: allow more requests when the process is running
Makes it possible to set and remove other types of breakpoints while the
process is running. Makes debugging more convenient.

Approved-By: Tom Tromey <tom@tromey.com>
2025-06-17 11:11:18 -06:00
Tom Tromey
79f0096332 Minor grammar fix in DAP comment
I noticed a minor grammer issue in a comment in DAP.
2025-06-12 11:04:55 -06:00
Andrew Burgess
2898989ac7 gdb/python/guile: remove some explicit calls to xmalloc
In gdbpy_parse_command_name (python/py-cmd.c) there is a call to
xmalloc that can easily be replaced with a call to
make_unique_xstrndup, which makes the code easier to read (I think).

In gdbscm_parse_command_name (guile/scm-cmd.c) the same fix can be
applied to remove an identical xmalloc call.  And there is an
additional xmalloc call, which can also be replaced with
make_unique_xstrndup in the same way.

The second xmalloc call in gdbscm_parse_command_name was also present
in gdbpy_parse_command_name at one point, but was replaced with a use
of std::string by this commit:

  commit 075c55e0cc
  Date:   Wed Dec 26 11:05:57 2018 -0700

      Remove more calls to xfree from Python

I haven't changed the gdbscm_parse_command_name to use std::string
though, as that doesn't work well with the guile exception model.
Guile exceptions work by performing a longjmp from the function that
raises the exception, back to the guile run-time.  The consequence of
this is that destructors are not run.  For example, if
gdbscm_parse_command_name calls gdbscm_out_of_range_error, then any
function local objects in gdbscm_parse_command_name will not have
their destructors called.

What this means is that, for the existing `result` and `prefix_text`
locals, any allocated memory managed by these objects will be leaked
if an exception is called.  However, fixing this is pretty easy, one
way is to just assign nullptr to these locals before raising the
exception, this would cause the allocated memory to be released.

But for std::string it is harder to ensure that the managed memory has
actually been released.  We can call std::string::clear() and then
maybe std::string::shrink_to_fit(), but this is still not guaranteed
to release any managed memory.  In fact, I believe the only way to
ensure all managed memory is released, is to call the std::string
destructor.

And so, for functions that can throw a guile exception, it is easier
to just avoid std::string.

As for the memory leak that I identify above; I'll fix that in a
follow on commit.

Approved-By: Tom Tromey <tom@tromey.com>
2025-06-06 23:46:47 +01:00