Commit graph

200 commits

Author SHA1 Message Date
Andrew Burgess
d2d62da62e gdb/python: have UnwindInfo.add_saved_register accept named args
Update gdb.UnwindInfo.add_saved_register to accept named keyword
arguments.

As part of this update we now use gdb_PyArg_ParseTupleAndKeywords
instead of PyArg_UnpackTuple to parse the function arguments.

By switching to gdb_PyArg_ParseTupleAndKeywords, we can now use 'O!'
as the argument format for the function's value argument.  This means
that we can check the argument type (is gdb.Value) as part of the
argument processing rather than manually performing the check later in
the function.  One result of this is that we now get a better error
message (at least, I think so).  Previously we would get something
like:

  ValueError: Bad register value

Now we get:

  TypeError: argument 2 must be gdb.Value, not XXXX

It's unfortunate that the exception type changed, but I think the new
exception type actually makes more sense.

My preference for argument names is to use full words where that's not
too excessive.  As such, I've updated the name of the argument from
'reg' to 'register' in the documentation, which is the argument name
I've made GDB look for here.

For existing unwinder code that doesn't throw any exceptions nothing
should change with this commit.  It is possible that a user has some
code that throws and catches the ValueError, and this code will break
after this commit, but I think this is going to be sufficiently rare
that we can take the risk here.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-06 14:57:32 +01:00
Andrew Burgess
3712e78cab gdb/python: Add new gdb.unwinder.FrameId class
When writing an unwinder it is necessary to create a new class to act
as a frame-id.  This new class is almost certainly just going to set a
'sp' and 'pc' attribute within the instance.

This commit adds a little helper class gdb.unwinder.FrameId that does
this job.  Users can make use of this to avoid having to write out
standard boilerplate code any time they write an unwinder.

Of course, if the user wants their FrameId class to be more
complicated in some way, then they can still write their own class,
just like they could before.

I've simplified the example code in the documentation to now use the
new helper class, and I've also made use of this helper within the
testsuite.

Any existing user code will continue to work just as it did before
after this change.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-30 10:25:46 +01:00
Andrew Burgess
64826d05d3 gdb/python: Allow gdb.UnwindInfo to be created with non gdb.Value args
Currently when creating a gdb.UnwindInfo object a user must call
gdb.PendingFrame.create_unwind_info and pass a frame-id object.

The frame-id object should have at least a 'sp' attribute, and
probably a 'pc' attribute too (it can also, in some cases have a
'special' attribute).

Currently all of these frame-id attributes need to be gdb.Value
objects, but the only reason for that requirement is that we have some
code in py-unwind.c that only handles gdb.Value objects.

If instead we switch to using get_addr_from_python in py-utils.c then
we will support both gdb.Value objects and also raw numbers, which
might make things simpler in some cases.

So, I started rewriting pyuw_object_attribute_to_pointer (in
py-unwind.c) to use get_addr_from_python.  However, while looking at
the code I noticed a problem.

The pyuw_object_attribute_to_pointer function returns a boolean flag,
if everything goes OK we return true, but we return false in two
cases, (1) when the attribute is not present, which might be
acceptable, or might be an error, and (2) when we get an error trying
to extract the attribute value, in which case a Python error will have
been set.

Now in pending_framepy_create_unwind_info we have this code:

  if (!pyuw_object_attribute_to_pointer (pyo_frame_id, "sp", &sp))
    {
      PyErr_SetString (PyExc_ValueError,
		       _("frame_id should have 'sp' attribute."));
      return NULL;
    }

Notice how we always set an error.  This will override any error that
is already set.

