Commit Graph

3162 Commits

Author SHA1 Message Date
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
Tom Tromey
3f33695b64 Update documentation for Python Frame.older and Frame.newer
I noticed that Frame.older and Frame.newer don't document that they
return None at the ends of the stack.  This patch updates the
documentation, and also fixes a somewhat related typo in a comment
that I noticed while digging into this.

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-05-19 10:47:09 -06:00
Tom Tromey
c96452ad16 Use lower-case in @sc in the documentation
Eli pointed out that @sc only produces small caps for lower case
letters in its argument, so it's weird to write it using upper-case
letters.  This patch fixes the instances I found.

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-05-18 13:28:47 -06: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
Andrew Burgess
773e2d29c3 gdb/doc: improve Python Disassembler API documentation
Some small improvements to the Python Disassembler API documentation:

  * Be consistent about using the package scope in the @deftp lines,

  * Rework the description of the DisassemblerResult class to include
    mention of builtin_disassemble.
2023-05-12 18:24:24 +01:00
Tom Tromey
8b331fa16b Add "scheduler-locking" to documentation index
I noticed that "scheduler-locking" does not appear in the index of the
gdb manual.  This patch corrects this oversight.
2023-05-11 09:27:53 -06:00
Tom de Vries
2093c2af3c [gdb/tui] Fix tui compact-source
Consider a hello.c, with less than 10 lines:
...
$ wc -l hello.c
8 hello.c
...
and compiled with -g into an a.out.

With compact-source off:
...
$ gdb -q a.out \
    -ex "set tui border-kind ascii" \
    -ex "maint set tui-left-margin-verbose on" \
    -ex "set tui compact-source off" \
    -ex "tui enable"
...
we get:
...
+-./data/hello.c-----------------------+
|___000005_{                           |
|___000006_  printf ("hello\n");       |
|___000007_  return 0;                 |
|___000008_}                           |
|___000009_                            |
|___000010_                            |
|___000011_                            |
...
but with compact-source on:
...
+-./data/hello.c-----------------------+
|___5{                                 |
|___6  printf ("hello\n");             |
|___7  return 0;                       |
|___8}                                 |
|___9                                  |
|___1                                  |
|___1                                  |
...

There are a couple of problems with compact-source.

First of all the documentation mentions:
...
The default display uses more space for line numbers and starts the
source text at the next tab stop; the compact display uses only as
much space as is needed for the line numbers in the current file, and
only a single space to separate the line numbers from the source.
...

The bit about the default display and the next tab stop looks incorrect.  The
source doesn't start at a tab stop, instead it uses a single space to separate
the line numbers from the source.

Then the documentation mentions that there's single space in the compact
display, but evidently that's missing.

Then there's the fact that the line numbers "10" and "11" are both abbreviated
to "1" in the compact case.

The abbreviation is due to allocating space for <lines in source>, which is
8 for this example, and takes a single digit.  The line numbers though
continue past the end of the file, so fix this by allocating space for
max (<lines in source>, <last line in window>), which in this example takes 2
digits.

The missing space is due to some confusion about what the "1" here in
tui_source_window::set_contents represent:
...
      double l = log10 ((double) offsets->size ());
      m_digits = 1 + (int) l;
...

It could be the trailing space that's mentioned in tui-source.h:
...
  /* How many digits to use when formatting the line number.  This
     includes the trailing space.  */
  int m_digits;
...

Then again, it could be part of the calculation for the number of digits
needed for printing.  With this minimal example:
...
int main () {
  for (int i = 8; i <= 11; ++i) {
    double l = log10 ((double) i);
    printf ("%d %d\n", i, (int)l);
  }
  return 0;
}
...
we get:
...
$ ./a.out
8 0
9 0
10 1
11 1
...
which shows that the number of digits needed for printing i is
"1 + (int)log10 ((double) i)".

Fix this by introducing named variables needed_digits and trailing_space, each
adding 1.

With the fixes, we get for compact-source on:
...
+-./data/hello.c-----------------------+
|___05_{                               |
|___06_  printf ("hello\n");           |
|___07_  return 0;                     |
|___08_}                               |
|___09_                                |
|___10_                                |
|___11_                                |
|...

Also fix the documentation and help text to actually match effect of
compact-source.

Tested on x86_64-linux.
2023-05-10 06:56:08 +02:00
Gareth Rees
51f8dafba8 Don't treat references to compound values as "simple".
SUMMARY

The '--simple-values' argument to '-stack-list-arguments' and similar
GDB/MI commands does not take reference types into account, so that
references to arbitrarily large structures are considered "simple" and
printed. This means that the '--simple-values' argument cannot be used
by IDEs when tracing the stack due to the time taken to print large
structures passed by reference.

DETAILS

Various GDB/MI commands ('-stack-list-arguments', '-stack-list-locals',
'-stack-list-variables' and so on) take a PRINT-VALUES argument which
may be '--no-values' (0), '--all-values' (1) or '--simple-values' (2).
In the '--simple-values' case, the command is supposed to print the
name, type, and value of variables with simple types, and print only the
name and type of variables with compound types.

The '--simple-values' argument ought to be suitable for IDEs that need
to update their user interface with the program's call stack every time
the program stops. However, it does not take C++ reference types into
account, and this makes the argument unsuitable for this purpose.

For example, consider the following C++ program:

    struct s {
        int v[10];
    };

    int
    sum(const struct s &s)
    {
        int total = 0;
        for (int i = 0; i < 10; ++i) total += s.v[i];
        return total;
    }

    int
    main(void)
    {
        struct s s = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };
        return sum(s);
    }

If we start GDB in MI mode and continue to 'sum', the behaviour of
'-stack-list-arguments' is as follows:

    (gdb)
    -stack-list-arguments --simple-values
    ^done,stack-args=[frame={level="0",args=[{name="s",type="const s &",value="@0x7fffffffe310: {v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}"}]},frame={level="1",args=[]}]

Note that the value of the argument 's' was printed, even though 's' is
a reference to a structure, which is not a simple value.

