Commit Graph

782 Commits

Author SHA1 Message Date
Tom Tromey
ed80156930 Add gdb.Value.assign method
This adds an 'assign' method to gdb.Value.  This allows for assignment
without requiring the use of parse_and_eval.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-06-12 12:09:39 -06:00
Tom de Vries
9f82823f89 [gdb/testsuite] Relax breakpoint count check in gdb.python/py-rbreak.exp
With a gdb 13.2 based package on SLE-15 aarch64,  I run into:
...
(gdb) PASS: gdb.python/py-rbreak.exp: nosharedlibrary
py sl = gdb.rbreak("^[^_]",minsyms=False)^M
Breakpoint 2 at 0x4004ac: file ../sysdeps/aarch64/crti.S, line 63.^M
  ...
(gdb) py print(len(sl))^M
12^M
(gdb) FAIL: gdb.python/py-rbreak.exp: check number of returned breakpoints is 11
...

The FAIL is due to:
- the glibc object crti.o containing debug information for function
  call_weak_fn, and
- the test-case not expecting this.

The debug information is there due to compiling glibc using a binutils which
contains commit 591cc9fbbf ("gas/Dwarf: record functions").

I've run into a similar issue before, see commit 3fbbcf473a ("[gdb/testsuite]
Fix regexp in py-rbreak.exp").

The fix I applied there was to use a regexp "^[^_]" to filter out
__libc_csu_fini and __libc_csu_init, but that doesn't work for call_weak_fn.

Fix this by:
- reverting the regexp to "", and
- rewriting the check to require at least 11 functions, rather than a precise
  match.

Tested on x86_64-linux.

PR testsuite/30538
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30538
2023-06-12 13:00:09 +02:00
Tom de Vries
d033023bc4 [gdb/testsuite] Add missing wait in gdb.python/tui-window-disabled.exp
While working on PR tui/30526, I noticed a bug in test-case
gdb.python/tui-window-disabled.exp.

Here we send "tui enable" to gdb, but don't wait for it to arrive before
checking for a window box:
...
    send_gdb "tui enable\n"
    Term::check_box "check for python window" 0 0 80 16
...

Fix this by waiting for the prompt to be issued in TUI before doing the check.

Tested on x86_64-linux.
2023-06-07 11:36:19 +02:00
Tom de Vries
d791a1b6ae [gdb/testsuite] Fix two typos in gdb.python/tui-window-disabled.exp
Fix two typos in test-case gdb.python/tui-window-disabled.exp.
2023-06-07 11:36:19 +02:00
Andrew Burgess
baab375361 gdb: building inferior strings from within GDB
History Of This Patch
=====================

This commit aims to address PR gdb/21699.  There have now been a
couple of attempts to fix this issue.  Simon originally posted two
patches back in 2021:

  https://sourceware.org/pipermail/gdb-patches/2021-July/180894.html
  https://sourceware.org/pipermail/gdb-patches/2021-July/180896.html

Before Pedro then posted a version of his own:

  https://sourceware.org/pipermail/gdb-patches/2021-July/180970.html

After this the conversation halted.  Then in 2023 I (Andrew) also took
a look at this bug and posted two versions:

  https://sourceware.org/pipermail/gdb-patches/2023-April/198570.html
  https://sourceware.org/pipermail/gdb-patches/2023-April/198680.html

The approach taken in my first patch was pretty similar to what Simon
originally posted back in 2021.  My second attempt was only a slight
variation on the first.

Pedro then pointed out his older patch, and so we arrive at this
patch.  The GDB changes here are mostly Pedro's work, but updated by
me (Andrew), any mistakes are mine.

The tests here are a combinations of everyone's work, and the commit
message is new, but copies bits from everyone's earlier work.

Problem Description
===================

Bug PR gdb/21699 makes the observation that using $_as_string with
GDB's printf can cause GDB to print unexpected data from the
inferior.  The reproducer is pretty simple:

  #include <stddef.h>
  static char arena[100];

  /* Override malloc() so value_coerce_to_target() gets a known
     pointer, and we know we"ll see an error if $_as_string() gives
     a string that isn't null terminated. */
  void
  *malloc (size_t size)
  {
      memset (arena, 'x', sizeof (arena));
      if (size > sizeof (arena))
          return NULL;
      return arena;
  }

  int
  main ()
  {
    return 0;
  }

And then in a GDB session:

  $ gdb -q test
  Reading symbols from /tmp/test...
  (gdb) start
  Temporary breakpoint 1 at 0x4004c8: file test.c, line 17.
  Starting program: /tmp/test

  Temporary breakpoint 1, main () at test.c:17
  17        return 0;
  (gdb) printf "%s\n", $_as_string("hello")
  "hello"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  (gdb) quit

The problem above is caused by how value_cstring is used within
py-value.c, but once we understand the issue then it turns out that
value_cstring is used in an unexpected way in many places within GDB.

Within py-value.c we have a null-terminated C-style string.  We then
pass a pointer to this string, along with the length of this
string (so not including the null-character) to value_cstring.

In value_cstring GDB allocates an array value of the given character
type, and copies in requested number of characters.  However
value_cstring does not add a null-character of its own.  This means
that the value created by calling value_cstring is only
null-terminated if the null-character is included in the passed in
length.  In py-value.c this is not the case, and indeed, in most uses
of value_cstring, this is not the case.

When GDB tries to print one of these strings the value contents are
pushed to the inferior, and then read back as a C-style string, that
is, GDB reads inferior memory until it finds a null-terminator.  For
the py-value.c case, no null-terminator is pushed into the inferior,
so GDB will continue reading inferior memory until a null-terminator
is found, with unpredictable results.

Patch Description
=================

The first thing this patch does is better define what the arguments
for the two function value_cstring and value_string should represent.
The comments in the header file are updated to describe whether the
length argument should, or should not, include a null-character.
Also, the data argument is changed to type gdb_byte.  The functions as
they currently exist will handle wide-characters, in which case more
than one 'char' would be needed for each character.  As such using
gdb_byte seems to make more sense.