So, if you create a frame-id object that has an 'sp' attribute, but
the attribute is not a gdb.Value, then currently we fail to extract
the attribute value (it's not a gdb.Value) and set this error in
pyuw_object_attribute_to_pointer:

  rc = pyuw_value_obj_to_pointer (pyo_value.get (), addr);
  if (!rc)
    PyErr_Format (
        PyExc_ValueError,
        _("The value of the '%s' attribute is not a pointer."),
        attr_name);

Then we return to pending_framepy_create_unwind_info and immediately
override this error with the error about 'sp' being missing.

This all feels very confused.

Here's my proposed solution: pyuw_object_attribute_to_pointer will now
return a tri-state enum, with states OK, MISSING, or ERROR.  The
meanings of these states are:

  OK - Attribute exists and was extracted fine,

  MISSING - Attribute doesn't exist, no Python error was set.

  ERROR - Attribute does exist, but there was an error while
     extracting it, a Python error was set.

We need to update pending_framepy_create_unwind_info, the only user of
pyuw_object_attribute_to_pointer, but now I think things are much
clearer.  Errors from lower levels are not blindly overridden with the
generic meaningless error message, but we still get the "missing 'sp'
attribute" error when appropriate.

This change also includes the switch to get_addr_from_python which was
what started this whole journey.

For well behaving user code there should be no visible changes after
this commit.

For user code that hits an error, hopefully the new errors should be
more helpful in figuring out what's gone wrong.

Additionally, users can now use integers for the 'sp' and 'pc'
attributes in their frame-id objects if that is useful.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-30 10:25:46 +01:00
Andrew Burgess
86b35b7116 gdb/python: add some additional methods to gdb.PendingFrame
The gdb.Frame class has far more methods than gdb.PendingFrame.  Given
that a PendingFrame hasn't yet been claimed by an unwinder, there is a
limit to which methods we can add to it, but many of the methods that
the Frame class has, the PendingFrame class could also support.

In this commit I've added those methods to PendingFrame that I believe
are safe.

In terms of implementation: if I was starting from scratch then I
would implement many of these (or most of these) as attributes rather
than methods.  However, given both Frame and PendingFrame are just
different representation of a frame, I think there is value in keeping
the interface for the two classes the same.  For this reason
everything here is a method -- that's what the Frame class does.

The new methods I've added are:

  - gdb.PendingFrame.is_valid: Return True if the pending frame
    object is valid.

  - gdb.PendingFrame.name: Return the name for the frame's function,
    or None.

  - gdb.PendingFrame.pc: Return the $pc register value for this
    frame.

  - gdb.PendingFrame.language: Return a string containing the
    language for this frame, or None.

  - gdb.PendingFrame.find_sal: Return a gdb.Symtab_and_line object
    for the current location within the pending frame, or None.

  - gdb.PendingFrame.block: Return a gdb.Block for the current
    pending frame, or None.

  - gdb.PendingFrame.function: Return a gdb.Symbol for the current
    pending frame, or None.

In every case I've just copied the implementation over from gdb.Frame
and cleaned the code slightly e.g. NULL to nullptr.  Additionally each
function required a small update to reflect the PendingFrame type, but
that's pretty minor.

There are tests for all the new methods.

For more extensive testing, I added the following code to the file
gdb/python/lib/command/unwinders.py:

  from gdb.unwinder import Unwinder

  class TestUnwinder(Unwinder):
      def __init__(self):
          super().__init__("XXX_TestUnwinder_XXX")

      def __call__(self,pending_frame):
          lang = pending_frame.language()
          try:
              block = pending_frame.block()
              assert isinstance(block, gdb.Block)
          except RuntimeError as rte:
              assert str(rte) == "Cannot locate block for frame."
          function = pending_frame.function()
          arch = pending_frame.architecture()
          assert arch is None or isinstance(arch, gdb.Architecture)
          name = pending_frame.name()
          assert name is None or isinstance(name, str)
          valid = pending_frame.is_valid()
          pc = pending_frame.pc()
          sal = pending_frame.find_sal()
          assert sal is None or isinstance(sal, gdb.Symtab_and_line)
          return None

  gdb.unwinder.register_unwinder(None, TestUnwinder())

This registers a global unwinder that calls each of the new
PendingFrame methods and checks the result is of an acceptable type.
The unwinder never claims any frames though, so shouldn't change how
GDB actually behaves.

I then ran the testsuite.  There was only a single regression, a test
that uses 'disable unwinder' and expects a single unwinder to be
disabled -- the extra unwinder is now disabled too, which changes the
test output.  So I'm reasonably confident that the new methods are not
going to crash GDB.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-30 10:25:46 +01:00
Andrew Burgess
6bf5f25bb1 gdb/python: make the gdb.unwinder.Unwinder class more robust
This commit makes a few related changes to the gdb.unwinder.Unwinder
class attributes:

  1. The 'name' attribute is now a read-only attribute.  This prevents
  user code from changing the name after registering the unwinder.  It
  seems very unlikely that any user is actually trying to do this in
  the wild, so I'm not very worried that this will upset anyone,

  2. We now validate that the name is a string in the
  Unwinder.__init__ method, and throw an error if this is not the
  case.  Hopefully nobody was doing this in the wild.  This should
  make it easier to ensure the 'info unwinder' command shows sane
  output (how to display a non-string name for an unwinder?),

  3. The 'enabled' attribute is now implemented with a getter and
  setter.  In the setter we ensure that the new value is a boolean,
  but the real important change is that we call
  'gdb.invalidate_cached_frames()'.  This means that the backtrace
  will be updated if a user manually disables an unwinder (rather than
  calling the 'disable unwinder' command).  It is not unreasonable to
  think that a user might register multiple unwinders (relating to
  some project) and have one command that disables/enables all the
  related unwinders.  This command might operate by poking the enabled
  attribute of each unwinder object directly, after this commit, this
  would now work correctly.

There's tests for all the changes, and lots of documentation updates
that both cover the new changes, but also further improve (I think)
the general documentation for GDB's Unwinder API.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-30 10:25:46 +01:00
Tom Tromey
12d290fbbf Fix minor grammar issue in python.texi
I noticed a minor grammar problem in the 'GDB/MI Commands In Python'
node of the manual.  I'm checking in this patch to correct it.
2023-03-23 10:47:15 -06:00
Andrew Burgess
a8afc8a7e1 gdb/doc: spring clean the Python unwinders documentation
The documentation for the Python Unwinders API could do with some
improvement.  The 'Unwinder Skeleton Code' has an error: it says
'unwinders' when it should say 'unwinder' in one case.

Additionally, by placing the 'Unwinder Skeleton Code' before the
section 'Registering an Unwinder' we have skipping including the
registration line in the skeleton code.  But this is confusion for
users (I think) as the skeleton code is almost complete, except for
one missing line which the user has to figure out for themselves.  By
reordering the sections, it is now obvious that the registration
should be included in the skeleton code, and the example is therefore
almost complete.

Additionally, in the example skeleton code the way in which the
frame-id was being built (using the current stack point and program
counter is (a) not correct, and (b) counter to what is laid out in the
'Unwinder Input' section when describing building a frame-id.

I've removed the incorrect code and replaced it with more generic
comments indicating what needs to be done.  As the actual actions that
need to be performed are both architecture specific, and dependent on
the function being unwound, it's almost impossible to include more
exact code here, but I think what I'm proposing is less misleading
than what we had before.

I've also added more cross references.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-03-16 14:29:30 +00:00
Andrew Burgess
76b58849c5 GDB: Add a character string limiting option
This commit splits the `set/show print elements' option into two.  We
retain `set/show print elements' for controlling how many elements of an
array we print, but a new `set/show print characters' setting is added
which is used for controlling how many characters of a string are
printed.

The motivation behind this change is to allow users a finer level of
control over how data is printed, reflecting that, although strings can
be thought of as arrays of characters, users often want to treat these
two things differently.

For compatibility reasons by default the `set/show print characters'
option is set to `elements', which makes the limit for character strings
follow the setting of the `set/show print elements' option, as it used
to.  Using `set print characters' with any other value makes the limit
independent from the `set/show print elements' setting, however it can
be restored to the default with the `set print characters elements'
command at any time.

A corresponding `-characters' option for the `print' command is added,
with the same semantics, i.e. one can use `elements' to make a given
`print' invocation follow the limit of elements, be it set with the
`-elements' option also given with the same invocation or taken from the
`set/show print elements' setting, for characters as well regardless of
the current setting of the `set/show print characters' option.

The GDB changes are all pretty straightforward, just changing references
to the old 'print_max' to use a new `get_print_max_chars' helper which
figures out which of the two of `print_max' and `print_max_chars' values
to use.

Likewise, the documentation is just updated to reference the new setting
where appropriate.

To make people's life easier the message shown by `show print elements'
now indicates if the setting also applies to character strings:

(gdb) set print characters elements
(gdb) show print elements
Limit on string chars or array elements to print is 200.
(gdb) set print characters unlimited
(gdb) show print elements
Limit on array elements to print is 200.
(gdb)

and the help text shows the dependency as well:

(gdb) help set print elements
Set limit on array elements to print.
"unlimited" causes there to be no limit.
This setting also applies to string chars when "print characters"
is set to "elements".
(gdb)

In the testsuite there are two minor updates, one to add `-characters'
to the list of completions now shown for the `print' command, and a bare
minimum pair of checks for the right handling of `set print characters'
and `show print characters', copied from the corresponding checks for
`set print elements' and `show print elements' respectively.

Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-01-19 21:15:56 +00:00
Maciej W. Rozycki
7aeb03e2d4 GDB: Allow arbitrary keywords in integer set commands
Rather than just `unlimited' allow the integer set commands (or command
options) to define arbitrary keywords for the user to use, removing
hardcoded arrangements for the `unlimited' keyword.

Remove the confusingly named `var_zinteger', `var_zuinteger' and
`var_zuinteger_unlimited' `set'/`show' command variable types redefining
them in terms of `var_uinteger', `var_integer' and `var_pinteger', which
have the range of [0;UINT_MAX], [INT_MIN;INT_MAX], and [0;INT_MAX] each.

Following existing practice `var_pinteger' allows extra negative values
to be used, however unlike `var_zuinteger_unlimited' any number of such
values can be defined rather than just `-1'.

The "p" in `var_pinteger' stands for "positive", for the lack of a more
appropriate unambiguous letter, even though 0 obviously is not positive;
"n" would be confusing as to whether it stands for "non-negative" or
"negative".

Add a new structure, `literal_def', the entries of which define extra
keywords allowed for a command and numerical values they correspond to.
Those values are not verified against the basic range supported by the
underlying variable type, allowing extra values to be allowed outside
that range, which may or may not be individually made visible to the
user.  An optional value translation is possible with the structure to
follow the existing practice for some commands where user-entered 0 is
internally translated to UINT_MAX or INT_MAX.  Such translation can now
be arbitrary.  Literals defined by this structure are automatically used
for completion as necessary.

So for example:

const literal_def integer_unlimited_literals[] =
  {
    { "unlimited", INT_MAX, 0 },
    { nullptr }
  };

defines an extra `unlimited' keyword and a user-visible 0 value, both of
which get translated to INT_MAX for the setting to be used with.

Similarly:

const literal_def zuinteger_unlimited_literals[] =
  {
    { "unlimited", -1, -1 },
    { nullptr }
  };

defines the same keyword and a corresponding user-visible -1 value that
is used for the requested setting.  If the last member were omitted (or
set to `{}') here, then only the keyword would be allowed for the user
to enter and while -1 would still be used internally trying to enter it
as a part of a command would result in an "integer -1 out of range"
error.

Use said error message in all cases (citing the invalid value requested)
replacing "only -1 is allowed to set as unlimited" previously used for
`var_zuinteger_unlimited' settings only rather than propagating it to
`var_pinteger' type.  It could only be used for the specific case where
a single extra `unlimited' keyword was defined standing for -1 and the
use of numeric equivalents is discouraged anyway as it is for historical
reasons only that they expose GDB internals, confusingly different
across variable types.  Similarly update the "must be >= -1" Guile error
message.

Redefine Guile and Python parameter types in terms of the new variable
types and interpret extra keywords as Scheme keywords and Python strings
used to communicate corresponding parameter values.  Do not add a new
PARAM_INTEGER Guile parameter type, however do handle the `var_integer'
variable type now, permitting existing parameters defined by GDB proper,
such as `listsize', to be accessed from Scheme code.

With these changes in place it should be trivial for a Scheme or Python
programmer to expand the syntax of the `make-parameter' command and the
`gdb.Parameter' class initializer to have arbitrary extra literals along
with their internal representation supplied.

Update the testsuite accordingly.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-01-19 21:15:56 +00:00
Simon Marchi
cc81f07b80 gdb/doc: some whitespace fixes
For consistency, replace tabs with spaces in all gdb.texinfo menus.

Change-Id: I0801a72cf82a8afe49ec842244f42d30719634ce
2023-01-10 10:11:48 -05:00
Simon Marchi
000f9cbef9 gdb/doc: fix @code{GDBN} -> @value{GDBN}
Change-Id: I928d6f8d6e6bc41d8c7ddbfae8f6ae0614f4993e
2023-01-09 14:11:29 -05:00
Joel Brobecker
213516ef31 Update copyright year range in header of all files managed by GDB
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
2023-01-01 17:01:16 +04:00
Tom Tromey
4881fcd7c1 Add missing TYPE_CODE_* constants to Python
A user noticed that TYPE_CODE_FIXED_POINT was not exported by the gdb
Python layer.  This patch fixes the bug, and prevents future
occurences of this type of bug.
2022-10-31 12:47:36 -06:00
Andrew Burgess
c6d20401a2 gdb/doc: reword description of DisassembleInfo.read_memory
While reading the documentation of DisassembleInfo.read_memory I
spotted the word 'available' in one sentence where it didn't make
sense.
2022-10-24 18:04:42 +01:00
Pedro Alves
62fe72fda1 Improve Python Unwinders documentation
- avoid "GDB proper" to refer to global locus, as object files and
  program spaces are also GDB proper.

- gdb.register_unwinder does not accept locus=gdb.

- "a unwinder" -> "an unwinder"

Approved-by: Eli Zaretskii <eliz@gnu.org>
Change-Id: I98c1b1000e1063815238e945ca71ec6f37b5702e
2022-10-21 22:05:16 +01:00
Andrew Burgess
7abc6ec0a6 gdb/python: restrict the names accepted by gdb.register_window_type
I noticed that, from Python, I could register a new TUI window that
had whitespace in its name, like this:

  gdb.register_window_type('my window', MyWindowType)

however, it is not possible to then use this window in a new TUI
layout, e.g.:

  (gdb) tui new-layout foo my window 1 cmd 1
  Unknown window "my"
  (gdb) tui new-layout foo "my window" 1 cmd 1
  Unknown window ""my"
  (gdb) tui new-layout foo my\ window 1 cmd 1
  Unknown window "my\"

GDB clearly uses the whitespace to split the incoming command line.

I could fix this by trying to add a mechanism by which we can use
whitespace within a window name, but it seems like an easier solution
if we just forbid whitespace within a window name.  Not only is this
easier, but I think this is probably the better solution, identifier
names with spaces in would mean we'd need to audit all the places a
window name could be printed and ensure that the use of a space didn't
make the output ambiguous.

So, having decided to disallow whitespace, I then thought about other
special characters.  We currently accept anything as a window name,
and I wondered if this was a good idea.

My concerns were about how special characters used in a window name
might cause confusion, for example, we allow '$' in window names,
which is maybe fine now, but what if one day we wanted to allow
variable expansion when creating new layouts?  Or what about starting
a window name with '-'?  We already support a '-horizontal' option,
what if we want to add more in the future?  Or use of the special
character '{' which has special meaning within a new layout?

In the end I figured it might make sense to place some restrictive
rules in place, and then relax the rules later if/when users complain,
we can consider each relaxation as its requested.

So, I propose that window names should match this regular expression:

  [a-zA-Z][-_.a-zA-Z0-9]*

There is a chance that there is user code in the wild which will break
with the addition of this change, but hopefully adapting to the new
restrictions shouldn't be too difficult.
2022-09-22 10:34:15 +01:00
Tom Tromey
dd083c6524 Fix gdb.flush documentation
The gdb.flush documentation does not mention the 'stream' argument in
the function signature, only in the description.  This patch fixes the
oversight.
2022-08-30 11:49:48 -06:00
Simon Farre
e5213e2c85 gdb/python: Add BreakpointLocation type
PR python/18385

v7:
This version addresses the issues pointed out by Tom.

Added nullchecks for Python object creations.

Changed from using PyLong_FromLong to the gdb_py-versions.

Re-factored some code to make it look more cohesive.

Also added the more safe Python reference count decrement PY_XDECREF,
even though the BreakpointLocation type is never instantiated by the
user (explicitly documented in the docs) decrementing < 0 is made
impossible with the safe call.

Tom pointed out that using the policy class explicitly to decrement a
reference counted object was not the way to go, so this has instead been
wrapped in a ref_ptr that handles that for us in blocpy_dealloc.

Moved macro from py-internal to py-breakpoint.c.

Renamed section at the bottom of commit message "Patch Description".

v6:
This version addresses the points Pedro gave in review to this patch.

Added the attributes `function`, `fullname` and `thread_groups`
as per request by Pedro with the argument that it more resembles the
output of the MI-command "-break-list".  Added documentation for these attributes.

Cleaned up left overs from copy+paste in test suite, removed hard coding
of line numbers where possible.

Refactored some code to use more c++-y style range for loops
wrt to breakpoint locations.

Changed terminology, naming was very inconsistent. Used a variety of "parent",
"owner". Now "owner" is the only term used, and the field in the
gdb_breakpoint_location_object now also called "owner".

v5:

Changes in response to review by Tom Tromey:
- Replaced manual INCREF/DECREF calls with
  gdbpy_ref ptrs in places where possible.
- Fixed non-gdb style conforming formatting
- Get parent of bploc increases ref count of parent.
- moved bploc Python definition to py-breakpoint.c

The INCREF of self in bppy_get_locations is due
to the individual locations holding a reference to
it's owner. This is decremented at de-alloc time.

The reason why this needs to be here is, if the user writes
for instance;

py loc = gdb.breakpoints()[X].locations[Y]

The breakpoint owner object is immediately going
out of scope (GC'd/dealloced), and the location
object requires it to be alive for as long as it is alive.

Thanks for your review, Tom!

v4:
Fixed remaining doc issues as per request
by Eli.

v3:
Rewritten commit message, shortened + reworded,
added tests.

Patch Description

Currently, the Python API lacks the ability to
query breakpoints for their installed locations,
and subsequently, can't query any information about them, or
enable/disable individual locations.

This patch solves this by adding Python type gdb.BreakpointLocation.
The type is never instantiated by the user of the Python API directly,
but is produced by the gdb.Breakpoint.locations attribute returning
a list of gdb.BreakpointLocation.

gdb.Breakpoint.locations:
The attribute for retrieving the currently installed breakpoint
locations for gdb.Breakpoint. Matches behavior of
the "info breakpoints" command in that it only
returns the last known or currently inserted breakpoint locations.

BreakpointLocation contains 7 attributes

6 read-only attributes:
owner: location owner's Python companion object
source: file path and line number tuple: (string, long) / None
address: installed address of the location
function: function name where location was set
fullname: fullname where location was set
thread_groups: thread groups (inferiors) where location was set.

1 writeable attribute:
enabled: get/set enable/disable this location (bool)

Access/calls to these, can all throw Python exceptions (documented in
the online documentation), and that's due to the nature
of how breakpoint locations can be invalidated
"behind the scenes", either by them being removed
from the original breakpoint or changed,
like for instance when a new symbol file is loaded, at
which point all breakpoint locations are re-created by GDB.
Therefore this patch has chosen to be non-intrusive:
it's up to the Python user to re-request the locations if
they become invalid.

Also there's event handlers that handle new object files etc, if a Python
user is storing breakpoint locations in some larger state they've
built up, refreshing the locations is easy and it only comes
with runtime overhead when the Python user wants to use them.

gdb.BreakpointLocation Python type
struct "gdbpy_breakpoint_location_object" is found in python-internal.h

Its definition, layout, methods and functions
are found in the same file as gdb.Breakpoint (py-breakpoint.c)

1 change was also made to breakpoint.h/c to make it possible
to enable and disable a bp_location* specifically,
without having its LOC_NUM, as this number
also can change arbitrarily behind the scenes.

Updated docs & news file as per request.

Testsuite: tests the .source attribute and the disabling of
individual locations.

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


Change-Id: I302c1c50a557ad59d5d18c88ca19014731d736b0
2022-07-28 11:20:46 -06:00
Kevin Buettner
24d2cbc42c set/show python dont-write-bytecode fixes
GDB uses the environment variable PYTHONDONTWRITEBYTECODE to
determine whether or not to write the result of byte-compiling
python modules when the "python dont-write-bytecode" setting
is "auto".  Simon noticed that GDB's implementation doesn't
follow the Python documentation.

At present, GDB only checks for the existence of this environment
variable.  That is not sufficient though.  Regarding
PYTHONDONTWRITEBYTECODE, this document...

    https://docs.python.org/3/using/cmdline.html

...says:

    If this is set to a non-empty string, Python won't try to write
    .pyc files on the import of source modules.

This commit fixes GDB's handling of PYTHONDONTWRITEBYTECODE by adding
an empty string check.

This commit also corrects the set/show command documentation for
"python dont-write-bytecode".  The current doc was just a copy
of that for set/show python ignore-environment.

During his review of an earlier version of this patch, Eli Zaretskii
asked that the help text that I proposed for "set/show python
dont-write-bytecode" be expanded.  I've done that in addition to
clarifying the documentation of this option in the GDB manual.
2022-07-25 12:05:14 -07:00
Tom Tromey
0b4fe76f95 Add gdb.free_objfile event registry
Currently, Python code can use event registries to detect when gdb
loads a new objfile, and when gdb clears the objfile list.  However,
there's no way to detect the removal of an objfile, say when the
inferior calls dlclose.

This patch adds a gdb.free_objfile event registry and arranges for an
event to be emitted in this case.
2022-07-18 11:25:34 -06:00
Tom Tromey
72be9d6be7 Add 'summary' mode to Value.format_string
This adds a 'summary' mode to Value.format_string and to
gdb.print_options.  For the former, it lets Python code format values
using this mode.  For the latter, it lets a printer potentially detect
if it is being called in a backtrace with 'set print frame-arguments'
set to 'scalars'.

I considered adding a new mode here to let a pretty-printer see
whether it was being called in a 'backtrace' context at all, but I'm
not sure if this is really desirable.
2022-07-15 09:26:54 -06:00
Tom Tromey
c4a3dbaf11 Expose current 'print' settings to Python
PR python/17291 asks for access to the current print options.  While I
think this need is largely satisfied by the existence of
Value.format_string, it seemed to me that a bit more could be done.

First, while Value.format_string uses the user's settings, it does not
react to temporary settings such as "print/x".  This patch changes
this.

Second, there is no good way to examine the current settings (in
particular the temporary ones in effect for just a single "print").
This patch adds this as well.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17291
2022-07-15 09:25:33 -06:00
Tom Tromey
99298c958c Add gdb.Objfile.is_file attribute
Sometimes an objfile comes from memory and not from a file.  It can be
useful to be able to check this from Python, so this patch adds a new
"is_file" attribute.
2022-07-05 11:22:20 -06:00
Enze Li
3f52a09075 gdb/python: Export nibbles to python layer
This patch makes it possible to allow Value.format_string() to return
nibbles output.

When we set the parameter of nibbles to True, we can achieve the
displaying binary values in groups of every four bits.

Here's an example:
  (gdb) py print (gdb.Value (1230).format_string (format='t', nibbles=True))
  0100 1100 1110
  (gdb)

Note that the parameter nibbles is only useful if format='t' is also used.

This patch also includes update to the relevant testcase and
documentation.

Tested on x86_64 openSUSE Tumbleweed.
2022-06-18 11:23:16 +08:00
Tom Tromey
285dfa0f68 Add to documentation of Python 'dont_repeat' method
PR python/28533 points out that the Python 'dont_repeat' documentation
is a bit ambiguous about when the method ought to be called.  This
patch spells it out.
2022-06-15 14:00:39 -06:00
Andrew Burgess
15e15b2d9c gdb/python: implement the print_insn extension language hook
This commit extends the Python API to include disassembler support.

The motivation for this commit was to provide an API by which the user
could write Python scripts that would augment the output of the
disassembler.

To achieve this I have followed the model of the existing libopcodes
disassembler, that is, instructions are disassembled one by one.  This
does restrict the type of things that it is possible to do from a
Python script, i.e. all additional output has to fit on a single line,
but this was all I needed, and creating something more complex would,
I think, require greater changes to how GDB's internal disassembler
operates.

The disassembler API is contained in the new gdb.disassembler module,
which defines the following classes:

  DisassembleInfo

      Similar to libopcodes disassemble_info structure, has read-only
  properties: address, architecture, and progspace.  And has methods:
  __init__, read_memory, and is_valid.

      Each time GDB wants an instruction disassembled, an instance of
  this class is passed to a user written disassembler function, by
  reading the properties, and calling the methods (and other support
  methods in the gdb.disassembler module) the user can perform and
  return the disassembly.

  Disassembler

      This is a base-class which user written disassemblers should
  inherit from.  This base class provides base implementations of
  __init__ and __call__ which the user written disassembler should
  override.

  DisassemblerResult

      This class can be used to hold the result of a call to the
  disassembler, it's really just a wrapper around a string (the text
  of the disassembled instruction) and a length (in bytes).  The user
  can return an instance of this class from Disassembler.__call__ to
  represent the newly disassembled instruction.

The gdb.disassembler module also provides the following functions:

  register_disassembler

      This function registers an instance of a Disassembler sub-class
  as a disassembler, either for one specific architecture, or, as a
  global disassembler for all architectures.

  builtin_disassemble

      This provides access to GDB's builtin disassembler.  A common
  use case that I see is augmenting the existing disassembler output.
  The user code can call this function to have GDB disassemble the
  instruction in the normal way.  The user gets back a
  DisassemblerResult object, which they can then read in order to
  augment the disassembler output in any way they wish.

      This function also provides a mechanism to intercept the
  disassemblers reads of memory, thus the user can adjust what GDB
  sees when it is disassembling.

The included documentation provides a more detailed description of the
API.

There is also a new CLI command added:

  maint info python-disassemblers

This command is defined in the Python gdb.disassemblers module, and
can be used to list the currently registered Python disassemblers.
2022-06-15 09:44:54 +01:00
Tom Tromey
1c76a0e2a6 Minor fix to Python breakpoint event documentation
I noticed that the Python event documentation referred to the event's
"breakpoint" field as a function, whereas it is actually an attribute.
This patch fixes the error.
2022-06-09 12:34:00 -06:00
Tom Tromey
80fa4b2a60 Add gdb.current_language and gdb.Frame.language
This adds the gdb.current_language function, which can be used to find
the current language without (1) ever having the value "auto" or (2)
having to parse the output of "show language".

It also adds the gdb.Frame.language, which can be used to find the
language of a given frame.  This is normally preferable if one has a
Frame object handy.
2022-06-01 06:15:53 -06:00
Pedro Alves
5541bfdc97 gdb/manual: Introduce location specs
The current "Specify Location" section of the GDB manual starts with:

 "Several @value{GDBN} commands accept arguments that specify a location
 of your program's code."

And then, such commands are documented as taking a "location"
argument.  For example, here's a representative subset:

 @item break @var{location}
 @item clear @var{location}
 @item until @var{location}
 @item list @var{location}
 @item edit @var{location}
 @itemx info line @var{location}
 @item info macros @var{location}
 @item trace @var{location}
 @item info scope @var{location}
 @item maint agent @r{[}-at @var{location}@r{,}@r{]} @var{expression}

The issue here is that "location" isn't really correct for most of
these commands.  Instead, the "location" argument is really a
placeholder that represent an umbrella term for all of the
"linespecs", "explicit location", and "address location" input
formats.  GDB parses these and then finds the actual code locations
(plural) in the program that match.  For example, a "location"
specified like "-function func" will actually match all the code
locations in the program that correspond to the address/file/lineno of
all the functions named "func" in all the loaded programs and shared
libraries of all the inferiors.  A location specified like "-function
func -label lab" matches all the addresses of C labels named "lab" in
all functions named "func".  Etc.

This means that several of the commands that claim they accept a
"location", actually end up working with multiple locations, and the
manual doesn't explain that all that well.  In some cases, the command
will work with all the resolved locations.  In other cases, the
command aborts with an error if the location specification resolves to
multiple locations in the program.  In other cases, GDB just
arbitrarily and silently picks whatever is the first resolved code
location (which sounds like should be improved).

To clarify this, I propose we use the term "Location Specification",
with shorthand "locaction spec", when we're talking about the user
input, the argument or arguments that is/are passed to commands to
instruct GDB how to find locations of interest.  This is distinct from
the actual code locations in the program, which are what GDB finds
based on the user-specified location spec.  Then use "location
specification or the shorter "location spec" thoughout instead of
"location" when we're talking about the user input.

Thus, this commit does the following:

- renames the "Specify Location" section of the manual to "Location
  Specifications".

- It then introduces the term "Location Specification", with
  corresponding shorthand "location spec", as something distinct from
  an actual code location in the program.  It explains what a concrete
  code location is.  It explains that a location specification may be
  incomplete, and that may match multiple code locations in the
  program, or no code location at all.  It gives examples.  Some
  pre-existing examples were moved from the "Set Breaks" section, and
  a few new ones that didn't exist yet were added.  I think it is
  better to have these centralized in this "Location Specification"
  section, since all the other commands that accept a location spec
  have an xref that points there.

- Goes through the manual, and where "@var{location}" was used for a
  command argument, updated it to say "@var{locspec}" instead.  At the
  same time, tweaks the description of the affected commands to
  describe what happens when the location spec resolves to more than
  one location.  Most commands just did not say anything about that.

  One command -- "maint agent -at @var{location}" -- currently says it
  accepts a "location", suggesting it can accept address and explicit
  locations too, but that's incorrect.  In reality, it only accepts
  linespecs, so fix it accordingly.

  One MI command -- "-trace-find line" -- currently says it accepts a
  "line specification", but it can accept address and explicit
  locations too, so fix it accordingly.

Special thanks goes to Eli Zaretskii for reviews and rewording
suggestions.

Change-Id: Ic42ad8565e79ca67bfebb22cbb4794ea816fd08b
2022-05-30 15:36:52 +01:00
Tom Tromey
77d97a0a19 Reorganize Python events documentation
This slightly reorganizes the Python events documentation.  It hoists
the "ThreadEvent" text out of the list of events, where it seemed to
be misplaced.  It tidies the formatting a little bit (adding some
vertical space for easier reading in info), fixes a typo, adds some
missing commas, and fixes an incorrect reference to NewInferiorEvent.
2022-04-14 09:50:44 -06:00
Simon Marchi
edae3fd660 gdb/python: remove Python 2 support
New in this version:

 - Add a PY_MAJOR_VERSION check in configure.ac / AC_TRY_LIBPYTHON.  If
   the user passes --with-python=python2, this will cause a configure
   failure saying that GDB only supports Python 3.

Support for Python 2 is a maintenance burden for any patches touching
Python support.  Among others, the differences between Python 2 and 3
string and integer types are subtle.  It requires a lot of effort and
thinking to get something that behaves correctly on both.  And that's if
the author and reviewer of the patch even remember to test with Python
2.

See this thread for an example:

  https://sourceware.org/pipermail/gdb-patches/2021-December/184260.html

So, remove Python 2 support.  Update the documentation to state that GDB
can be built against Python 3 (as opposed to Python 2 or 3).

Update all the spots that use:

 - sys.version_info
 - IS_PY3K
 - PY_MAJOR_VERSION
 - gdb_py_is_py3k

... to only keep the Python 3 portions and drop the use of some
now-removed compatibility macros.

I did not update the configure script more than just removing the
explicit references to Python 2.  We could maybe do more there, like
check the Python version and reject it if that version is not
supported.  Otherwise (with this patch), things will only fail at
compile time, so it won't really be clear to the user that they are
trying to use an unsupported Python version.  But I'm a bit lost in the
configure code that checks for Python, so I kept that for later.

Change-Id: I75b0f79c148afbe3c07ac664cfa9cade052c0c62
2022-03-23 07:41:19 -04:00
Andrew Burgess
25209e2c69 gdb/python: add gdb.format_address function
Add a new function, gdb.format_address, which is a wrapper around
GDB's print_address function.

This method takes an address, and returns a string with the format:

  ADDRESS <SYMBOL+OFFSET>

Where, ADDRESS is the original address, formatted as hexadecimal,
SYMBOL is a symbol with an address lower than ADDRESS, and OFFSET is
the offset from SYMBOL to ADDRESS in decimal.

If there's no SYMBOL suitably close to ADDRESS then the
<SYMBOL+OFFSET> part is not included.

This is useful if a user wants to write a Python script that
pretty-prints addresses, the user no longer needs to do manual symbol
lookup, or worry about correctly formatting addresses.

Additionally, there are some settings that effect how GDB picks
SYMBOL, and whether the file name and line number should be included
with the SYMBOL name, the gdb.format_address function ensures that the
users Python script also benefits from these settings.

The gdb.format_address by default selects SYMBOL from the current
inferiors program space, and address is formatted using the
architecture for the current inferior.  However, a user can also
explicitly pass a program space and architecture like this:

  gdb.format_address(ADDRESS, PROGRAM_SPACE, ARCHITECTURE)

In order to format an address for a different inferior.

Notes on the implementation:

In py-arch.c I extended arch_object_to_gdbarch to add an assertion for
the type of the PyObject being worked on.  Prior to this commit all
uses of arch_object_to_gdbarch were guaranteed to pass this function a
gdb.Architecture object, but, with this commit, this might not be the
case.

So, with this commit I've made it a requirement that the PyObject be a
gdb.Architecture, and this is checked with the assert.  And in order
that callers from other files can check if they have a
gdb.Architecture object, I've added the new function
gdbpy_is_architecture.

In py-progspace.c I've added two new function, the first
progspace_object_to_program_space, converts a PyObject of type
gdb.Progspace to the associated program_space pointer, and
gdbpy_is_progspace checks if a PyObject is a gdb.Progspace or not.
2022-03-22 10:05:05 +00:00
Andrew Burgess
740b42ceb7 gdb/python/mi: create MI commands using python
This commit allows a user to create custom MI commands using Python
similarly to what is possible for Python CLI commands.

A new subclass of mi_command is defined for Python MI commands,
mi_command_py. A new file, gdb/python/py-micmd.c contains the logic
for Python MI commands.

This commit is based on work linked too from this mailing list thread:

  https://sourceware.org/pipermail/gdb/2021-November/049774.html

Which has also been previously posted to the mailing list here:

  https://sourceware.org/pipermail/gdb-patches/2019-May/158010.html

And was recently reposted here:

  https://sourceware.org/pipermail/gdb-patches/2022-January/185190.html

The version in this patch takes some core code from the previously
posted patches, but also has some significant differences, especially
after the feedback given here:

  https://sourceware.org/pipermail/gdb-patches/2022-February/185767.html

A new MI command can be implemented in Python like this:

  class echo_args(gdb.MICommand):
      def invoke(self, args):
          return { 'args': args }

  echo_args("-echo-args")

The 'args' parameter (to the invoke method) is a list
containing (almost) all command line arguments passed to the MI
command (--thread and --frame are handled before the Python code is
called, and removed from the args list).  This list can be empty if
the MI command was passed no arguments.

When used within gdb the above command produced output like this:

  (gdb)
  -echo-args a b c
  ^done,args=["a","b","c"]
  (gdb)

The 'invoke' method of the new command must return a dictionary.  The
keys of this dictionary are then used as the field names in the mi
command output (e.g. 'args' in the above).

The values of the result returned by invoke can be dictionaries,
lists, iterators, or an object that can be converted to a string.
These are processed recursively to create the mi output.  And so, this
is valid:

  class new_command(gdb.MICommand):
      def invoke(self,args):
          return { 'result_one': { 'abc': 123, 'def': 'Hello' },
                   'result_two': [ { 'a': 1, 'b': 2 },
                                   { 'c': 3, 'd': 4 } ] }

Which produces output like:

  (gdb)
  -new-command
  ^done,result_one={abc="123",def="Hello"},result_two=[{a="1",b="2"},{c="3",d="4"}]
  (gdb)

I have required that the fields names used in mi result output must
match the regexp: "^[a-zA-Z][-_a-zA-Z0-9]*$" (without the quotes).
This restriction was never written down anywhere before, but seems
sensible to me, and we can always loosen this rule later if it proves
to be a problem.  Much harder to try and add a restriction later, once
people are already using the API.

What follows are some details about how this implementation differs
from the original patch that was posted to the mailing list.

In this patch, I have changed how the lifetime of the Python
gdb.MICommand objects is managed.  In the original patch, these object
were kept alive by an owned reference within the mi_command_py object.
As such, the Python object would not be deleted until the
mi_command_py object itself was deleted.

This caused a problem, the mi_command_py were held in the global mi
command table (in mi/mi-cmds.c), which, as a global, was not cleared
until program shutdown.  By this point the Python interpreter has
already been shutdown.  Attempting to delete the mi_command_py object
at this point was causing GDB to try and invoke Python code after
finalising the Python interpreter, and we would crash.

To work around this problem, the original patch added code in
python/python.c that would search the mi command table, and delete the
mi_command_py objects before the Python environment was finalised.

In contrast, in this patch, I have added a new global dictionary to
the gdb module, gdb._mi_commands.  We already have several such global
data stores related to pretty printers, and frame unwinders.

The MICommand objects are placed into the new gdb.mi_commands
dictionary, and it is this reference that keeps the objects alive.
When GDB's Python interpreter is shut down gdb._mi_commands is deleted,
and any MICommand objects within it are deleted at this point.

This change avoids having to make the mi_cmd_table global, and walk
over it from within GDB's python related code.

This patch handles command redefinition entirely within GDB's python
code, though this does impose one small restriction which is not
present in the original code (detailed below), I don't think this is a
big issue.  However, the original patch relied on being able to
finish executing the mi_command::do_invoke member function after the
mi_command object had been deleted.  Though continuing to execute a
member function after an object is deleted is well defined, it is
also (IMHO) risky, its too easy for someone to later add a use of the
object without realising that the object might sometimes, have been
deleted.  The new patch avoids this issue.

The one restriction that is added to avoid this, is that an MICommand
object can't be reinitialised with a different command name, so:

  (gdb) python cmd = MyMICommand("-abc")
  (gdb) python cmd.__init__("-def")
  can't reinitialize object with a different command name

This feels like a pretty weird edge case, and I'm happy to live with
this restriction.

I have also changed how the memory is managed for the command name.
In the most recently posted patch series, the command name is moved
into a subclass of mi_command, the python mi_command_py, which
inherits from mi_command is then free to use a smart pointer to manage
the memory for the name.

In this patch, I leave the mi_command class unchanged, and instead
hold the memory for the name within the Python object, as the lifetime
of the Python object always exceeds the c++ object stored in the
mi_cmd_table.  This adds a little more complexity in py-micmd.c, but
leaves the mi_command class nice and simple.

Next, this patch adds some extra functionality, there's a
MICommand.name read-only attribute containing the name of the command,
and a read-write MICommand.installed attribute that can be used to
install (make the command available for use) and uninstall (remove the
command from the mi_cmd_table so it can't be used) the command.  This
attribute will be automatically updated if a second command replaces
an earlier command.

This patch adds additional error handling, and makes more use the
gdbpy_handle_exception function.

Co-Authored-By: Jan Vrany <jan.vrany@labware.com>
2022-03-14 14:09:09 +00:00
Andrew Burgess
551b380fbd gdb/python: add Type.is_signed property
Add a new read-only property, Type.is_signed, which is True for signed
types, and False otherwise.

This property should only be read on types for which Type.is_scalar is
true, attempting to read this property for non-scalar types will raise
a ValueError.

I chose 'is_signed' rather than 'is_unsigned' in order to match the
existing Architecture.integer_type method, which takes a 'signed'
parameter.  As far as I could find, that was the only existing
signed/unsigned selector in the Python API, so it seemed reasonable to
stay consistent.
2022-03-07 19:42:08 +00:00
Andrew Burgess
ee6a3d9e94 gdb/python: add Type.is_scalar property
Add a new read-only property which is True for scalar types,
otherwise, it's False.
2022-03-07 19:42:07 +00:00
Andrew Burgess
659971cb0f gdb/python: Add gdb.InferiorThread.details attribute
This adds a new read-only attribute gdb.InferiorThread.details, this
attribute contains a string, the results of target_extra_thread_info
for the thread, or None, if target_extra_thread_info returns nullptr.

As the string returned by target_extra_thread_info is unstructured,
this attribute is only really useful for echoing straight through to
the user, but, if a user wants to write a command that displays the
same, or a similar 'Thread Id' to the one seen in 'info threads', then
they need access to this string.

Given that the string produced by target_extra_thread_info varies by
target, there's only minimal testing of this attribute, I check that
the attribute can be accessed, and that the return value is either
None, or a string.
2022-02-28 17:01:31 +00:00
Andrew Burgess
0642912e83 gdb/python: allow Value.format_string to return styled output
Add a new argument to the gdb.Value.format_string method, 'styling'.
This argument is False by default.

When this argument is True, then the returned string can contain output
styling escape sequences.

When this argument is False, then the returned string will not contain
any styling escape sequences.

If the returned string is going to be printed to the user, then it is
often nice to retain the GDB styling.

For the testing, we need to adjust the TERM environment variable, as
we do for all the styling tests.  I'm now running all of the C tests
in gdb.python/py-format-string.exp in an environment where styling
could be generated, but only my new test should actually produce
styled output, hopefully this will catch the case where a bug might
cause format_string to always produce styled output.
2022-02-07 16:52:47 +00:00
Andrew Burgess
bbea680797 gdb/python: improve the auto help text for gdb.Parameter
This commit attempts to improve the help text that is generated for
gdb.Parameter objects when the user fails to provide their own
documentation.

Documentation for a gdb.Parameter is currently pulled from two
sources: the class documentation string, and the set_doc/show_doc
class attributes.  Thus, a fully documented parameter might look like
this:

  class Param_All (gdb.Parameter):
     """This is the class documentation string."""

     show_doc = "Show the state of this parameter"
     set_doc = "Set the state of this parameter"

     def get_set_string (self):
        val = "on"
        if (self.value == False):
           val = "off"
        return "Test Parameter has been set to " + val

     def __init__ (self, name):
        super (Param_All, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)
        self._value = True

  Param_All ('param-all')

Then in GDB we see this:

  (gdb) help set param-all
  Set the state of this parameter
  This is the class documentation string.

Which is fine.  But, if the user skips both of the documentation parts
like this:

  class Param_None (gdb.Parameter):

     def get_set_string (self):
        val = "on"
        if (self.value == False):
           val = "off"
        return "Test Parameter has been set to " + val

     def __init__ (self, name):
        super (Param_None, self).__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)
        self._value = True

  Param_None ('param-none')

Now in GDB we see this:

  (gdb) help set param-none
  This command is not documented.
  This command is not documented.

That's not great, the duplicated text looks a bit weird.  If we drop
different parts we get different results.  Here's what we get if the
user drops the set_doc and show_doc attributes:

  (gdb) help set param-doc
  This command is not documented.
  This is the class documentation string.

That kind of sucks, we say it's undocumented, then proceed to print
the documentation.  Finally, if we drop the class documentation but
keep the set_doc and show_doc:

  (gdb) help set param-set-show
  Set the state of this parameter
  This command is not documented.

That seems OK.

So, I think there's room for improvement.

With this patch, for the four cases above we now see this:

  # All values provided by the user, no change in this case:
  (gdb) help set param-all
  Set the state of this parameter
  This is the class documentation string.

  # Nothing provided by the user, the first string is now different:
  (gdb) help set param-none
  Set the current value of 'param-none'.
  This command is not documented.

  # Only the class documentation is provided, the first string is
  # changed as in the previous case:
  (gdb) help set param-doc
  Set the current value of 'param-doc'.
  This is the class documentation string.

  # Only the set_doc and show_doc are provided, this case is unchanged
  # from before the patch:
  (gdb) help set param-set-show
  Set the state of this parameter
  This command is not documented.

The one place where this change might be considered a negative is when
dealing with prefix commands.  If we create a prefix command but don't
supply the set_doc / show_doc strings, then this is what we saw before
my patch:

  (gdb) python Param_None ('print param-none')
  (gdb) help set print
  set print, set pr, set p
  Generic command for setting how things print.

  List of set print subcommands:

  ... snip ...
  set print param-none -- This command is not documented.
  ... snip ...

And after my patch:

  (gdb) python Param_None ('print param-none')
  (gdb) help set print
  set print, set pr, set p
  Generic command for setting how things print.

  List of set print subcommands:

  ... snip ...
  set print param-none -- Set the current value of 'print param-none'.
  ... snip ...

This seems slightly less helpful than before, but I don't think its
terrible.

Additionally, I've changed what we print when the get_show_string
method is not provided in Python.

Back when gdb.Parameter was first added to GDB, we didn't provide a
show function when registering the internal command object within
GDB.  As a result, GDB would make use of its "magic" mangling of the
show_doc string to create a sentence that would display the current
value (see deprecated_show_value_hack in cli/cli-setshow.c).

However, when we added support for the get_show_string method to
gdb.Parameter, there was an attempt to maintain backward compatibility
by displaying the show_doc string with the current value appended, see
get_show_value in py-param.c.  Unfortunately, this isn't anywhere
close to what deprecated_show_value_hack does, and the results are
pretty poor, for example, this is GDB before my patch:

  (gdb) show param-none
  This command is not documented. off

I think we can all agree that this is pretty bad.

After my patch, we how show this:

  (gdb) show param-none
  The current value of 'param-none' is "off".

Which at least is a real sentence, even if it's not very informative.

This patch does change the way that the Python API behaves slightly,
but only in the cases when the user has missed providing GDB with some
information.  In most cases I think the new behaviour is a lot better,
there's the one case (noted above) which is a bit iffy, but I think is
still OK.

I've updated the existing gdb.python/py-parameter.exp test to cover
the modified behaviour.

Finally, I've updated the documentation to (I hope) make it clearer
how the various bits of help text come together.
2022-01-26 22:00:20 +00:00
Andrew Burgess
30a87e90be gdb/python: add gdb.history_count function
Add a new function gdb.history_count to the Python api, this function
returns an integer, the number of items in GDB's value history.

This is useful if you want to pull items from the history by their
absolute number, for example, if you wanted to show a complete history
list.  Previously we could figure out how many items are in the
history list by trying to fetch the items, and then catching the
exception when the item is not available, but having this function
seems nicer.
2022-01-26 21:58:12 +00:00
Tom Tromey
b583c328e7 Add a way to temporarily set a gdb parameter from Python
It's sometimes useful to temporarily set some gdb parameter from
Python.  Now that the 'endian' crash is fixed, and now that the
current language is no longer captured by the Python layer, it seems
reasonable to add a helper function for this situation.

This adds a new gdb.with_parameter function.  This creates a context
manager which temporarily sets some parameter to a specified value.
The old value is restored when the context is exited.  This is most
useful with the Python "with" statement:

   with gdb.with_parameter('language', 'ada'):
      ... do Ada stuff

This also adds a simple function to set a parameter,
gdb.set_parameter, as suggested by Andrew.

This is PR python/10790.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=10790
2022-01-26 06:49:51 -07:00
Andrew Burgess
965c919f98 gdb/doc: improve description for Window.click on Python TUI windows
The description of the Window.click method doesn't mention where the
coordinates are anchored (it's the top left corner).

This minor tweak just mentions this point.
2022-01-24 15:33:55 +00:00
Andrew Burgess
b13d7831eb gdb/doc: fill in two missing @r
I noticed two places in the docs where we appear to be missing @r.
makeinfo seems to do the correct things despite these being
missing (at least, I couldn't see any difference in the pdf or info
output), but it doesn't hurt to have the @r in place.
2022-01-21 12:49:48 +00:00
Andrew Burgess
61671e9792 gdb/python: add gdb.host_charset function
We already have gdb.target_charset and gdb.target_wide_charset.  This
commit adds gdb.host_charset along the same lines.
2022-01-12 16:00:07 +00:00
Joel Brobecker
4a94e36819 Automatic Copyright Year update after running gdb/copyright.py
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.

For the avoidance of doubt, all changes in this commits were
performed by the script.
2022-01-01 19:13:23 +04:00
Andrew Burgess
2988a36005 gdb/python: Use tp_init instead of tp_new to setup gdb.Value
The documentation suggests that we implement gdb.Value.__init__,
however, this is not currently true, we really implement
gdb.Value.__new__.  This will cause confusion if a user tries to
sub-class gdb.Value.  They might write:

  class MyVal (gdb.Value):
      def __init__ (self, val):
          gdb.Value.__init__(self, val)

  obj = MyVal(123)
  print ("Got: %s" % obj)

But, when they source this code they'll see:

  (gdb) source ~/tmp/value-test.py
  Traceback (most recent call last):
    File "/home/andrew/tmp/value-test.py", line 7, in <module>
      obj = MyVal(123)
    File "/home/andrew/tmp/value-test.py", line 5, in __init__
      gdb.Value.__init__(self, val)
  TypeError: object.__init__() takes exactly one argument (the instance to initialize)
  (gdb)

The reason for this is that, as we don't implement __init__ for
gdb.Value, Python ends up calling object.__init__ instead, which
doesn't expect any arguments.

The Python docs suggest that the reason why we might take this
approach is because we want gdb.Value to be immutable:

   https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_new

But I don't see any reason why we should require gdb.Value to be
immutable when other types defined in GDB are not.  This current
immutability can be seen in this code:

  obj = gdb.Value(1234)
  print("Got: %s" % obj)
  obj.__init__ (5678)
  print("Got: %s" % obj)

Which currently runs without error, but prints:

  Got: 1234
  Got: 1234

In this commit I propose that we switch to using __init__ to
initialize gdb.Value objects.

This does introduce some additional complexity, during the __init__
call a gdb.Value might already be associated with a gdb value object,
in which case we need to cleanly break that association before
installing the new gdb value object.  However, the cost of doing this
is not great, and the benefit - being able to easily sub-class
gdb.Value seems worth it.

After this commit the first example above works without error, while
the second example now prints:

  Got: 1234
  Got: 5678

In order to make it easier to override the gdb.Value.__init__ method,
I have tweaked the definition of gdb.Value.__init__.  The second,
optional argument to __init__ is a gdb.Type, if this argument is not
present then GDB figures out a suitable type.

However, if we want to override the __init__ method in a sub-class,
and still support the default argument, it is easier to write:

  class MyVal (gdb.Value):
      def __init__ (self, val, type=None):
          gdb.Value.__init__(self, val, type)

Currently, passing None for the Type will result in an error:

  TypeError: type argument must be a gdb.Type.

After this commit I now allow the type argument to be None, in which
case GDB figures out a suitable type just as if the type had not been
passed at all.

Unless a user is trying to reinitialize a value, or create sub-classes
of gdb.Value, there should be no user visible changes after this
commit.
2021-12-08 13:38:11 +00:00
Andrew Burgess
24b2de7b77 gdb/python: add gdb.RemoteTargetConnection.send_packet
This commits adds a new sub-class of gdb.TargetConnection,
gdb.RemoteTargetConnection.  This sub-class is created for all
'remote' and 'extended-remote' targets.

This new sub-class has one additional method over its base class,
'send_packet'.  This new method is equivalent to the 'maint
packet' CLI command, it allows a custom packet to be sent to a remote
target.

The outgoing packet can either be a bytes object, or a Unicode string,
so long as the Unicode string contains only ASCII characters.

The result of calling RemoteTargetConnection.send_packet is a bytes
object containing the reply that came from the remote.
2021-11-30 12:10:40 +00:00
Andrew Burgess
0e3b7c25ee gdb/python: introduce gdb.TargetConnection object type
This commit adds a new object type gdb.TargetConnection.  This new
type represents a connection within GDB (a connection as displayed by
'info connections').

There's three ways to find a gdb.TargetConnection, there's a new
'gdb.connections()' function, which returns a list of all currently
active connections.

Or you can read the new 'connection' property on the gdb.Inferior
object type, this contains the connection for that inferior (or None
if the inferior has no connection, for example, it is exited).

Finally, there's a new gdb.events.connection_removed event registry,
this emits a new gdb.ConnectionEvent whenever a connection is removed
from GDB (this can happen when all inferiors using a connection exit,
though this is not always the case, depending on the connection type).
The gdb.ConnectionEvent has a 'connection' property, which is the
gdb.TargetConnection being removed from GDB.

The gdb.TargetConnection has an 'is_valid()' method.  A connection
object becomes invalid when the underlying connection is removed from
GDB (as discussed above, this might be when all inferiors using a
connection exit, or it might be when the user explicitly replaces a
connection in GDB by issuing another 'target' command).

The gdb.TargetConnection has the following read-only properties:

  'num': The number for this connection,

  'type': e.g. 'native', 'remote', 'sim', etc

  'description': The longer description as seen in the 'info
                 connections' command output.

  'details': A string or None.  Extra details for the connection, for
             example, a remote connection's details might be
             'hostname:port'.
2021-11-30 12:10:33 +00:00
Tom Tromey
d3771fe234 Add gdb.Architecture.integer_type Python function
This adds a new Python function, gdb.Architecture.integer_type, which
can be used to look up an integer type of a given size and
signed-ness.  This is useful to avoid dependency on debuginfo when a
particular integer type would be useful.

v2 moves this to be a method on gdb.Architecture and addresses other
review comments.
2021-10-29 07:52:31 -06:00
Andrew Burgess
8b87fbe6bb gdb/python: new gdb.architecture_names function
Add a new function to the Python API, gdb.architecture_names().  This
function returns a list containing all of the supported architecture
names within the current build of GDB.

The values returned in this list are all of the possible values that
can be returned from gdb.Architecture.name().
2021-10-22 13:42:49 +01:00
Andrew Burgess
b1f0f28418 gdb/python: add a new gdb_exiting event
Add a new event, gdb.events.gdb_exiting, which is called once GDB
decides it is going to exit.

This event is not triggered in the case that GDB performs a hard
abort, for example, when handling an internal error and the user
decides to quit the debug session, or if GDB hits an unexpected,
fatal, signal.

This event is triggered if the user just types 'quit' at the command
prompt, or if GDB is run with '-batch' and has processed all of the
required commands.

The new event type is gdb.GdbExitingEvent, and it has a single
attribute exit_code, which is the value that GDB is about to exit
with.

The event is triggered before GDB starts dismantling any of its own
internal state, so, my expectation is that most Python calls should
work just fine at this point.

When considering this functionality I wondered about using the
'atexit' Python module.  However, this is triggered when the Python
environment is shut down, which is done from a final cleanup.  At
this point we don't know for sure what other GDB state has already
been cleaned up.
2021-10-05 10:05:40 +01:00