See https://github.com/microsoft/MIEngine/pull/673 for a case where this
behaviour caused Microsoft to avoid the use of '--simple-values' in
their MIEngine debug adapter, because it caused Visual Studio Code to
take too long to refresh the call stack in the user interface.

SOLUTIONS

There are two ways we could fix this problem, depending on whether we
consider the current behaviour to be a bug.

1. If the current behaviour is a bug, then we can update the behaviour
   of '--simple-values' so that it takes reference types into account:
   that is, a value is simple if it is neither an array, struct, or
   union, nor a reference to an array, struct or union.

   In this case we must add a feature to the '-list-features' command so
   that IDEs can detect that it is safe to use the '--simple-values'
   argument when refreshing the call stack.

2. If the current behaviour is not a bug, then we can add a new option
   for the PRINT-VALUES argument, for example, '--scalar-values' (3),
   that would be suitable for use by IDEs.

   In this case we must add a feature to the '-list-features' command
   so that IDEs can detect that the '--scalar-values' argument is
   available for use when refreshing the call stack.

PATCH

This patch implements solution (1) as I think the current behaviour of
not printing structures, but printing references to structures, is
contrary to reasonable expectation.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29554
2023-05-04 08:58:18 -06:00
Tom Tromey
a01e847fc8 Document DAP 'launch' parameter
The Debugger Adapter Protocol defines a "launch" request but leaves
the parameters up to the implementation:

    Since launching is debugger/runtime specific, the arguments for
    this request are not part of this specification.

This patch adds some documentation for the parameter GDB currently
defines.  Note that I plan to add more parameters here, and perhaps
there will be other extensions in time as well.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-05-01 14:19:47 -06:00
Andrew Burgess
00cdd79a5d gdb/mi: check thread exists when creating thread-specific b/p
I noticed the following behaviour:

  $ gdb -q -i=mi /tmp/hello.x
  =thread-group-added,id="i1"
  =cmd-param-changed,param="print pretty",value="on"
  ~"Reading symbols from /tmp/hello.x...\n"
  (gdb)
  -break-insert -p 99 main
  ^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0000000000401198",func="main",file="/tmp/hello.c",fullname="/tmp/hello.c",line="18",thread-groups=["i1"],thread="99",times="0",original-location="main"}
  (gdb)
  info breakpoints
  &"info breakpoints\n"
  ~"Num     Type           Disp Enb Address            What\n"
  ~"1       breakpoint     keep y   0x0000000000401198 in main at /tmp/hello.c:18\n"
  &"../../src/gdb/thread.c:1434: internal-error: print_thread_id: Assertion `thr != nullptr' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable."
  &"\n"
  &"----- Backtrace -----\n"
  &"Backtrace unavailable\n"
  &"---------------------\n"
  &"\nThis is a bug, please report it."
  &"  For instructions, see:\n"
  &"<https://www.gnu.org/software/gdb/bugs/>.\n\n"
  Aborted (core dumped)

What we see here is that when using the MI a user can create
thread-specific breakpoints for non-existent threads.  Then if we try
to use the CLI 'info breakpoints' command GDB throws an assertion.
The assert is a result of the print_thread_id call when trying to
build the 'stop only in thread xx.yy' line; print_thread_id requires a
valid thread_info pointer, which we can't have for a non-existent
thread.

In contrast, when using the CLI we see this behaviour:

  $ gdb -q /tmp/hello.x
  Reading symbols from /tmp/hello.x...
  (gdb) break main thread 99
  Unknown thread 99.
  (gdb)

The CLI doesn't allow a breakpoint to be created for a non-existent
thread.  So the 'info breakpoints' command is always fine.

Interestingly, the MI -break-info command doesn't crash, this is
because the MI uses global thread-ids, and so never calls
print_thread_id.  However, GDB does support using CLI and MI in
parallel, so we need to solve this problem.

One option would be to change the CLI behaviour to allow printing
breakpoints for non-existent threads.  This would preserve the current
MI behaviour.

The other option is to pull the MI into line with the CLI and prevent
breakpoints being created for non-existent threads.  This is good for
consistency, but is a breaking change for the MI.

In the end I figured that it was probably better to retain the
consistent CLI behaviour, and just made the MI reject requests to
place a breakpoint on a non-existent thread.  The only test we had
that depended on the old behaviour was
gdb.mi/mi-thread-specific-bp.exp, which was added by me in commit:

  commit 2fd9a436c8
  Date:   Fri Feb 17 10:48:06 2023 +0000

      gdb: don't duplicate 'thread' field in MI breakpoint output

I certainly didn't intend for this test to rely on this feature of the
MI, so I propose to update this test to only create breakpoints for
threads that exist.

Actually, I've added a new test that checks the MI rejects creating a
breakpoint for a non-existent thread, and I've also extended the test
to run with the separate MI/CLI UIs, and then tested 'info
breakpoints' to ensure this command doesn't crash.

I've extended the documentation of the `-p` flag to explain the
constraints better.

I have also added a NEWS entry just in case someone runs into this
issue, at least then they'll know this change in behaviour was
intentional.

One thing that I did wonder about while writing this patch, is whether
we should treat requests like this, on both the MI and CLI, as another
form of pending breakpoint, something like:

  (gdb) break foo thread 9
  Thread 9 does not exist.
  Make breakpoint pending on future thread creation? (y or [n]) y
  Breakpoint 1 (foo thread 9) pending.
  (gdb) info breakpoints
  Num     Type           Disp Enb Address    What
  1       breakpoint     keep y   <PENDING>  foo thread 9

Don't know if folk think that would be a useful idea or not?  Either
way, I think that would be a separate patch from this one.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-04-29 00:15:42 +01:00
Tom Tromey
ebb83b77a7 Remove @var from @defun in Python documentation
Eli pointed out that @var isn't needed in @defun in Texinfo.  This
patch removes the cases I found in python.texi.  I also renamed some
variables in one spot, because "-" isn't valid in a Python variable
name.
2023-04-28 10:51:58 -06:00
Eli Zaretskii
7408b951b8 Fix a typo in gdb.texinfo. 2023-04-28 18:36:30 +03:00
Andrew Burgess
0d42948f0c gdb/doc: extend the documentation of the jump command
This commit addresses PR gdb/7946.  While checking for bugs relating
to the jump command I noticed a long standing bug that points out a
deficiency with GDB's documentation of the jump command.