To avoid adding casts throughout GDB, I've also added an overload that
still takes a 'char *', but asserts that the character type being used
is of size '1'.

The value_cstring function is now responsible for adding a null
character at the end of the string value it creates.

However, once we start looking at how value_cstring is used, we
realise there's another, related, problem.  Not every language's
strings are null terminated.  Fortran and Ada strings, for example,
are just an array of characters, GDB already has the function
value_string which can be used to create such values.

Consider this example using current GDB:

  (gdb) set language ada
  (gdb) p $_gdb_setting("arch")
  $1 = (97, 117, 116, 111)
  (gdb) ptype $
  type = array (1 .. 4) of char
  (gdb) p $_gdb_maint_setting("test-settings string")
  $2 = (0)
  (gdb) ptype $
  type = array (1 .. 1) of char

This shows two problems, first, the $_gdb_setting and
$_gdb_maint_setting functions are calling value_cstring using the
builtin_char character, rather than a language appropriate type.  In
the first call, the 'arch' case, the value_cstring call doesn't
include the null character, so the returned array only contains the
expected characters.  But, in the $_gdb_maint_setting example we do
end up including the null-character, even though this is not expected
for Ada strings.

This commit adds a new language method language_defn::value_string,
this function takes a pointer and length and creates a language
appropriate value that represents the string.  For C, C++, etc this
will be a null-terminated string (by calling value_cstring), and for
Fortran and Ada this can be a bounded array of characters with no null
terminator.  Additionally, this new language_defn::value_string
function is responsible for selecting a language appropriate character
type.

After this commit the only calls to value_cstring are from the C
expression evaluator and from the default language_defn::value_string.

And the only calls to value_string are from Fortan, Ada, and ObjectC
related code.

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

Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Co-Authored-By: Pedro Alves <pedro@palves.net>
Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-06-05 13:25:08 +01:00
Tom de Vries
33b5899fc0 [gdb] Fix typos
Fix a few typos:
- implemention -> implementation
- convertion(s) -> conversion(s)
- backlashes -> backslashes
- signoring -> ignoring
- (un)ambigious -> (un)ambiguous
- occured -> occurred
- hidding -> hiding
- temporarilly -> temporarily
- immediatelly -> immediately
- sillyness -> silliness
- similiar -> similar
- porkuser -> pokeuser
- thats -> that
- alway -> always
- supercede -> supersede
- accomodate -> accommodate
- aquire -> acquire
- priveleged -> privileged
- priviliged -> privileged
- priviledges -> privileges
- privilige -> privilege
- recieve -> receive
- (p)refered -> (p)referred
- succesfully -> successfully
- successfuly -> successfully
- responsability -> responsibility
- wether -> whether
- wich -> which
- disasbleable -> disableable
- descriminant -> discriminant
- construcstor -> constructor
- underlaying -> underlying
- underyling -> underlying
- structureal -> structural
- appearences -> appearances
- terciarily -> tertiarily
- resgisters -> registers
- reacheable -> reachable
- likelyhood -> likelihood
- intepreter -> interpreter
- disassemly -> disassembly
- covnersion -> conversion
- conviently -> conveniently
- atttribute -> attribute
- struction -> struct
- resonable -> reasonable
- popupated -> populated
- namespaxe -> namespace
- intialize -> initialize
- identifer(s) -> identifier(s)
- expection -> exception
- exectuted -> executed
- dungerous -> dangerous
- dissapear -> disappear
- completly -> completely
- (inter)changable -> (inter)changeable
- beakpoint -> breakpoint
- automativ -> automatic
- alocating -> allocating
- agressive -> aggressive
- writting -> writing
- reguires -> requires
- registed -> registered
- recuding -> reducing
- opeartor -> operator
- ommitted -> omitted
- modifing -> modifying
- intances -> instances
- imbedded -> embedded
- gdbaarch -> gdbarch
- exection -> execution
- direcive -> directive
- demanged -> demangled
- decidely -> decidedly
- argments -> arguments
- agrument -> argument
- amespace -> namespace
- targtet -> target
- supress(ed) -> suppress(ed)
- startum -> stratum
- squence -> sequence
- prompty -> prompt
- overlow -> overflow
- memember -> member
- languge -> language
- geneate -> generate
- funcion -> function
- exising -> existing
- dinking -> syncing
- destroh -> destroy
- clenaed -> cleaned
- changep -> changedp (name of variable)
- arround -> around
- aproach -> approach
- whould -> would
- symobl -> symbol
- recuse -> recurse
- outter -> outer
- freeds -> frees
- contex -> context

Tested on x86_64-linux.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-03 22:43:57 +02:00
Tom Tromey
3153113252 Add attributes and methods to gdb.Inferior
This adds two new attributes and three new methods to gdb.Inferior.

The attributes let Python code see the command-line arguments and the
name of "main".  Argument setting is also supported.

The methods let Python code manipulate the inferior's environment
variables.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-05-24 06:16:10 -06:00
Tom Tromey
125862f0f2 Add global_context parameter to gdb.parse_and_eval
This adds a 'global_context' parse_and_eval to gdb.parse_and_eval.
This lets users request a parse that is done at "global scope".

I considered letting callers pass in a block instead, with None
meaning "global" -- but then there didn't seem to be a clean way to
express the default for this parameter.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-05-23 14:17:04 -06:00
Tom Tromey
c97d123d67 Implement gdb.execute_mi
This adds a new Python function, gdb.execute_mi, that can be used to
invoke an MI command but get the output as a Python object, rather
than a string.  This is done by implementing a new ui_out subclass
that builds a Python object.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=11688
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-05-23 10:09:28 -06:00
Andrew Burgess
637969a709 gdb/testsuite: handle older Python versions in gdb.python/py-disasm.exp
It was pointed out on the mailing list that the new tests added in
this commit:

  commit 4de4e48514
  Date:   Tue Jan 24 15:35:45 2023 +0000

      gdb/python: extend the Python Disassembler API to allow for styling