The bug points out that 'jump 0x...' is not always the same as 'set
$pc = 0x...' and then 'continue'.  Writing directly to the $pc
register does not update any auxiliary state, e.g. $npc on SPARC,
while using 'jump' does.

It felt like this would be an easy issue to address by adding a
paragraph to the docs, so I took a stab at writing something suitable.

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

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-04-27 13:59:30 +01:00
Tankut Baris Aktemur
c6537074be gdb, doc: add index entry for the $_inferior_thread_count convenience var
Add a marker in the documentation for indexing the $_inferior_thread_count
variable.

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-04-27 14:44:16 +02:00
Tom de Vries
f1531d0461 [gdb/cli] Add maint info screen
While working on PRs tui/30337 and cli/30346 I came across various notions of
width in gdb, as reported by gdb, readline, curses and the environment
variables.

As for gdb, readline and the environment variables, the way things work
is:
- Gdb asks readline to detect screen size,
- readline sets the actual screen size in the environment variables
  COLUMNS and LINES,
- readline reports back a screen size to gdb, which may have one column
  less than the actual screen size, to deal with lack of auto-wrap.
  This becomes gdb's notion of screen size (in other words the point where
  we can expect the gdb command line to wrap),
- Gdb then explicitly sets readline's screen size, which readline itself may
  adjust to deal with lack of auto-wrap.  This becomes readlines notion
  of screen size (well, internally the unadjusted one, but it'll report back
  the adjusted one).

Add a command "maint info screen" that prints these notions, both for width
and height.

For TERM=xterm we have:
...
$ TERM=xterm gdb -ex "maint info screen"
Number of characters gdb thinks are in a line is 118.
Number of characters readline reports are in a line is 118.
Number of characters curses thinks are in a line is 118.
Number of characters environment thinks are in a line is 118 (COLUMNS).
Number of lines gdb thinks are in a page is 27.
Number of lines readline reports are in a page is 27.
Number of lines curses thinks are in a page is 27.
Number of lines environment thinks are in a page is 27 (LINES).
...

And for TERM=ansi:
...
$ TERM=ansi gdb -ex "maint info screen"
Number of characters gdb thinks are in a line is 117.
Number of characters readline reports are in a line is 116.
Number of characters curses thinks are in a line is 118.
Number of characters environment thinks are in a line is 118 (COLUMNS).
Number of lines gdb thinks are in a page is 27.
Number of lines readline reports are in a page is 27.
Number of lines curses thinks are in a page is 27.
Number of lines environment thinks are in a page is 27 (LINES).
...

[ The fact that we have "characters readline reports are in a line is 116" is
is due to gdb making readline adjust twice for the lack of auto-wrap, this is
PR cli/30346.

Likewise we can detect tui/30337 by doing a resize in TUI mode and doing
"maint info screen":
...
Number of characters characters curses thinks are in a line is 110.
Number of characters environment thinks are in a line is 111 (COLUMNS). ]

And for TERM=ansi, with width and heigth set to 0:
...
Number of characters gdb thinks are in a line is 4294967295 (unlimited).
Number of characters readline reports are in a line is 32766 (unlimited - 1).
Number of characters curses thinks are in a line is 118.
Number of characters environment thinks are in a line is 118 (COLUMNS).
Number of lines gdb thinks are in a page is 4294967295 (unlimited).
Number of lines readline reports are in a page is 32767 (unlimited).
Number of lines curses thinks are in a page is 27.
Number of lines environment thinks are in a page is 27 (LINES).
...

[ Note that when doing a resize by say maximizing or de-maximizing a terminal,
all reported values are updated, except for curses when not in TUI mode.

Maybe that means there's a bug.  If not, then maybe we should not print
the curses lines unless in TUI mode, or annotate those lines such that it's
clear that the values may be not up-to-date. ]

I'd like to use this command in the regression test for PR cli/30346.

Tested on x86_64-linux.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-04-21 17:12:23 +02:00
Luis Machado
acdf60711d pauth: Create new feature string for pauth to prevent crashing older gdb's
Older gdb's (9, 10, 11 and 12) have a bug that causes them to crash whenever
a target reports the pauth feature string in the target description and also
provide additional register outside of gdb's known and expected feature
strings.

This was fixed in gdb 13 onwards, but that means we're stuck with gdb's out
there that will crash on connection to the above targets.

QEMU has postponed inclusion of the pauth feature string in version 8, and
instead we agreed to use a new feature name to prevent crashing those older
gdb's.

Initially there was a plan to backport a trivial fix all the way to gdb 9, but
given QEMU's choice, this is no longer needed.

This new feature string is org.gnu.gdb.aarch64.pauth_v2, and should be used
by all targets going forward, except native linux gdb and gdbserver, for
backwards compatibility with older gdb's/gdbserver's.

gdb/gdbserver will still emit the old feature string for Linux since it doesn't
report additional system registers and thus doesn't cause a crash of older
gdb's. We can revisit this in the future once the problematic gdb's are likely
no longer in use.

I've added some documentation to explain the situation.
2023-04-14 13:44:11 +01:00
Tom de Vries
58b77c6af2 [gdb/tui] Add maint set/show tui-left-margin-verbose
The TUI has two types of windows derived from tui_source_window_base:
- tui_source_window (the source window), and
- tui_disasm_window (the disassembly window).

The two windows share a common concept: the left margin.

With a hello world a.out, we can see the source window:
...
┌─/home/vries/hello.c───────────────────────────────────────┐
│        5  {                                               │
│B+>     6    printf ("hello\n");                           │
│        7    return 0;                                     │
│        8  }                                               │
│        9                                                  │
│
...
where the left margin is the part holding "B+>" and the line number, and the
disassembly window:
...
┌───────────────────────────────────────────────────────────┐
│    0x555555555149 <main>           endbr64                │
│    0x55555555514d <main+4>         push   %rbp            │
│    0x55555555514e <main+5>         mov    %rsp,%rbp       │
│B+> 0x555555555151 <main+8>         lea    0xeac(%rip),%rax│
│    0x555555555158 <main+15>        mov    %rax,%rdi       │
...
where the left margin is just the bit holding "B+>".

Because the left margin contains some spaces, it's not clear where it starts
and ends, making it harder to observe problems related to it.

Add a new maintenance command "maint set tui-left-margin-verbose", that when
set to on replaces the spaces in the left margin with either '_' or '0',
giving us this for the source window:
...
┌─/home/vries/hello.c───────────────────────────────────────┐
│___000005__{                                               │
│B+>000006__  printf ("hello\n");                           │
│___000007__  return 0;                                     │
│___000008__}                                               │
...
and this for the disassembly window:
...
┌───────────────────────────────────────────────────────────┐
│___ 0x555555555149 <main>           endbr64                │
│___ 0x55555555514d <main+4>         push   %rbp            │
│___ 0x55555555514e <main+5>         mov    %rsp,%rbp       │
│B+> 0x555555555151 <main+8>         lea    0xeac(%rip),%rax│
│___ 0x555555555158 <main+15>        mov    %rax,%rdi       │
...

Note the space between "B+>" and 0x555555555151.  The space shows that a bit
of the left margin is not written, a problem reported as PR tui/30325.

Specifically, PR tui/30325 is about the fact that the '[' character from the
string "[ No Assembly Available ]" ends up in that same spot:
...
│B+>[0x555555555151 <main+8>         lea    0xeac(%rip),%rax│
...
which only happens for certain window widths.

The new command allows us to spot the problem with any window width.

Likewise, when we revert the fix from commit 1b6d4bb223 ("Redraw both spaces
between line numbers and source code"), we have:
...
┌─/home/vries/hello.c───────────────────────────────────────┐
│___000005_ {                                               │
│B+>000006_   printf ("hello\n");                           │
│___000007_   return 0;                                     │
│___000008_ }                                               │
...
showing a similar problem at the space between '_' and '{'.

Tested on x86_64-linux.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
2023-04-13 00:18:12 +02:00
Nils-Christian Kempke
d8ca1d2fc5 gdb, doc: correct argument description for info connections/inferiors
It said for 'info inferiors' and 'info connections' that the argument
could be 'a space separated list of inferior numbers' which is correct
but incomplete.  In fact the arguments can be any space separated
combination of numbers and (ascending) ranges.

The beginning of the section now describes the ID list as a new keyword.

Co-Authored-By: Christina Schimpe <christina.schimpe@intel.com>
2023-04-11 18:45:35 +02:00
Philippe Blain
61a8ffdc04 Fix typos in previous commit of gdb.texinfo.
* gdb/doc/gdb.texinfo (Requirements): Fix typos.
2023-04-08 19:45:17 +03: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
Eli Zaretskii
3401f947d8 Improve documentation of GDB build requirements and options
MPFR is now mandatory, so its previous description in Requirements
was inappropriate and out of place.  In addition, the description
of how to go about specifying 'configure' time options for
building with libraries was highly repetitive.  Some of the text
was also outdated and used wrong markup.

Original patch and suggestions from Philippe Blain
<levraiphilippeblain@gmail.com>.

ChangeLog:
2023-04-05  Eli Zaretskii  <eliz@gnu.org>

	* gdb/doc/gdb.texinfo (Requirements, Configure Options): Update and
	rearrange; improve and fix markup.
2023-04-05 16:21:31 +03:00
Tankut Baris Aktemur
59fa90bce5 gdb, doc: add the missing '-gid' option to 'info threads'
The 'info threads' command does not show the '-gid' option
in the syntax.  Add the option.  The flag is already explained
in the command description and used in the examples.

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-04-05 12:10:00 +02:00
Richard Bunt
03d83cd5f5 GDB: Add `info main' command
Allow consumers of GDB to extract the name of the main method.  This is
most useful for Fortran programs which have a variable main method.

Used by both MAP and DDT e.g. it is used to detect the presence of debug
information.

Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
2023-03-31 15:31:40 +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
Nils-Christian Kempke
f8c88b6231 doc: fix informations typo in gdb.texinfo
Co-Authored-By: Christina Schimpe <christina.schimpe@intel.com>
2023-03-29 14:21:07 +02: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
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
eef174f6a9 gdb/doc: extended documentation for inferior function calls
I noticed that the documentation for inferior function calls doesn't
say much about what happens if/when an inferior function call is
interrupted, i.e. it doesn't describe what the dummy frame looks like
on the stack, or how GDB behaves when the inferior is continued and
reaches the dummy frame.

This commit aims to add some of this missing information.
2023-03-16 17:14:21 +00: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
Luis Machado
d7001b29e9 aarch64: Expand documentation of XML features
Similar to the arm target documentation situation, the documentation of the
XML features for AArch64 targets is rather brief.  I have received the same
feedback that what gdb carries in the documentation is quite unclear from the
perspective of what debugging servers should define in the XML features, how and
what the outcome is in gdb.

This patch attempts to clarify a bit more what all the possible features are.
2023-03-13 11:30:18 +00:00
Luis Machado
e0994165d1 arm: Expand documentation of XML features
The documentation of the XML features for Arm targets is very brief.  I have
received feedback saying it is quite unclear from the perspective of the
debugging servers what should be defined in the XML features, how and
what the outcome is in gdb.

This patch attempts to clarify a bit more what all the possible features are.
2023-03-13 11:30:12 +00:00
Tom Tromey
f0c3dcc1ca Ensure index cache entry written in test
Now that index cache files are written in the background, one test in
index-cache.exp is racy -- it assumes that the cache file will have
been written during startup.

This patch fixes the problem by introducing a new maintenance command
to wait for all pending writes to the index cache.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-03-07 07:58:30 -07:00
Tom de Vries
0d5adb56c8 [gdb/symtab] Add set/show always-read-ctf on/off
[ This is a simplified rewrite of an earlier submission "[RFC][gdb/symtab] Add
maint set symbol-read-order", submitted here (
https://sourceware.org/pipermail/gdb-patches/2022-September/192044.html
). ]

With the test-case included in this patch, we run into:
...
(gdb) file dwarf2-and-ctf
(gdb) print var_ctf^M
'var_ctf' has unknown type; cast it to its declared type^M
...

The problem is that the executable contains both ctf and dwarf2, so the ctf
info (which contains the type information about var_ctf) is ignored.

GDB has support for handling multiple debug formats, but the common use case
for ctf is to be used when dwarf2 is not present, and gdb reflects that,
assuming that by reading ctf in addition there won't be any extra information,
so it's not worth the additional cycles and memory.

Add a new command "set/show always-read-ctf on/off", that when on forces
unconditional reading of ctf, allowing us to do:
...
(gdb) set always-read-ctf on
(gdb) file dwarf2-and-ctf
(gdb) print var_ctf^M
$2 = 2^M
...

The setting is off by default, preserving current behaviour.

A bit of background on the relevance of reading order: the formats have a
priority relationship between them, where reading earlier means lower
priority.  By reading the format with the most detail last, we ensure it has
the highest priority, which makes sure that in case there is overlapping info,
the most detailed info is found.  This explains the current reading order of
mdebug, stabs and dwarf2.

Add the unconditional reading of ctf before dwarf2, because it's less detailed
than dwarf2.  The conditional reading of ctf is still done after the attempt to
read dwarf2, necessarily so because we only know whether there's dwarf2 after
we've tried to read it.

The new command allow us to replace uses of -Wl,--strip-debug added in commit
908a926ec4 ("[gdb/testsuite] Fix ctf test-cases on openSUSE Tumbleweed") by
uses of "set always-read-ctf on", but I've left that for another commit.

Tested on x86_64-linux.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-02 10:56:40 +01:00
Palmer Dabbelt
ee65c8f578
gdb/doc: The RISC-V vector registers didn't change
When we merged the GDB vector register support we did it a bit early,
just eating the risk in the very unlikely case that the vector register
names changed.  They didn't, so we can now remove the caveat in the docs
that they might.
2023-02-23 13:51:58 -08:00
Andrew Burgess
a5b6347b66 gdb/doc: Consistency fixes for GDB/MI documentation
I noticed two inconsistencies in the GDB/MI documentation, which this
commit addresses:

  1. Each MI command is introduced like this:

     @subheading The @code{-command-name} Command

     Except for a few of the tracing command, which just use:

     @subheading -command-name

     In this commit I've updated all these trace commands to use the
     more common format.

  2. Each MI command starts with a @subheading, and then the details
     of that command are split up using multiple @subsubheading
     entries.

     Except for a few commands which use @subheading for the top-level
     command, and then continue to use @subheading for each part of
     the command description.

     In this commit I've updated these to use @subsubheading where
     appropriate.
2023-02-20 14:18:03 +00:00
Tom Tromey
16b84b6599 Update the 'g' packet documentation
The 'g' packet documentation references a macro that no longer exists,
and it also claims that the 'x' response for an unavailable register
is limited to trace frames.  This patch updates the documentation to
reflect what I think is currently correct.

Co-Authored-By: Pedro Alves <pedro@palves.net>
Approved-By: Eli Zaretskii <eliz@gnu.org>
Change-Id: I863baa3b9293059cfd4aa3d534602cbcb693ba87
2023-02-16 17:08:48 +00:00
Andrew Burgess
42af03dafe gdb/doc: document MI -remove-inferior command
Back in 2010 the -remove-inferior command was added in commit
a79b8f6ea8, unfortunately this command was never added to the
documentation.

This commit addresses that oversight.

Approved-By: Eli Zaretskii <eliz@gnu.org>
2023-02-16 08:42:48 +00:00
Pedro Alves
91265a7d7c Add new "$_shell(CMD)" internal function
For testing a following patch, I wanted a way to send a SIGINT to GDB
from a breakpoint condition.  And I didn't want to do it from a Python
breakpoint or Python function, as I wanted to exercise non-Python code
paths.  So I thought I'd add a new $_shell internal function, that
runs a command under the shell, and returns the exit code.  With this,
I could write:

  (gdb) b foo if $_shell("kill -SIGINT $gdb_pid") != 0 || <other condition>

I think this is generally useful, hence I'm proposing it here.

Here's the new function in action:

 (gdb) p $_shell("true")
 $1 = 0
 (gdb) p $_shell("false")
 $2 = 1
 (gdb) p $_shell("echo hello")
 hello
 $3 = 0
 (gdb) p $_shell("foobar")
 bash: line 1: foobar: command not found
 $4 = 127
 (gdb) help function _shell
 $_shell - execute a shell command and returns the result.
 Usage: $_shell (command)
 Returns the command's exit code: zero on success, non-zero otherwise.
 (gdb)

NEWS and manual changes included.

Approved-By: Andrew Burgess <aburgess@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
Approved-By: Eli Zaretskii <eliz@gnu.org>
Change-Id: I7e36d451ee6b428cbf41fded415ae2d6b4efaa4e
2023-02-15 20:58:00 +00:00
Pedro Alves
71e28f788f gdb/manual: Move @findex entries
The manual currently has many cases like these:

 @item $_gdb_setting_str (@var{setting})
 @findex $_gdb_setting_str@r{, convenience function}

As suggested by Eli, move the @findex entries before @item so that the
index records the position of @item, and the Info reader places you
there when you use index-search.

I went over all @findex calls in the manual, and most are like the
above.  Most either appear before @item, or before @subheading, like:

 @subheading The @code{-break-after} Command
 @findex -break-after

I fixed all of them.

There are findex entries in annotate.texinfo,python.texi, and
stabs.texinfo as well, though those all look right to me already.

Tested by typing "i _isvoid" (@item case) and "i -complete"
(@subheading case) in an Info reader, and checking where those took
me.

Change-Id: Idb6903b0bb39ff03f93524628dcef86b5585c97e
Suggested-By: Eli Zaretskii <eliz@gnu.org>
2023-02-15 15:28:33 +00:00
Keith Seitz
14d0e6818a Fix doc build dependencies for --with-system-readline
PR build/30108 concerns building gdb documentation with
--with-sytem-readline.  If the in-tree readline directory is
missing, though, the docs will fail to build:

make[4]: Entering directory '/home/keiths/work/readline-doc-issue/linux/gdb/doc'
make[4]: *** No rule to make target '../../../src/gdb/doc/../../readline/readline/doc/rluser.texi', needed by 'gdb.info'.  Stop.

The listed file (and hsuser.texi) are conditionally included by gdb.texinfo.
When system readline is used, gdb/configure.ac will leave
READLINE_TEXI_INCFLAGS empty, causing doc/Makefile.in to output a line to
$BUILD/doc/GDBvn.texi with "@set SYSTEM_READLINE".  This surpresses the
inclusion of the missing files. They are not needed or used in this
scenario.

However, GDB_DOC_SOURCE_INCLUDES always lists these two files as dependencies,
thus provoking the build error whenever readline/ is missing.

This patch fixes this by creating (essentially) a conditional setting of the
dependencies to be included from readline.
2023-02-13 06:14:40 -08:00
Andrew Burgess
a0c0791577 GDB: Introduce limited array lengths while printing values
This commit introduces the idea of loading only part of an array in
order to print it, what I call "limited length" arrays.

The motivation behind this work is to make it possible to print slices
of very large arrays, where very large means bigger than
`max-value-size'.

Consider this GDB session with the current GDB:

  (gdb) set max-value-size 100
  (gdb) p large_1d_array
  value requires 400 bytes, which is more than max-value-size
  (gdb) p -elements 10 -- large_1d_array
  value requires 400 bytes, which is more than max-value-size

notice that the request to print 10 elements still fails, even though 10
elements should be less than the max-value-size.  With a patched version
of GDB:

  (gdb) p -elements 10 -- large_1d_array
  $1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...}

So now the print has succeeded.  It also has loaded `max-value-size'
worth of data into value history, so the recorded value can be accessed
consistently:

  (gdb) p -elements 10 -- $1
  $2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...}
  (gdb) p $1
  $3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
    20, 21, 22, 23, 24, <unavailable> <repeats 75 times>}
  (gdb)

Accesses with other languages work similarly, although for Ada only
C-style [] array element/dimension accesses use history.  For both Ada
and Fortran () array element/dimension accesses go straight to the
inferior, bypassing the value history just as with C pointers.

Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
2023-02-10 23:49:19 +00:00
Tom de Vries
be01687991 [gdb/cli] Add maint info frame-unwinders
Add a new command "maint info frame-unwinders":
...
(gdb) help maint info frame-unwinders
List the frame unwinders currently in effect, starting with the highest \
  priority.
...

Output for i386:
...
$ gdb -q -batch -ex "set arch i386" -ex "maint info frame-unwinders"
The target architecture is set to "i386".
dummy                   DUMMY_FRAME
dwarf2 tailcall         TAILCALL_FRAME
inline                  INLINE_FRAME
i386 epilogue           NORMAL_FRAME
dwarf2                  NORMAL_FRAME
dwarf2 signal           SIGTRAMP_FRAME
i386 stack tramp        NORMAL_FRAME
i386 sigtramp           SIGTRAMP_FRAME
i386 prologue           NORMAL_FRAME
...

Output for x86_64:
...
$ gdb -q -batch -ex "set arch i386:x86-64" -ex "maint info frame-unwinders"
The target architecture is set to "i386:x86-64".
dummy                   DUMMY_FRAME
dwarf2 tailcall         TAILCALL_FRAME
inline                  INLINE_FRAME
python                  NORMAL_FRAME
amd64 epilogue          NORMAL_FRAME
i386 epilogue           NORMAL_FRAME
dwarf2                  NORMAL_FRAME
dwarf2 signal           SIGTRAMP_FRAME
amd64 sigtramp          SIGTRAMP_FRAME
amd64 prologue          NORMAL_FRAME
i386 stack tramp        NORMAL_FRAME
i386 sigtramp           SIGTRAMP_FRAME
i386 prologue           NORMAL_FRAME
...

Tested on x86_64-linux.

Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2023-02-10 13:07:14 +01:00
Andrew Burgess
85df9457b7 gdb/doc: extend the documentation for the 'handle' command
The documentation for the 'handle' command does not cover all of the
features of the command, and in one case, is just wrong.

The user can specify 'all' as signal name, the documentation implies
that this will change the behaviour of all signals, in reality, this
changes all signals except SIGINT and SIGTRAP (the signals used by
GDB).  I've updated the docs to list this limitation.

The 'handle' command also allows the user to specify multiple signals
for a single command, e.g. 'handle SIGFPE SIGILL nostop pass print',
however the documentation doesn't describe this, so I've updated the
docs to describe this feature.
2023-02-06 14:56:42 +00:00
Simon Marchi
18b4d0736b gdb: initial support for ROCm platform (AMDGPU) debugging
This patch adds the foundation for GDB to be able to debug programs
offloaded to AMD GPUs using the AMD ROCm platform [1].  The latest
public release of the ROCm release at the time of writing is 5.4, so
this is what this patch targets.

The ROCm platform allows host programs to schedule bits of code for
execution on GPUs or similar accelerators.  The programs running on GPUs
are typically referred to as `kernels` (not related to operating system
kernels).

Programs offloaded with the AMD ROCm platform can be written in the HIP
language [2], OpenCL and OpenMP, but we're going to focus on HIP here.
The HIP language consists of a C++ Runtime API and kernel language.
Here's an example of a very simple HIP program:

    #include "hip/hip_runtime.h"
    #include <cassert>

    __global__ void
    do_an_addition (int a, int b, int *out)
    {
      *out = a + b;
    }

    int
    main ()
    {
      int *result_ptr, result;

      /* Allocate memory for the device to write the result to.  */
      hipError_t error = hipMalloc (&result_ptr, sizeof (int));
      assert (error == hipSuccess);

      /* Run `do_an_addition` on one workgroup containing one work item.  */
      do_an_addition<<<dim3(1), dim3(1), 0, 0>>> (1, 2, result_ptr);

      /* Copy result from device to host.  Note that this acts as a synchronization
         point, waiting for the kernel dispatch to complete.  */
      error = hipMemcpyDtoH (&result, result_ptr, sizeof (int));
      assert (error == hipSuccess);

      printf ("result is %d\n", result);
      assert (result == 3);

      return 0;
    }

This program can be compiled with:

    $ hipcc simple.cpp -g -O0 -o simple

... where `hipcc` is the HIP compiler, shipped with ROCm releases.  This
generates an ELF binary for the host architecture, containing another
ELF binary with the device code.  The ELF for the device can be
inspected with:

    $ roc-obj-ls simple
    1       host-x86_64-unknown-linux                                           file://simple#offset=8192&size=0
    1       hipv4-amdgcn-amd-amdhsa--gfx906                                     file://simple#offset=8192&size=34216
    $ roc-obj-extract 'file://simple#offset=8192&size=34216'
    $ file simple-offset8192-size34216.co
    simple-offset8192-size34216.co: ELF 64-bit LSB shared object, *unknown arch 0xe0* version 1, dynamically linked, with debug_info, not stripped
                                                                                 ^
                       amcgcn architecture that my `file` doesn't know about ----´

Running the program gives the very unimpressive result:

    $ ./simple
    result is 3

While running, this host program has copied the device program into the
GPU's memory and spawned an execution thread on it.  The goal of this
GDB port is to let the user debug host threads and these GPU threads
simultaneously.  Here's a sample session using a GDB with this patch
applied:

    $ ./gdb -q -nx --data-directory=data-directory ./simple
    Reading symbols from ./simple...
    (gdb) break do_an_addition
    Function "do_an_addition" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (do_an_addition) pending.
    (gdb) r
    Starting program: /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    [New Thread 0x7ffff5db7640 (LWP 1082911)]
    [New Thread 0x7ffef53ff640 (LWP 1082913)]
    [Thread 0x7ffef53ff640 (LWP 1082913) exited]
    [New Thread 0x7ffdecb53640 (LWP 1083185)]
    [New Thread 0x7ffff54bf640 (LWP 1083186)]
    [Thread 0x7ffdecb53640 (LWP 1083185) exited]
    [Switching to AMDGPU Wave 2:2:1:1 (0,0,0)/0]

    Thread 6 hit Breakpoint 1, do_an_addition (a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    24        *out = a + b;
    (gdb) info inferiors
      Num  Description       Connection           Executable
    * 1    process 1082907   1 (native)           /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple
    (gdb) info threads
      Id   Target Id                                    Frame
      1    Thread 0x7ffff5dc9240 (LWP 1082907) "simple" 0x00007ffff5e9410b in ?? () from /opt/rocm-5.4.0/lib/libhsa-runtime64.so.1
      2    Thread 0x7ffff5db7640 (LWP 1082911) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36
      5    Thread 0x7ffff54bf640 (LWP 1083186) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36
    * 6    AMDGPU Wave 2:2:1:1 (0,0,0)/0                do_an_addition (
        a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    (gdb) bt
    Python Exception <class 'gdb.error'>: Unhandled dwarf expression opcode 0xe1
    #0  do_an_addition (a=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        b=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>,
        out=<error reading variable: DWARF-2 expression error: `DW_OP_regx' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at simple.cpp:24
    (gdb) continue
    Continuing.
    result is 3
    warning: Temporarily disabling breakpoints for unloaded shared library "file:///home/smarchi/build/binutils-gdb-amdgpu/gdb/simple#offset=8192&size=67208"
    [Thread 0x7ffff54bf640 (LWP 1083186) exited]
    [Thread 0x7ffff5db7640 (LWP 1082911) exited]
    [Inferior 1 (process 1082907) exited normally]

One thing to notice is the host and GPU threads appearing under
the same inferior.  This is a design goal for us, as programmers tend to
think of the threads running on the GPU as part of the same program as
the host threads, so showing them in the same inferior in GDB seems
natural.  Also, the host and GPU threads share a global memory space,
which fits the inferior model.

Another thing to notice is the error messages when trying to read
variables or printing a backtrace.  This is expected for the moment,
since the AMD GPU compiler produces some DWARF that uses some
non-standard extensions:

  https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html

There were already some patches posted by Zoran Zaric earlier to make
GDB support these extensions:

  https://inbox.sourceware.org/gdb-patches/20211105113849.118800-1-zoran.zaric@amd.com/

We think it's better to get the basic support for AMD GPU in first,
which will then give a better justification for GDB to support these
extensions.

GPU threads are named `AMDGPU Wave`: a wave is essentially a hardware
thread using the SIMT (single-instruction, multiple-threads) [3]
execution model.

GDB uses the amd-dbgapi library [4], included in the ROCm platform, for
a few things related to AMD GPU threads debugging.  Different components
talk to the library, as show on the following diagram:

    +---------------------------+     +-------------+     +------------------+
    | GDB   | amd-dbgapi target | <-> |     AMD     |     |    Linux kernel  |
    |       +-------------------+     |   Debugger  |     +--------+         |
    |       | amdgcn gdbarch    | <-> |     API     | <=> | AMDGPU |         |
    |       +-------------------+     |             |     | driver |         |
    |       | solib-rocm        | <-> | (dbgapi.so) |     +--------+---------+
    +---------------------------+     +-------------+

  - The amd-dbgapi target is a target_ops implementation used to control
    execution of GPU threads.  While the debugging of host threads works
    by using the ptrace / wait Linux kernel interface (as usual), control
    of GPU threads is done through a special interface (dubbed `kfd`)
    exposed by the `amdgpu` Linux kernel module.  GDB doesn't interact
    directly with `kfd`, but instead goes through the amd-dbgapi library
    (AMD Debugger API on the diagram).

    Since it provides execution control, the amd-dbgapi target should
    normally be a process_stratum_target, not just a target_ops.  More
    on that later.

  - The amdgcn gdbarch (describing the hardware architecture of the GPU
    execution units) offloads some requests to the amd-dbgapi library,
    so that knowledge about the various architectures doesn't need to be
    duplicated and baked in GDB.  This is for example for things like
    the list of registers.

  - The solib-rocm component is an solib provider that fetches the list of
    code objects loaded on the device from the amd-dbgapi library, and
    makes GDB read their symbols.  This is very similar to other solib
    providers that handle shared libraries, except that here the shared
    libraries are the pieces of code loaded on the device.

Given that Linux host threads are managed by the linux-nat target, and
the GPU threads are managed by the amd-dbgapi target, having all threads
appear in the same inferior requires the two targets to be in that
inferior's target stack.  However, there can only be one
process_stratum_target in a given target stack, since there can be only
one target per slot.  To achieve it, we therefore resort the hack^W
solution of placing the amd-dbgapi target in the arch_stratum slot of
the target stack, on top of the linux-nat target.  Doing so allows the
amd-dbgapi target to intercept target calls and handle them if they
concern GPU threads, and offload to beneath otherwise.  See
amd_dbgapi_target::fetch_registers for a simple example:

    void
    amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno)
    {
      if (!ptid_is_gpu (regcache->ptid ()))
        {
          beneath ()->fetch_registers (regcache, regno);
          return;
        }

      // handle it
    }