will fail when GDB is built with Python 3.6 or earlier.  This is
because the error that is emitted when a function argument is missing
changed in Python 3.7, instead of an error like this:

  Python Exception <class 'TypeError'>: function missing required argument 'style' (pos 1)

earlier versions of Python emit:

  Python Exception <class 'TypeError'>: Required argument 'style' (pos 1) not found

and the new tests didn't allow for this.

This commit fixes this by allowing either pattern.  I've tested this
building GDB against Python 3.7.9 and 3.6.15, with this commit all
tests in gdb.python/py-disasm.exp now pass.
2023-05-19 09:58:46 +01:00
Paul Pluzhnikov
73eff1cbd3 Update comments for the gdb/24331 fix.
Approved-by: Andrew Burgess <aburgess@redhat.com>
2023-05-16 12:27:47 +00:00
Andrew Burgess
66b8e6c7b8 gdb/testsuite: fix formatting of gdb.python/py-disasm.py
Run black on gdb.python/py-disasm.py file and commit the changes.
2023-05-16 11:59:45 +01:00
Andrew Burgess
4de4e48514 gdb/python: extend the Python Disassembler API to allow for styling
This commit extends the Python Disassembler API to allow for styling
of the instructions.

Before this commit the Python Disassembler API allowed the user to do
two things:

  - They could intercept instruction disassembly requests and return a
    string of their choosing, this string then became the disassembled
    instruction, or

  - They could call builtin_disassemble, which would call back into
    libopcode to perform the disassembly.  As libopcode printed the
    instruction GDB would collect these print requests and build a
    string.  This string was then returned from the builtin_disassemble
    call, and the user could modify or extend this string as needed.

Neither of these approaches allowed for, or preserved, disassembler
styling, which is now available within libopcodes for many of the more
popular architectures GDB supports.

This commit aims to fill this gap.  After this commit a user will be
able to do the following things:

  - Implement a custom instruction disassembler entirely in Python
    without calling back into libopcodes, the custom disassembler will
    be able to return styling information such that GDB will display
    the instruction fully styled.  All of GDB's existing style
    settings will affect how instructions coming from the Python
    disassembler are displayed in the expected manner.

  - Call builtin_disassemble and receive a result that represents how
    libopcode would like the instruction styled.  The user can then
    adjust or extend the disassembled instruction before returning the
    result to GDB.  Again, the instruction will be styled as expected.

To achieve this I will add two new classes to GDB,
DisassemblerTextPart and DisassemblerAddressPart.

Within builtin_disassemble, instead of capturing the print calls from
libopcodes and building a single string, we will now create either a
text part or address part and store these parts in a vector.

The DisassemblerTextPart will capture a small piece of text along with
the associated style that should be used to display the text.  This
corresponds to the disassembler calling
disassemble_info::fprintf_styled_func, or for disassemblers that don't
support styling disassemble_info::fprintf_func.

The DisassemblerAddressPart is used when libopcodes requests that an
address be printed, and takes care of printing the address and
associated symbol, this corresponds to the disassembler calling
disassemble_info::print_address_func.

These parts are then placed within the DisassemblerResult when
builtin_disassemble returns.

Alternatively, the user can directly create parts by calling two new
methods on the DisassembleInfo class: DisassembleInfo.text_part and
DisassembleInfo.address_part.

Having created these parts the user can then pass these parts when
initializing a new DisassemblerResult object.

Finally, when we return from Python to gdbpy_print_insn, one way or
another, the result being returned will have a list of parts.  Back in
GDB's C++ code we walk the list of parts and call back into GDB's core
to display the disassembled instruction with the correct styling.

The new API lives in parallel with the old API.  Any existing code
that creates a DisassemblerResult using a single string immediately
creates a single DisassemblerTextPart containing the entire
instruction and gives this part the default text style.  This is also
what happens if the user calls builtin_disassemble for an architecture
that doesn't (yet) support libopcode styling.