ptids of GPU threads are crafted with the following pattern:

  (pid, 1, wave id)

Where pid is the inferior's pid and "wave id" is the wave handle handed
to us by the amd-dbgapi library (in practice, a monotonically
incrementing integer).  The idea is that on Linux systems, the
combination (pid != 1, lwp == 1) is not possible.  lwp == 1 would always
belong to the init process, which would also have pid == 1 (and it's
improbable for the init process to offload work to the GPU and much less
for the user to debug it).  We can therefore differentiate GPU and
non-GPU ptids this way.  See ptid_is_gpu for more details.

Note that we believe that this scheme could break down in the context of
containers, where the initial process executed in a container has pid 1
(in its own pid namespace).  For instance, if you were to execute a ROCm
program in a container, then spawn a GDB in that container and attach to
the process, it will likely not work.  This is a known limitation.  A
workaround for this is to have a dummy process (like a shell) fork and
execute the program of interest.

The amd-dbgapi target watches native inferiors, and "attaches" to them
using amd_dbgapi_process_attach, which gives it a notifier fd that is
registered in the event loop (see enable_amd_dbgapi).  Note that this
isn't the same "attach" as in PTRACE_ATTACH, but being ptrace-attached
is a precondition for amd_dbgapi_process_attach to work.  When the
debugged process enables the ROCm runtime, the amd-dbgapi target gets
notified through that fd, and pushes itself on the target stack of the
inferior.  The amd-dbgapi target is then able to intercept target_ops
calls.  If the debugged process disables the ROCm runtime, the
amd-dbgapi target unpushes itself from the target stack.

This way, the amd-dbgapi target's footprint stays minimal when debugging
a process that doesn't use the AMD ROCm platform, it does not intercept
target calls.

The amd-dbgapi library is found using pkg-config.  Since enabling
support for the amdgpu architecture (amdgpu-tdep.c) depends on the
amd-dbgapi library being present, we have the following logic for
the interaction with --target and --enable-targets:

 - if the user explicitly asks for amdgcn support with
   --target=amdgcn-*-* or --enable-targets=amdgcn-*-*, we probe for
   the amd-dbgapi and fail if not found

 - if the user uses --enable-targets=all, we probe for amd-dbgapi,
   enable amdgcn support if found, disable amdgcn support if not found

 - if the user uses --enable-targets=all and --with-amd-dbgapi=yes,
   we probe for amd-dbgapi, enable amdgcn if found and fail if not found

 - if the user uses --enable-targets=all and --with-amd-dbgapi=no,
   we do not probe for amd-dbgapi, disable amdgcn support

 - otherwise, amd-dbgapi is not probed for and support for amdgcn is not
   enabled

Finally, a simple test is included.  It only tests hitting a breakpoint
in device code and resuming execution, pretty much like the example
shown above.

[1] https://docs.amd.com/category/ROCm_v5.4
[2] https://docs.amd.com/bundle/HIP-Programming-Guide-v5.4
[3] https://en.wikipedia.org/wiki/Single_instruction,_multiple_threads
[4] https://docs.amd.com/bundle/ROCDebugger-API-Guide-v5.4