This matches up with what happens when the Python API is not involved,
an architecture without disassembler styling support uses the old
libopcodes printing API (the API that doesn't pass style info), and
GDB just prints everything using the default text style.

The reason that parts are created by calling methods on
DisassembleInfo, rather than calling the class constructor directly,
is DisassemblerAddressPart.  Ideally this part would only hold the
address which the part represents, but in order to support backwards
compatibility we need to be able to convert the
DisassemblerAddressPart into a string.  To do that we need to call
GDB's internal print_address function, and to do that we need an
gdbarch.

What this means is that the DisassemblerAddressPart needs to take a
gdb.Architecture object at creation time.  The only valid place a user
can pull this from is from the DisassembleInfo object, so having the
DisassembleInfo act as a factory ensures that the correct gdbarch is
passed over each time.  I implemented both solutions (the one
presented here, and an alternative where parts could be constructed
directly), and this felt like the cleanest solution.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-16 10:30:47 +01:00
Andrew Burgess
0af2f23333 gdb/python: rework how the disassembler API reads the result object
This commit is a refactor ahead of the next change which will make
disassembler styling available through the Python API.

Unfortunately, in order to make the styling support available, I think
the easiest solution is to make a very small change to the existing
API.

The current API relies on returning a DisassemblerResult object to
represent each disassembled instruction.  Currently GDB allows the
DisassemblerResult class to be sub-classed, which could mean that a
user tries to override the various attributes that exist on the
DisassemblerResult object.

This commit removes this ability, effectively making the
DisassemblerResult class final.

Though this is a change to the existing API, I'm hoping this isn't
going to cause too many issues:

  - The Python disassembler API was only added in the previous release
    of GDB, so I don't expect it to be widely used yet, and

  - It's not clear to me why a user would need to sub-class the
    DisassemblerResult type, I allowed it in the original patch
    because at the time I couldn't see any reason to NOT allow it.

Having prevented sub-classing I can now rework the tail end of the
gdbpy_print_insn function; instead of pulling the results out of the
DisassemblerResult object by calling back into Python, I now cast the
Python object back to its C++ type (disasm_result_object), and access
the fields directly from there.  In later commits I will be reworking
the disasm_result_object type in order to hold information about the
styled disassembler output.

The tests that dealt with sub-classing DisassemblerResult have been
removed, and a new test that confirms that DisassemblerResult can't be
sub-classed has been added.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-05-16 10:30:46 +01:00
Paul Pluzhnikov
d2b585f3cf Fix bad interaction between element limit and repeated values (BZ#24331).
Currently

  print -elements=3 -- "AAAAAA"

prints complete string, which is not what the user asked for.

Fix two buggy tests exposed by the fix, and add a new test.

Reviewed-by: Keith Seitz <keiths@redhat.com>
2023-05-13 18:10:05 +00:00
Andrew Burgess
6a66780739 gdb/python: implement DisassemblerResult.__str__ method
Add the DisassemblerResult.__str__ method.  This gives the same result
as the DisassemblerResult.string attribute, but can be useful
sometimes depending on how the user is trying to print the object.

There's a test for the new functionality.
2023-05-12 18:24:24 +01:00
Andrew Burgess
15ccb5e393 gdb/python: implement __repr__ methods for py-disasm.c types
Add a __repr__ method for the DisassembleInfo and DisassemblerResult
types, and add some tests for these new methods.
2023-05-12 18:24:24 +01:00
Johnson Sun
6e96d8a970 Disable out-of-scope watchpoints
Currently, when a local software watchpoint goes out of scope, GDB sets
the watchpoint's disposition to `delete at next stop' and then normal
stops (i.e., stop and wait for the next GDB command). When GDB normal
stops, it automatically deletes the breakpoints with their disposition
set to `delete at next stop'.

Suppose a Python script decides not to normal stop when a local
software watchpoint goes out of scope, the watchpoint will not be
automatically deleted even when its disposition is set to
`delete at next stop'.

Since GDB single-steps the program and tests the watched expression
after each instruction, not deleting the watchpoint causes the
watchpoint to be hit many more times than it should, as reported in
PR python/29603.

This was happening because the watchpoint is not deleted or disabled
when going out of scope.

This commit fixes this issue by disabling the watchpoint when going out
of scope. It also adds a test to ensure this feature isn't regressed in
the future.

Calling `breakpoint_auto_delete' on all kinds of stops (in
`fetch_inferior_event') seem to solve this issue, but is in fact
inappropriate, since `breakpoint_auto_delete' goes over all breakpoints
instead of just going through the bpstat chain (which only contains the
breakpoints that were hit right now).

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29603
Change-Id: Ia85e670b2bcba2799219abe4b6be3b582387e383
2023-05-11 12:09:10 -04:00
Tom Tromey
3c0e312054 Allow pretty-print of static members
Python pretty-printers haven't applied to static members for quite
some time.  I tracked this down to the call to cp_print_value_fields
in cp_print_static_field -- it doesn't let pretty-printers have a
chance to print the value.  This patch fixes the problem.

The way that static members are handled is very weird to me.  I tend
to think this should be done more globally, like in value_print.
However, I haven't made any big change.

Reviewed-by:  Keith Seitz <keiths@redhat.com>
Tested-by:  Keith Seitz <keiths@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30057
2023-05-06 10:38:31 -06:00
Andrew Burgess
a5d3f94c27 gdb/testsuite: more newline pattern cleanup
After this commit:

  commit e2f620135d
  Date:   Thu Mar 30 13:26:25 2023 +0100

      gdb/testsuite: change newline patterns used in gdb_test

It was pointed out in PR gdb/30403 that the same patterns can be found
in other lib/gdb.exp procs and that it would probably be a good idea
if these procs remained in sync with gdb_test.  Actually, the bug
specifically calls out gdb_test_multiple when using with '-wrap', but
I found a couple of other locations in gdb_continue_to_breakpoint,
gdb_test_multiline, get_valueof, and get_local_valueof.

In all these locations one or both of the following issues are
addressed:

  1. A leading pattern of '[\r\n]*' is pointless.  If there is a
  newline it will be matched, but if there is not then the testsuite
  doesn't care.  Also, as expect is happy to skip non-matched output
  at the start of a pattern, if there is a newline expect is happy to
  skip over it before matching the rest.  As such, this leading
  pattern is removed.

  2. Using '\[\r\n\]*$gdb_prompt' means that we will swallow
  unexpected blank lines at the end of a command's output, but also,
  if the pattern from the test script ends with a '\r', '\n', or '.'
  then these will partially match the trailing newline, with the
  remainder of the newline matched by the pattern from gdb.exp.  This
  split matching doesn't add any value, it's just something that has
  appeared as a consequence of how gdb.exp was originally written.  In
  this case the '\[\r\n\]*' is replaced with '\r\n'.

I've rerun the testsuite and fixed the regressions that I saw, these
were places where GDB emits a blank line at the end of the command
output, which we now need to explicitly match in the test script, this
was for:

  gdb.dwarf2/dw2-out-of-range-end-of-seq.exp
  gdb.guile/guile.exp
  gdb.python/python.exp

Or a location where the test script was matching part of the newline
sequence, while gdb.exp was previously matching the remainder of the
newline sequence.  Now we rely on gdb.exp to match the complete
newline sequence, this was for:

  gdb.base/commands.exp

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30403
2023-05-05 17:59:21 +01:00
Andrew Burgess
08ec06d644 gdb/testsuite: special case '^' in gdb_test pattern
In this commit I propose that we add special handling for the '^' when
used at the start of a gdb_test pattern.  Consider this usage:

  gdb_test "some_command" "^command output pattern"

I think the intention here is pretty clear - run 'some_command', and
the output from the command should be exactly 'command output
pattern'.

After the previous commit which tightened up how gdb_test matches the
final newline and prompt we know that the only thing after the output
pattern will be a single newline and prompt, and the leading '^'
ensures that there's no output before 'command output pattern', so
this will do what I want, right?

... except it doesn't.  The command itself will also needs to be
matched, so I should really write:

  gdb_test "some_command" "^some_command\r\ncommand output pattern"

which will do what I want, right?  Well, that's fine until I change
the command and include some regexp character, then I have to write:

  gdb_test "some_command" \
    "^[string_to_regexp some_command]\r\ncommand output pattern"

but this all gets a bit verbose, so in most cases I simply don't
bother anchoring the output with a '^', and a quick scan of the
testsuite would indicate that most other folk don't both either.

What I propose is this: the *only* thing that can appear immediately
after the '^' is the command converted into a regexp, so lets do that
automatically, moving the work into gdb_test.  Thus, when I write:

  gdb_test "some_command" "^command output pattern"

Inside gdb_test we will spot the leading '^' in the pattern, and
inject the regexp version of the command after the '^', followed by a
'\r\n'.

My hope is that given this new ability, folk will be more inclined to
anchor their output patterns when this makes sense to do so.  This
should increase our ability to catch any unexpected output from GDB
that appears as a result of running a particular command.

There is one problem case we need to consider, sometime people do
this:

  gdb_test "" "^expected output pattern"

In this case no command is sent to GDB, but we are still expecting
some output from GDB.  This might be a result of some asynchronous
event for example.  As there is no command sent to GDB (from the
gdb_test) there will be no command text to parse.

In this case my proposed new feature injects the command regexp, which
is the empty string (as the command itself is empty), but still
injects the '\r\n' after the command regexp, thus we end up with this
pattern:

  ^\r\nexpected output pattern

This extra '\r\n' is not what we should expected here, and so there is
a special case inside gdb_test -- if the command is empty then don't
add anything after the '^' character.

There are a bunch of tests that do already use '^' followed by the
command, and these can all be simplified in this commit.

I've tried to run all the tests that I can to check this commit, but I
am certain that there will be some tests that I manage to miss.
Apologies for any regressions this commit causes, hopefully fixing the
regressions will not be too hard.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-27 13:56:38 +01:00
Andrew Burgess
e2f620135d gdb/testsuite: change newline patterns used in gdb_test
This commit makes two changes to how we match newline characters in
the gdb_test proc.

First, for the newline pattern between the command output and the
prompt, I propose changing from '[\r\n]+' to an explicit '\r\n'.

The old pattern would spot multiple newlines, and so there are a few
places where, as part of this commit, I've needed to add an extra
trailing '\r\n' to the pattern in the main test file, where GDB's
output actually includes a blank line.

But I think this is a good thing.  If a command produces a blank line
then we should be checking for it, the current gdb_test doesn't do
that.  But also, with the current gdb_test, if a blank line suddenly
appears in the output, this is going to be silently ignored, and I
think this is wrong, the test should fail in that case.

Additionally, the existing pattern will happily match a partial
newline.  There are a strangely large number of tests that end with a
random '.' character.  Not matching a literal period, but matching any
single character, this is then matching half of the trailing newline
sequence, while the \[\r\n\]+ in gdb_test is matching the other half
of the sequence.  I can think of no reason why this would be
intentional, I suspect that the expected output at one time included a
period, which has since been remove, but I haven't bothered to check
on this.  In this commit I've removed all these unneeded trailing '.'
characters.

The basic rule of gdb_test after this is that the expected pattern
needs to match everything up to, but not including the newline
sequence immediately before the GDB prompt.  This is generally how the
proc is used anyway, so in almost all cases, this commit represents no
significant change.

Second, while I was cleaning up newline matching in gdb_test, I've
also removed the '[\r\n]*' that was added to the start of the pattern
passed to gdb_test_multiple.

The addition of this pattern adds no value.  If the user pattern
matches at the start of a line then this would match against the
newline sequence.  But, due to the '*', if the user pattern doesn't
match at the start of a line then this group doesn't care, it'll
happily match nothing.

As such, there's no value to it, it just adds more complexity for no
gain, so I'm removing it.  No tests will need updating as a
consequence of this part of the patch.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-27 13:56:37 +01:00
Simon Marchi
d7845ddc86 gdb: re-format Python code with black 23
Change-Id: I849d10d69c254342bf01e955ffe62a2b60f9de4b
2023-04-18 12:11:03 -04:00
Tom de Vries
31c5028017 [gdb/testsuite] Add -q to INTERNAL_GDBFLAGS
Whenever we start gdb in the testsuite, we have the rather verbose:
...
$ gdb
GNU gdb (GDB) 14.0.50.20230405-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)
...

This makes gdb.log longer than necessary and harder to read.

We do need to test that the output is produced, but that should be limited to
one or a few test-cases.

Fix this by adding -q to INTERNAL_GDBFLAGS, such that we simply have:
...
$ gdb -q
(gdb)
...

Tested on x86_64-linux.
2023-04-07 10:26:02 +02:00
Andrew Burgess
d344cef4bf gdb/python: allow Frame.read_var to accept named arguments
This commit allows Frame.read_var to accept named arguments, and also
improves (I think) some of the error messages emitted when values of
the wrong type are passed to this function.

The read_var method takes two arguments, one a variable, which is
either a gdb.Symbol or a string, while the second, optional, argument
is always a gdb.Block.

I'm now using 'O!' as the format specifier for the second argument,
which allows the argument type to be checked early on.  Currently, if
the second argument is of the wrong type then we get this error:

  (gdb) python print(gdb.selected_frame().read_var("a1", "xxx"))
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  RuntimeError: Second argument must be block.
  Error while executing Python code.
  (gdb)

After this commit, we now get an error like this:

  (gdb) python print(gdb.selected_frame().read_var("a1", "xxx"))
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  TypeError: argument 2 must be gdb.Block, not str
  Error while executing Python code.
  (gdb)

Changes are:

  1. Exception type is TypeError not RuntimeError, this is unfortunate
  as user code _could_ be relying on this, but I think the improvement
  is worth the risk, user code relying on the exact exception type is
  likely to be pretty rare,

  2. New error message gives argument position and expected argument
  type, as well as the type that was passed.

If the first argument, the variable, has the wrong type then the
previous exception was already a TypeError, however, I've updated the
text of the exception to more closely match the "standard" error
message we see above.  If the first argument has the wrong type then
before this commit we saw this:

  (gdb) python print(gdb.selected_frame().read_var(123))
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  TypeError: Argument must be a symbol or string.
  Error while executing Python code.
  (gdb)

And after we see this:

  (gdb) python print(gdb.selected_frame().read_var(123))
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  TypeError: argument 1 must be gdb.Symbol or str, not int
  Error while executing Python code.
  (gdb)

For existing code that doesn't use named arguments and doesn't rely on
exceptions, there will be no changes after this commit.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-06 15:04:17 +01:00
Andrew Burgess
02c7fce1ad gdb/python: convert Frame.read_register to take named arguments
Following on from the previous commit, this updates
Frame.read_register to accept named arguments.  As with the previous
commit there's no huge benefit for the users in accepting named
arguments here -- this function only takes a single argument after
all.

But I do think it is worth keeping Frame.read_register method in sync
with the PendingFrame.read_register method, this allows for the
possibility that the user has some code that can operate on either a
Frame or a Pending frame.

Minor update to allow for named arguments, and an extra test to check
the new functionality.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-06 15:03:55 +01:00
Andrew Burgess
56fcb715a9 gdb/python: have PendingFrame methods accept keyword arguments
Update the two gdb.PendingFrame methods gdb.PendingFrame.read_register
and gdb.PendingFrame.create_unwind_info to accept keyword arguments.

There's no huge benefit for making this change, both of these methods
only take a single argument, so it is (maybe) less likely that a user
will take advantage of the keyword arguments in these cases, but I
think it's nice to be consistent, and I don't see any particular draw
backs to making this change.

For PendingFrame.read_register I've changed the argument name from
'reg' to 'register' in the documentation and used 'register' as the
argument name in GDB.  My preference for APIs is to use full words
where possible, and given we didn't support named arguments before
this change should not break any existing code.

There should be no user visible changes (for existing code) after this
commit.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-06 15:01:43 +01:00
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
2dc3457a45 gdb: include breakpoint number in testing condition error message
When GDB fails to test the condition of a conditional breakpoint, for
whatever reason, the error message looks like this:

  (gdb) break foo if (*(int *) 0) == 1
  Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
  (gdb) r
  Starting program: /tmp/bpcond
  Error in testing breakpoint condition:
  Cannot access memory at address 0x0

  Breakpoint 1, foo () at bpcond.c:11
  11	  int a = 32;
  (gdb)

The line I'm interested in for this commit is this one:

  Error in testing breakpoint condition:

In the case above we can figure out that the problematic breakpoint
was #1 because in the final line of the message GDB reports the stop
at breakpoint #1.

However, in the next few patches I plan to change this.  In some cases
I don't think it makes sense for GDB to report the stop as being at
breakpoint #1, consider this case:

  (gdb) list some_func
  1	int
  2	some_func ()
  3	{
  4	  int *p = 0;
  5	  return *p;
  6	}
  7
  8	void
  9	foo ()
  10	{
  (gdb) break foo if (some_func ())
  Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
  (gdb) r
  Starting program: /tmp/bpcond

  Program received signal SIGSEGV, Segmentation fault.
  0x0000000000401116 in some_func () at bpcond.c:5
  5	  return *p;
  Error in testing breakpoint condition:
  The program being debugged was signaled while in a function called from GDB.
  GDB remains in the frame where the signal was received.
  To change this behavior use "set unwindonsignal on".
  Evaluation of the expression containing the function
  (some_func) will be abandoned.
  When the function is done executing, GDB will silently stop.

  Program received signal SIGSEGV, Segmentation fault.

  Breakpoint 1, 0x0000000000401116 in some_func () at bpcond.c:5
  5	  return *p;
  (gdb)

Notice that, the final lines of output reports the stop as being at
breakpoint #1, even though the inferior in not located within
some_func, and it's certainly not located at the breakpoint location.

I find this behaviour confusing, and propose that this should be
changed.  However, if I make that change then every reference to
breakpoint #1 will be lost from the error message.

So, in this commit, in preparation for the later commits, I propose to
change the 'Error in testing breakpoint condition:' line to this:

  Error in testing condition for breakpoint NUMBER:

where NUMBER will be filled in as appropriate.  Here's the first
example with the updated error:

  (gdb) break foo if (*(int *) 0) == 0
  Breakpoint 1 at 0x40111e: file bpcond.c, line 11.
  (gdb) r
  Starting program: /tmp/bpcond
  Error in testing condition for breakpoint 1:
  Cannot access memory at address 0x0

  Breakpoint 1, foo () at bpcond.c:11
  11	  int a = 32;
  (gdb)

The breakpoint number does now appear twice in the output, but I don't
see that as a negative.

This commit just changes the one line of the error, and updates the
few tests that either included the old error in comments, or actually
checked for the error in the expected output.

As the only test that checked the line I modified is a Python test,
I've added a new test that doesn't rely on Python that checks the
error message in detail.

While working on the new test, I spotted that it would fail when run
with native-gdbserver and native-extended-gdbserver target boards.
This turns out to be due to a gdbserver bug.  To avoid cluttering this
commit I've added a work around to the new test script so that the
test passes for the remote boards, in the next few commits I will fix
gdbserver, and update the test script to remove the work around.
2023-04-03 14:46:32 +01:00
Andrew Burgess
4c148f65fc gdb/testsuite: fix failure in gdb.python/py-unwind.exp
A potential test failure was introduced with commit:

  commit 6bf5f25bb1
  Date:   Wed Mar 8 16:11:30 2023 +0000

      gdb/python: make the gdb.unwinder.Unwinder class more robust

In this commit a new test was added, however the expected output
pattern varies depending on which Python version GDB is linked
against.

Older versions of Python result in output like this:

    (gdb) python global_test_unwinder.name = "foo"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    AttributeError: can't set attribute
    Error while executing Python code.
    (gdb)

While more recent versions of Python give a similar, but slightly more
verbose error message, like this:

    (gdb) python global_test_unwinder.name = "foo"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    AttributeError: can't set attribute 'name'
    Error while executing Python code.
    (gdb)

The test was only accepting the first version of the output.  This
commit extends the test pattern so that either version will be
accepted.
2023-04-03 10:56:10 +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
df4447e4c4 gdb/python: remove Py_TPFLAGS_BASETYPE from gdb.UnwindInfo
It is not currently possible to directly create gdb.UnwindInfo
instances, they need to be created by calling
gdb.PendingFrame.create_unwind_info so that the newly created
UnwindInfo can be linked to the pending frame.

As such there's no tp_init method defined for UnwindInfo.

A consequence of all this is that it doesn't really make sense to
allow sub-classing of gdb.UnwindInfo.  Any sub-class can't call the
parents __init__ method to correctly link up the PendingFrame
object (there is no parent __init__ method).  And any instances that
sub-classes UnwindInfo but doesn't call the parent __init__ is going
to be invalid for use in GDB.

This commit removes the Py_TPFLAGS_BASETYPE flag from the UnwindInfo
class, which prevents the class being sub-classed.  Then I've added a
test to check that this is indeed prevented.

Any functional user code will not have any issues with this change.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-30 10:25:46 +01:00
Andrew Burgess
7e6af18d0c gdb/python: add __repr__ for PendingFrame and UnwindInfo
Having a useful __repr__ method can make debugging Python code that
little bit easier.  This commit adds __repr__ for gdb.PendingFrame and
gdb.UnwindInfo classes, along with some tests.

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
44d9b0a174 gdb/python: add PENDING_FRAMEPY_REQUIRE_VALID macro in py-unwind.c
This commit copies the pattern that is present in many other py-*.c
files: having a single macro to check that the Python object is still
valid.

This cleans up the code a little throughout the py-unwind.c file.

Some of the exception messages will change slightly with this commit,
though the type of the exceptions is still ValueError in all cases.

I started writing some tests for this change and immediately ran into
a problem: GDB would crash.  It turns out that the PendingFrame
objects are not being marked as invalid!

In pyuw_sniffer where the pending frames are created, we make use of a
scoped_restore to invalidate the pending frame objects.  However, this
only restores the pending_frame_object::frame_info field to its
previous value -- and it turns out we never actually give this field
an initial value, it's left undefined.

So, when the scoped_restore (called invalidate_frame) performs its
cleanup, it actually restores the frame_info field to an undefined
value.  If this undefined value is not nullptr then any future
accesses to the PendingFrame object result in undefined behaviour and
most likely, a crash.

As part of this commit I now initialize the frame_info field, which
ensures all the new tests now pass.

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
3e8154778b Put pretty-printers to_string output in varobj result
PR mi/11335 points out that an MI varobj will not display the result
of a pretty-printer's "to_string" method.  Instead, it always shows
"{...}".

This does not seem very useful, and there have been multiple
complaints about it over the years.  This patch changes varobj to emit
this string when possible, and updates the test suite.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=11335
2023-03-28 12:17:58 -06:00
Tom Tromey
72a8f76323 Change symbol::line to unsigned int
A user here at AdaCore noticed that, when debugging a certain program,
a stack frame reported line 34358, where it should have been line
99894.

After debugging a bit, I discovered:

(top) p (99894 & ~65536)
$60 = 34358

That line, symbol::line is too narrow.

This patch widens the member and changes all the uses that currently
use the narrower type.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-27 08:37:14 -06:00
Tom de Vries
f2259ae756 [gdb/testsuite] Handle attributes.h for remote host
Handle $srcdir/lib/attributes.h using lappend_include_dir.

Tested on x86_64-linux.
2023-03-18 10:16:30 +01:00
Tom de Vries
7fee66abd3 [gdb/testsuite] Fix gdb.python/tui-window-factory.exp for remote host
When running gdb.python/tui-window.exp with host board
local-remote-host-notty and target board native-gdbserver, I get:
...
FAIL: gdb.python/tui-window-factory.exp: msg_2: \
  check test_window box (box check: ul corner is l, not +)
...

The problem is that the result of Term::prepare_for_tui is not checked.

Fix this by adding the missing check.

Tested on x86_64-linux.
2023-03-13 17:20:09 +01:00
Tom de Vries
1cdf05cd2d [gdb/testsuite] Fix gdb.python/tui-window.exp for remote host
When running gdb.python/tui-window.exp with host board
local-remote-host-notty and target board native-gdbserver, I get:
...
UNSUPPORTED: gdb.python/tui-window.exp: TUI not supported
FAIL: gdb.python/tui-window.exp: test title
...

Fix this by adding the missing return after the unsupported.

Tested on x86_64-linux.
2023-03-13 17:20:09 +01:00
Bruno Larsen
1878b6b5f6 [gdb/obvious]: fix python formatting for test gdb.python/py-typeprint.py
python black formatter was complaining about the formatting of
gdb.python/py-typeprint.py, so this commit corrects it.
2023-03-13 16:34:41 +01:00
Bruno Larsen
83b755117d gdb/testsuite: add regression test for per-objfile typeprinters
PR python/17136 reported an unhandled exception when using typeprinters
only valid on some objfiles, rather than being a global typeprinter. The
fix was accepted without a regression test, and we've been carrying one
out-of-tree for a while but I think it's worth upstreaming. The code
itself was developed by Jan Kratochvil.

Co-Authored-By: Jan Kratochvil <jkratochvil@azul.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17136
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
2023-03-13 14:40:33 +01:00
Tom de Vries
7f3294a9b7 [gdb/testsuite] Fix gdb.python/py-completion.exp
With test-case gdb.python/py-completion.exp and target board
native-extended-gdbserver I get this warning:
...
(gdb) PASS: gdb.python/py-completion.exp: discard #2
completefilecommandcond $outputs/gdb.python/py-completion/py-completion-t^G\
  PASS: gdb.python/py-completion.exp: completefilecommandcond completion
Remote debugging from host ::1, port 53346^M
monitor exit^M
not implemented^M
(gdb) WARNING: Timed out waiting for EOF in server after monitor exit
...

Fix this by adding the missing "discard #3", such that we have instead:
...
(gdb) PASS: gdb.python/py-completion.exp: discard #2
completefilecommandcond $outputs/gdb.python/py-completion/py-completion-t^G\
  PASS: gdb.python/py-completion.exp: completefilecommandcond completion
 ^M
not implemented^M
(gdb) PASS: gdb.python/py-completion.exp: discard #3
Remote debugging from host ::1, port 36278^M
monitor exit^M
(gdb)
...

Tested on x86_64-linux.
2023-03-10 16:34:04 +01:00
Tom de Vries
254de2628f [gdb/testsuite] Fix gdb.python/py-cmd.exp
[ Using $pp as shorthand for the pagination prompt
"--Type <RET> for more, q to quit, c to continue without paging--". ]

The test-case gdb.python/py-cmd.exp passes, but the handling of the
test_multiline command output looks a bit odd:
...
(gdb) test_multiline
test_multiline output
  ...
test_multiline output
$ppPASS: gdb.python/py-cmd.exp: verify pagination from test_multiline
q
test_multiline
Quit
(gdb) test_multiline
test_multiline output
  ...
test_multiline output
$ppPASS: gdb.python/py-cmd.exp: verify pagination from test_multiline: q
...

What happens is:
- a test_multiline command is issued
- some output is printed, followed by a pagination prompt
- the test-case concludes that pagination occurred, and produces a PASS
- "q\n" is replied to the pagination prompt
- without waiting for response to the "q\n", another test_multiline command is
  issued
- in response to the "q\n" we get "Quit\n(gdb) "
- some output is printed, followed by a pagination prompt
- the test-case concludes that there's a valid response to the "q\n", and
  produces a PASS, consuming the second pagination prompt, but without a reply.

My conclusion is that the second test_multiline command is unintentional, so fix
this by removing it.

Without it, we have the more straightforward:
...
(gdb) test_multiline
test_multiline output
  ...
test_multiline output
$ppPASS: gdb.python/py-cmd.exp: verify pagination from test_multiline
q
Quit
(gdb) PASS: gdb.python/py-cmd.exp: verify pagination from test_multiline: q
...

This also fixes the following warning with target board native-gdbserver:
...
WARNING: Timed out waiting for EOF in server after monitor exit
...

Tested on x86_64-linux.
2023-03-10 16:34:04 +01:00
Tom de Vries
ddc003b7de [gdb/testsuite] Fix py-autoloaded-pretty-printers-in-newobjfile-event.exp for remote target
With test-case gdb.python/py-autoloaded-pretty-printers-in-newobjfile-event.exp
and target board remote-gdbserver-on-localhost, I run into:
...
FAIL: $exp: runto: run to main
...

I can easily fix this using "gdb_load_shlib $binfile_lib", but then run into:
...
(gdb) print all_good^M
$1 = false^M
(gdb) FAIL: $exp: print all_good
info pretty-printer^M
...

Sysroot is set to "target:", so gdb downloads the shared library from the target
(Using $so as shorthand for
libpy-autoloaded-pretty-printers-in-newobjfile-event.so):
...
Reading /home/remote-target/$so from remote target...^M
...
and internally refers to it as "target:/home/remote-target/$so".

In load_auto_scripts_for_objfile, gdb gives up trying to auto-load scripts
for $so once it checks for is_target_filename.

Fix this by declaring auto-load unsupported if sysroot starts with "target:".

Tested on x86_64-linux.
2023-03-10 16:34:04 +01:00
Tom de Vries
69b956fbe9 [gdb/testsuite] Fix gdb.python/py-event-load.exp for remote target
Fix test-case gdb.python/py-event-load.exp for target board
remote-gdbserver-on-localhost using gdb_download_shlib.

Tested on x86_64-linux.
2023-03-10 16:34:04 +01:00
Tom de Vries
2c29b1ed19 [gdb/testsuite] Add another xfail case in gdb.python/py-record-btrace.exp
I ran into:
...
(gdb) PASS: gdb.python/py-record-btrace.exp: function call: \
  python print(c.prev)
python print(c == c.next.prev)^M
Traceback (most recent call last):^M
  File "<string>", line 1, in <module>^M
AttributeError: 'NoneType' object has no attribute 'prev'^M
Error while executing Python code.^M
(gdb) FAIL: gdb.python/py-record-btrace.exp: function call: \
  python print(c == c.next.prev)
...
due to having only 4 insn instead of 100:
...
python print(len(insn))^M
4^M
...

This could be caused by the same hw bug as we already have an xfail for, so
expand the xfail matching.

Tested on x86_64-linux.

PR testsuite/30185
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30185

Approved-By: Markus T. Metzger <markus.t.metzger@intel.com>
2023-03-01 13:44:04 +01:00
Tom de Vries
0c132dac7f [gdb/testsuite] Fix gdb.python/py-breakpoint.exp timeouts
On powerpc64le-linux, I run into two timeouts:
...
FAIL: gdb.python/py-breakpoint.exp: test_watchpoints: \
  Test watchpoint write (timeout)
FAIL: gdb.python/py-breakpoint.exp: test_bkpt_internal: \
  Test watchpoint write (timeout)
...

In this case, hw watchpoints are not supported, and using sw watchpoints
is slow.

Most of the time is spent in handling a try-catch, which triggers a malloc.  I
think this bit is more relevant for the "catch throw" part of the test-case,
so fix the timeouts by setting the watchpoints after the try-catch.

Tested on x86_64-linux and powerpc64le-linux.
2023-02-28 15:50:23 +01:00