Change-Id: I591edca98b8927b1e49e4b0abe4e304765fed9ee
Co-Authored-By: Zoran Zaric <zoran.zaric@amd.com>
Co-Authored-By: Laurent Morichetti <laurent.morichetti@amd.com>
Co-Authored-By: Tony Tye <Tony.Tye@amd.com>
Co-Authored-By: Lancelot SIX <lancelot.six@amd.com>
Co-Authored-By: Pedro Alves <pedro@palves.net>
2023-02-02 10:02:34 -05:00
Christina Schimpe
fe4c3ca003 gdb: Add per-remote target variables for memory read and write config
This patch adds per-remote target variables for the configuration of
memory read- and write packet size.  It is a further change to commit
"gdb: Make global feature array a per-remote target array" to apply the
fixme notes described in commit 5b6d1e4 "Multi-target support".

The former global variables for that configuration are still available
to allow the command line configuration for all future remote
connections.  Similar to the command line configuration of the per-
remote target feature array, the commands

- set remotewritesize (deprecated)
- set remote memory-read-packet-size
- set remote memory-write-packet-size

will configure the current target (if available).  If no target is
available, the default configuration for future remote connections is
adapted.  The show command will display the current remote target's
packet size configuration.  If no remote target is selected, the default
configuration for future connections will be shown.

It is required to adapt the test gdb.base/remote.exp which is failing
for --target_board=native-extended-gdbserver.  With that board GDB
connects to gdbserver at gdb start time.  Due to this patch two loggings
"The target may not be able to.." are shown if the command 'set remote
memory-write-packet-size fixed' is executed while a target is connected
for the current inferior.  To fix this, the clean_restart command is
moved to a later time point of the test.  It is sufficient to be
connected to the server when "runto_main" is executed.  Now the
connection time is similar to a testrun with
--target_board=native-gdbserver.

To allow the user to distinguish between the packet-size configuration
for future remote connections and for the currently selected target, the
commands' loggings are adapted.
2023-01-30 12:45:31 +01:00