Age | Commit message (Collapse) | Author | Files | Lines |
|
If the download size is known, a progress bar is displayed along with
the percentage of completion and the total download size.
Downloading separate debug info for /lib/libxyz.so
[############ ] 25% (10.01 M)
If the download size is not known, a progress indicator is displayed
with a ticker ("###") that moves across the screen at a rate of 1 tick
every 0.5 seconds.
Downloading separate debug info for /lib/libxyz.so
[ ### ]
If the output stream is not a tty, batch mode is enabled, the screen is
too narrow or width has been set to 'unlimited', then only a static
description of the download is printed. No bar or ticker is displayed.
Downloading separate debug info for /lib/libxyz.so...
In any case, if the size of the download is known at the time the
description is printed then it will be included in the description.
Downloading 10.01 MB separate debug info for /lib/libxyz.so...
|
|
Fix some whitespace issues introduced with the frame_info_ptr patch.
Change-Id: I158d30d8108c97564276c647fc98283ff7b12163
|
|
Currently, every internal_error call must be passed __FILE__/__LINE__
explicitly, like:
internal_error (__FILE__, __LINE__, "foo %d", var);
The need to pass in explicit __FILE__/__LINE__ is there probably
because the function predates widespread and portable variadic macros
availability. We can use variadic macros nowadays, and in fact, we
already use them in several places, including the related
gdb_assert_not_reached.
So this patch renames the internal_error function to something else,
and then reimplements internal_error as a variadic macro that expands
__FILE__/__LINE__ itself.
The result is that we now should call internal_error like so:
internal_error ("foo %d", var);
Likewise for internal_warning.
The patch adjusts all calls sites. 99% of the adjustments were done
with a perl/sed script.
The non-mechanical changes are in gdbsupport/errors.h,
gdbsupport/gdb_assert.h, and gdb/gdbarch.py.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
|
|
Currently, despite having a smart pointer for frame_infos, GDB may
attempt to use an invalidated frame_info_ptr, which would cause internal
errors to happen. One such example has been documented as PR
python/28856, that happened when printing frame arguments calls an
inferior function.
To avoid failures, the smart wrapper was changed to also cache the frame
id, so the pointer can be reinflated later. For this to work, the
frame-id stuff had to be moved to their own .h file, which is included
by frame-info.h.
Frame_id caching is done explicitly using the prepare_reinflate method.
Caching is done manually so that only the pointers that need to be saved
will be, and reinflating has to be done manually using the reinflate
method because the get method and the -> operator must not change
the internals of the class. Finally, attempting to reinflate when the
pointer is being invalidated causes the following assertion errors:
check_ptrace_stopped_lwp_gone: assertion `lp->stopped` failed.
get_frame_pc: Assertion `frame->next != NULL` failed.
As for performance concerns, my personal testing with `time make
chec-perf GDB_PERFTEST_MODE=run` showed an actual reduction of around
10% of time running.
This commit also adds a testcase that exercises the python/28856 bug with
7 different triggers, run, continue, step, backtrace, finish, up and down.
Some of them can seem to be testing the same thing twice, but since this
test relies on stale pointers, there is always a chance that GDB got lucky
when testing, so better to test extra.
Regression tested on x86_64, using both gcc and clang.
Approved-by: Tom Tomey <tom@tromey.com>
|
|
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
|
|
This replaces frame_id_eq with operator== and operator!=. I wrote
this for a version of this series that I later abandoned; but since it
simplifies the code, I left this patch in.
Approved-by: Tom Tomey <tom@tromey.com>
|
|
After the previous few commit, gdbarch_register_name no longer returns
nullptr. This commit audits all the calls to gdbarch_register_name
and removes any code that checks the result against nullptr.
There should be no visible change after this commit.
|
|
Now that the disassembler has two different strategies for laying out
the opcode bytes of an instruction (see /r vs /b for the disassemble
command), I wanted to add support for this to the MI disassemble
command.
Currently the -data-disassemble command takes a single 'mode' value,
which currently has 6 different values (0 -> 5), 3 of these modes
relate to opcode display.
So, clearly I should just add an additional 3 modes to handle the new
opcode format, right?
No, I didn't think that was a great idea either.
So, I wonder, could I adjust the -data-disassemble command in a
backward compatible way, that would allow GDB to move away from using
the mode value altogether?
I think we can.
In this commit, I propose adding two new options to -data-disassemble,
these are:
--opcodes none|bytes|display
--source
Additionally, I will make the mode optional, and default to mode 0 if
no mode value is given. Mode 0 is the simplest, no source code, no
opcodes disassembly mode.
The two new options are only valid for mode 0, if they are used with
any other mode then an error is thrown.
The --opcodes option can add opcodes to the result, with 'bytes' being
equivalent to 'disassemble /b' and 'display' being 'disassemble /r'.
The --source option will enable the /s style source code display, this
is equivalent to modes 4 and 5. There is no way, using the new
command options to get the now deprecated /m style source code
display, that is mode 1 and 3.
My hope is that new users of the MI will not use the mode at all, and
instead will just use the new options to achieve the output they need.
Existing MI users can continue to use the mode, and will not need to
be updated to use the new options.
|
|
Just some simple int to bool conversion in mi_cmd_disassemble. There
should be no user visible changes after this commit.
|
|
This commit changes the format of 'disassemble /r' to match GNU
objdump. Specifically, GDB will now display the instruction bytes in
as 'objdump --wide --disassemble' does.
Here is an example for RISC-V before this patch:
(gdb) disassemble /r 0x0001018e,0x0001019e
Dump of assembler code from 0x1018e to 0x1019e:
0x0001018e <call_me+66>: 03 26 84 fe lw a2,-24(s0)
0x00010192 <call_me+70>: 83 25 c4 fe lw a1,-20(s0)
0x00010196 <call_me+74>: 61 65 lui a0,0x18
0x00010198 <call_me+76>: 13 05 85 6a addi a0,a0,1704
0x0001019c <call_me+80>: f1 22 jal 0x10368 <printf>
End of assembler dump.
And here's an example after this patch:
(gdb) disassemble /r 0x0001018e,0x0001019e
Dump of assembler code from 0x1018e to 0x1019e:
0x0001018e <call_me+66>: fe842603 lw a2,-24(s0)
0x00010192 <call_me+70>: fec42583 lw a1,-20(s0)
0x00010196 <call_me+74>: 6561 lui a0,0x18
0x00010198 <call_me+76>: 6a850513 addi a0,a0,1704
0x0001019c <call_me+80>: 22f1 jal 0x10368 <printf>
End of assembler dump.
There are two differences here. First, the instruction bytes after
the patch are grouped based on the size of the instruction, and are
byte-swapped to little-endian order.
Second, after the patch, GDB now uses the bytes-per-line hint from
libopcodes to add whitespace padding after the opcode bytes, this
means that in most cases the instructions are nicely aligned.
It is still possible for a very long instruction to intrude into the
disassembled text space. The next example is x86-64, before the
patch:
(gdb) disassemble /r main
Dump of assembler code for function main:
0x0000000000401106 <+0>: 55 push %rbp
0x0000000000401107 <+1>: 48 89 e5 mov %rsp,%rbp
0x000000000040110a <+4>: c7 87 d8 00 00 00 01 00 00 00 movl $0x1,0xd8(%rdi)
0x0000000000401114 <+14>: b8 00 00 00 00 mov $0x0,%eax
0x0000000000401119 <+19>: 5d pop %rbp
0x000000000040111a <+20>: c3 ret
End of assembler dump.
And after the patch:
(gdb) disassemble /r main
Dump of assembler code for function main:
0x0000000000401106 <+0>: 55 push %rbp
0x0000000000401107 <+1>: 48 89 e5 mov %rsp,%rbp
0x000000000040110a <+4>: c7 87 d8 00 00 00 01 00 00 00 movl $0x1,0xd8(%rdi)
0x0000000000401114 <+14>: b8 00 00 00 00 mov $0x0,%eax
0x0000000000401119 <+19>: 5d pop %rbp
0x000000000040111a <+20>: c3 ret
End of assembler dump.
Most instructions are aligned, except for the very long instruction.
Notice too that for x86-64 libopcodes doesn't request that GDB group
the instruction bytes. This matches the behaviour of objdump.
In case the user really wants the old behaviour, I have added a new
modifier 'disassemble /b', this displays the instruction byte at a
time. For x86-64, which never groups instruction bytes, /b and /r are
equivalent, but for RISC-V, using /b gets the old layout back (except
that the whitespace for alignment is still present). Consider our
original RISC-V example, this time using /b:
(gdb) disassemble /b 0x0001018e,0x0001019e
Dump of assembler code from 0x1018e to 0x1019e:
0x0001018e <call_me+66>: 03 26 84 fe lw a2,-24(s0)
0x00010192 <call_me+70>: 83 25 c4 fe lw a1,-20(s0)
0x00010196 <call_me+74>: 61 65 lui a0,0x18
0x00010198 <call_me+76>: 13 05 85 6a addi a0,a0,1704
0x0001019c <call_me+80>: f1 22 jal 0x10368 <printf>
End of assembler dump.
Obviously, this patch is a potentially significant change to the
behaviour or /r. I could have added /b with the new behaviour and
left /r alone. However, personally, I feel the new behaviour is
significantly better than the old, hence, I made /r be what I consider
the "better" behaviour.
The reason I prefer the new behaviour is that, when I use /r, I almost
always want to manually decode the instruction for some reason, and
having the bytes displayed in "instruction order" rather than memory
order, just makes this easier.
The 'record instruction-history' command also takes a /r modifier, and
has been modified in the same way as disassemble; /r gets the new
behaviour, and /b has been added to retain the old behaviour.
Finally, the MI command -data-disassemble, is unchanged in behaviour,
this command now requests the raw bytes of the instruction, which is
equivalent to the /b modifier. This means that the MI output will
remain backward compatible.
|
|
Remove the macro, replace all uses with calls to type::length.
Change-Id: Ib9bdc954576860b21190886534c99103d6a47afb
|
|
I went through all the uses of dynamic_cast<> in gdb, looking for ones
that could be replaced with checked_static_cast. This patch is the
result. Regression tested on x86-64 Fedora 34.
|
|
mi_interp::resume does not need to call clear_interpreter_hooks,
because this is already done by interp_set.
|
|
These members of mi_interp aren't used and can be removed.
|
|
This changes ui_out_redirect_pop to also perform the redirection, and
then updates several sites to use this, rather than explicit
redirects.
|
|
The "script" field, output whenever information about a breakpoint with
commands is output, uses wrong MI syntax.
$ ./gdb -nx -q --data-directory=data-directory -x script -i mi
=thread-group-added,id="i1"
=breakpoint-created,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000000111d",func="main",file="test.c",fullname="/home/simark/build/binutils-gdb-one-target/gdb/test.c",line="3",thread-groups=["i1"],times="0",original-location="main"}
=breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000000111d",func="main",file="test.c",fullname="/home/simark/build/binutils-gdb-one-target/gdb/test.c",line="3",thread-groups=["i1"],times="0",script={"aaa","bbb","ccc"},original-location="main"}
(gdb)
-break-info
^done,BreakpointTable={nr_rows="1",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="18",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x000000000000111d",func="main",file="test.c",fullname="/home/simark/build/binutils-gdb-one-target/gdb/test.c",line="3",thread-groups=["i1"],times="0",script={"aaa","bbb","ccc"},original-location="main"}]}
(gdb)
In both the =breakpoint-modified and -break-info output, we have:
script={"aaa","bbb","ccc"}
According to the output syntax [1], curly braces means tuple, and a
tuple contains key=value pairs. This looks like it should be a list,
but uses curly braces by mistake. This would make more sense:
script=["aaa","bbb","ccc"]
Fix it, keeping the backwards compatibility by introducing a new MI
version (MI4), in exactly the same way as was done when fixing
multi-locations breakpoint output in [2].
- Add a fix_breakpoint_script_output uiout flag. MI uiouts will use
this flag if the version is >= 4.
- Add a fix_breakpoint_script_output_globally variable and the
-fix-breakpoint-script-output MI command to set it, if frontends want
to use the fixed output for this without using the newer MI version.
- When emitting the script field, use list instead of tuple, if we want
the fixed output (depending on the two criteria above)
-
[1] https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax
[2] https://gitlab.com/gnutools/binutils-gdb/-/commit/b4be1b0648608a2578bbed39841c8ee411773edd
Change-Id: I7113c6892832c8d6805badb06ce42496677e2242
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24285
|
|
cli_out_new is just a small wrapper around 'new'. This patch removes
it, replacing it with uses of 'new' instead.
|
|
[Note: the testcased added by this commit depends on
https://sourceware.org/pipermail/gdb-patches/2022-June/190259.html,
otherwise GDB just crashes when detaching the core]
Currently, in MI, =thread-created are always emitted, like:
=thread-group-started,id="i1",pid="195680"
=thread-created,id="1",group-id="i1"
...
but on teardown, if the target uses exit_inferior_silent, then you'll
only see the inferior exit notification (thread-group-exited), no
notification for threads.
The core target is one of the few targets that use
exit_inferior_silent. Here's an example session:
-target-select core $corefile
=thread-group-started,id="i1",pid="195680"
=thread-created,id="1",group-id="i1"
...
^connected,frame=....
(gdb)
-target-detach
=thread-group-exited,id="i1"
^done
(gdb)
This imbalance of emitting =thread-created but then not =thread-exited
seems off to me. (And, it complicates changes I want to do to
centralize emitting thread exit notifications for the CLI, which is
why I'm looking at this.)
And then, since most other targets use exit_inferior instead of
exit_inferior_silent, MI is already emitting =thread-exited
notifications when tearing down an inferior, for most targets.
This commit makes MI always emit the =thread-exited notifications,
even for exit_inferior_silent.
Afterwards, when debugging a core, MI outputs:
(gdb)
-target-detach
=thread-exited,id="1",group-id="i1" << new line
=thread-group-exited,id="i1"
^done
(gdb)
Surprisingly, there's no MI testcase debugging a core file. This
commit adds the first.
Change-Id: I5100501a46f07b6bbad3e04d120c2562a51c93a4
|
|
I noticed that touching interps.h caused a lot of recompilation. I
tracked this down to mi-common.h including this file. This patch
moves the MI interpreter to mi-interp.h, which cuts down on
recompilation when modifying interps.h.
|
|
Currently, there's the location_spec hierarchy, and then some
location_spec subclasses have their own struct type holding all their
data fields.
I.e., there is this:
location_spec
explicit_location_spec
linespec_location_spec
address_location_spec
probe_location_spec
and then these separate types:
explicit_location
linespec_location
where:
explicit_location_spec
has-a explicit_location
linespec_location_spec
has-a linespec_location
This patch eliminates explicit_location and linespec_location,
inlining their members in the corresponding location_spec type.
The location_spec subclasses were the ones currently defined in
location.c, so they are moved to the header. Since the definitions of
the classes are now visible, we no longer need location_spec_deleter.
Some constructors that are used for cloning location_specs, like:
explicit explicit_location_spec (const struct explicit_location *loc)
... were converted to proper copy ctors.
In the process, initialize_explicit_location is eliminated, and some
functions that returned the "data type behind a locspec", like
get_linespec_location are converted to downcast functions, like
as_linespec_location_spec.
Change-Id: Ia31ccef9382b25a52b00fa878c8df9b8cf2a6c5a
|
|
Currently, GDB internally uses the term "location" for both the
location specification the user input (linespec, explicit location, or
an address location), and for actual resolved locations, like the
breakpoint locations, or the result of decoding a location spec to
SaLs. This is expecially confusing in the breakpoints module, as
struct breakpoint has these two fields:
breakpoint::location;
breakpoint::loc;
"location" is the location spec, and "loc" is the resolved locations.
And then, we have a method called "locations()", which returns the
resolved locations as range...
The location spec type is presently called event_location:
/* Location we used to set the breakpoint. */
event_location_up location;
and it is described like this:
/* The base class for all an event locations used to set a stop event
in the inferior. */
struct event_location
{
and even that is incorrect... Location specs are used for finding
actual locations in the program in scenarios that have nothing to do
with stop events. E.g., "list" works with location specs.
To clean all this confusion up, this patch renames "event_location" to
"location_spec" throughout, and then all the variables that hold a
location spec, they are renamed to include "spec" in their name, like
e.g., "location" -> "locspec". Similarly, functions that work with
location specs, and currently have just "location" in their name are
renamed to include "spec" in their name too.
Change-Id: I5814124798aa2b2003e79496e78f95c74e5eddca
|
|
Even after the previous patches reworking the inheritance of several
breakpoint types, the present breakpoint hierarchy looks a bit
surprising, as we have "breakpoint" as the superclass, and then
"base_breakpoint" inherits from "breakpoint". Like so, simplified:
breakpoint
base_breakpoint
ordinary_breakpoint
internal_breakpoint
momentary_breakpoint
ada_catchpoint
exception_catchpoint
tracepoint
watchpoint
catchpoint
exec_catchpoint
...
The surprising part to me is having "base_breakpoint" being a subclass
of "breakpoint". I'm just refering to naming here -- I mean, you'd
expect that it would be the top level baseclass that would be called
"base".
Just flipping the names of breakpoint and base_breakpoint around
wouldn't be super great for us, IMO, given we think of every type of
*point as a breakpoint at the user visible level. E.g., "info
breakpoints" shows watchpoints, tracepoints, etc. So it makes to call
the top level class breakpoint.
Instead, I propose renaming base_breakpoint to code_breakpoint. The
previous patches made sure that all code breakpoints inherit from
base_breakpoint, so it's fitting. Also, "code breakpoint" contrasts
nicely with a watchpoint also being typically known as a "data
breakpoint".
After this commit, the resulting hierarchy looks like:
breakpoint
code_breakpoint
ordinary_breakpoint
internal_breakpoint
momentary_breakpoint
ada_catchpoint
exception_catchpoint
tracepoint
watchpoint
catchpoint
exec_catchpoint
...
... which makes a lot more sense to me.
I've left this patch as last in the series in case people want to
bikeshed on the naming.
"code" has a nice property that it's exactly as many letters as
"base", so this patch didn't require any reindentation. :-)
Change-Id: Id8dc06683a69fad80d88e674f65e826d6a4e3f66
|
|
There's no need to have vtable_breakpoint_ops any more, so remove it
in favor of base_breakpoint_ops.
|
|
This converts dprintf to use vtable_breakpoint_ops.
|
|
This converts "ordinary" breakpoint to use vtable_breakpoint_ops.
Recall that an ordinary breakpoint is both the kind normally created
by users, and also a base class used by other classes.
|
|
This converts tracepoints to use vtable_breakpoint_ops.
|
|
Replace with equivalent methods.
Change-Id: I334a319909a50b5cc5570a45c38c70e10dc00630
|
|
Replace with equivalent methods.
Change-Id: I31ec00f5bf85335c8b23d306ca0fe0b84d489101
|
|
This turns symbol_symtab into a method on symbol. It also replaces
symbol_set_symtab with a method.
|
|
Remove all macros related to getting and setting some symbol value:
#define SYMBOL_VALUE(symbol) (symbol)->value.ivalue
#define SYMBOL_VALUE_ADDRESS(symbol) \
#define SET_SYMBOL_VALUE_ADDRESS(symbol, new_value) \
#define SYMBOL_VALUE_BYTES(symbol) (symbol)->value.bytes
#define SYMBOL_VALUE_COMMON_BLOCK(symbol) (symbol)->value.common_block
#define SYMBOL_BLOCK_VALUE(symbol) (symbol)->value.block
#define SYMBOL_VALUE_CHAIN(symbol) (symbol)->value.chain
#define MSYMBOL_VALUE(symbol) (symbol)->value.ivalue
#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->value.address + 0)
#define MSYMBOL_VALUE_ADDRESS(objfile, symbol) \
#define BMSYMBOL_VALUE_ADDRESS(symbol) \
#define SET_MSYMBOL_VALUE_ADDRESS(symbol, new_value) \
#define MSYMBOL_VALUE_BYTES(symbol) (symbol)->value.bytes
#define MSYMBOL_BLOCK_VALUE(symbol) (symbol)->value.block
Replace them with equivalent methods on the appropriate objects.
Change-Id: Iafdab3b8eefc6dc2fd895aa955bf64fafc59ed50
|
|
Same idea as previous patch, but for symtab::objfile. I find
it clearer without this wrapper, as it shows that the objfile is
common to all symtabs of a given compunit. Otherwise, you could think
that each symtab (of a given compunit) can have a specific objfile.
Change-Id: Ifc0dbc7ec31a06eefa2787c921196949d5a6fcc6
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the printf family of functions. This is done under the name
"gdb_printf". Most of this patch was written by script.
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the putc family of functions. This is done under the name
"gdb_putc". Most of this patch was written by script.
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the puts family of functions. This is done under the name
"gdb_puts". Most of this patch was written by script.
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the vprintf family of functions: vprintf_filtered,
vprintf_unfiltered, vfprintf_filtered and vfprintf_unfiltered. (For
the gdb_stdout variants, recall that only printf_unfiltered gets truly
unfiltered output at this point.) This removes one such function and
renames the remaining two to "gdb_vprintf". All callers are updated.
Much of this patch was written by script.
|
|
In commit:
commit a2757c4ed693cef4ecc4dcdcb2518353eb6b3c3f
Date: Wed Mar 16 15:08:22 2022 +0000
gdb/mi: consistently notify user when GDB/MI client uses -thread-select
Changes were made to GDB to address some inconsistencies in when
notifications are sent from a MI terminal to a CLI terminal (when
multiple terminals are in use, see new-ui command).
Unfortunately, in order to track when the currently selected frame has
changed, that commit grabs a frame_info pointer before and after an MI
command has executed, and compares the pointers to see if the frame
has changed.
This is not safe.
If the frame cache is deleted for any reason then the frame_info
pointer captured before the command started, is no longer valid, and
any comparisons based on that pointer are undefined.
This was leading to random test failures for some folk, see:
https://sourceware.org/pipermail/gdb-patches/2022-March/186867.html
This commit changes GDB so we no longer hold frame_info pointers, but
instead store the frame_id and frame_level, this is safe even when the
frame cache is flushed.
|
|
The motivation for this patch is the fact that py-micmd.c doesn't build
with Python 2, due to PyDict_GetItemWithError being a Python 3-only
function:
CXX python/py-micmd.o
/home/smarchi/src/binutils-gdb/gdb/python/py-micmd.c: In function ‘int micmdpy_uninstall_command(micmdpy_object*)’:
/home/smarchi/src/binutils-gdb/gdb/python/py-micmd.c:430:20: error: ‘PyDict_GetItemWithError’ was not declared in this scope; did you mean ‘PyDict_GetItemString’?
430 | PyObject *curr = PyDict_GetItemWithError (mi_cmd_dict.get (),
| ^~~~~~~~~~~~~~~~~~~~~~~
| PyDict_GetItemString
A first solution to fix this would be to try to replace
PyDict_GetItemWithError equivalent Python 2 code. But I looked at why
we are doing this in the first place: it is to maintain the
`gdb._mi_commands` Python dictionary that we use as a `name ->
gdb.MICommand object` map. Since the `gdb._mi_commands` dictionary is
never actually used in Python, it seems like a lot of trouble to use a
Python object for this.
My first idea was to replace it with a C++ map
(std::unordered_map<std::string, gdbpy_ref<micmdpy_object>>). While
implementing this, I realized we don't really need this map at all. The
mi_command_py objects registered in the main MI command table can own
their backing micmdpy_object (that's a gdb.MICommand, but seen from the
C++ code). To know whether an mi_command is an mi_command_py, we can
use a dynamic cast. Since there's one less data structure to maintain,
there are less chances of messing things up.
- Change mi_command_py::m_pyobj to a gdbpy_ref, the mi_command_py is
now what keeps the MICommand alive.
- Set micmdpy_object::mi_command in the constructor of mi_command_py.
If mi_command_py manages setting/clearing that field in
swap_python_object, I think it makes sense that it also takes care of
setting it initially.
- Move a bunch of checks from micmdpy_install_command to
swap_python_object, and make them gdb_asserts.
- In micmdpy_install_command, start by doing an mi_cmd_lookup. This is
needed to know whether there's a Python MI command already registered
with that name. But we can already tell if there's a non-Python
command registered with that name. Return an error if that happens,
rather than waiting for insert_mi_cmd_entry to fail. Change the
error message to "name is already in use" rather than "may already be
in use", since it's more precise.
I asked Andrew about the original intent of using a Python dictionary
object to hold the command objects. The reason was to make sure the
objects get destroyed when the Python runtime gets finalized, not later.
Holding the objects in global C++ data structures and not doing anything
more means that the held Python objects will be decref'd after the
Python interpreter has been finalized. That's not desirable. I tried
it and it indeed segfaults.
Handle this by adding a gdbpy_finalize_micommands function called in
finalize_python. This is the mirror of gdbpy_initialize_micommands
called in do_start_initialization. In there, delete all Python MI
commands. I think it makes sense to do it this way: if it was somehow
possible to unload Python support from GDB in the middle of a session
we'd want to unregister any Python MI command. Otherwise, these MI
commands would be backed with a stale PyObject or simply nothing.
Delete tests that were related to `gdb._mi_commands`.
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Change-Id: I060d5ebc7a096c67487998a8a4ca1e8e56f12cd3
|
|
GDB notifies users about user selected thread changes somewhat
inconsistently as mentioned on gdb-patches mailing list here:
https://sourceware.org/pipermail/gdb-patches/2022-February/185989.html
Consider GDB debugging a multi-threaded inferior with both CLI and GDB/MI
interfaces connected to separate terminals.
Assuming inferior is stopped and thread 1 is selected, when a thread
2 is selected using '-thread-select 2' command on GDB/MI terminal:
-thread-select 2
^done,new-thread-id="2",frame={level="0",addr="0x00005555555551cd",func="child_sub_function",args=[],file="/home/jv/Projects/gdb/users_jv_patches/gdb/testsuite/gdb.mi/user-selected-context-sync.c",fullname="/home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c",line="30",arch="i386:x86-64"}
(gdb)
and on CLI terminal we get the notification (as expected):
[Switching to thread 2 (Thread 0x7ffff7daa640 (LWP 389659))]
#0 child_sub_function () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30
30 volatile int dummy = 0;
However, now that thread 2 is selected, if thread 1 is selected
using 'thread-select --thread 1 1' command on GDB/MI terminal
terminal:
-thread-select --thread 1 1
^done,new-thread-id="1",frame={level="0",addr="0x0000555555555294",func="main",args=[],file="/home/jv/Projects/gdb/users_jv_patches/gdb/testsuite/gdb.mi/user-selected-context-sync.c",fullname="/home/jv/Projects/gdb/users_jv_patches/gdb/testsuite/gdb.mi/user-selected-context-sync.c",line="66",arch="i386:x86-64"}
(gdb)
but no notification is printed on CLI terminal, despite the fact
that user selected thread has changed.
The problem is that when `-thread-select --thread 1 1` is executed
then thread is switched to thread 1 before mi_cmd_thread_select () is
called, therefore the condition "inferior_ptid != previous_ptid"
there does not hold.
To address this problem, we have to move notification logic up to
mi_cmd_execute () where --thread option is processed and notify
user selected contents observers there if context changes.
However, this in itself breaks GDB/MI because it would cause context
notification to be sent on MI channel. This is because by the time
we notify, MI notification suppression is already restored (done in
mi_command::invoke(). Therefore we had to lift notification suppression
logic also up to mi_cmd_execute (). This change in made distinction
between mi_command::invoke() and mi_command::do_invoke() unnecessary
as all mi_command::invoke() did (after the change) was to call
do_invoke(). So this patches removes do_invoke() and moves the command
execution logic directly to invoke().
With this change, all gdb.mi tests pass, tested on x86_64-linux.
Co-authored-by: Andrew Burgess <aburgess@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20631
|
|
This commit allows a user to create custom MI commands using Python
similarly to what is possible for Python CLI commands.
A new subclass of mi_command is defined for Python MI commands,
mi_command_py. A new file, gdb/python/py-micmd.c contains the logic
for Python MI commands.
This commit is based on work linked too from this mailing list thread:
https://sourceware.org/pipermail/gdb/2021-November/049774.html
Which has also been previously posted to the mailing list here:
https://sourceware.org/pipermail/gdb-patches/2019-May/158010.html
And was recently reposted here:
https://sourceware.org/pipermail/gdb-patches/2022-January/185190.html
The version in this patch takes some core code from the previously
posted patches, but also has some significant differences, especially
after the feedback given here:
https://sourceware.org/pipermail/gdb-patches/2022-February/185767.html
A new MI command can be implemented in Python like this:
class echo_args(gdb.MICommand):
def invoke(self, args):
return { 'args': args }
echo_args("-echo-args")
The 'args' parameter (to the invoke method) is a list
containing (almost) all command line arguments passed to the MI
command (--thread and --frame are handled before the Python code is
called, and removed from the args list). This list can be empty if
the MI command was passed no arguments.
When used within gdb the above command produced output like this:
(gdb)
-echo-args a b c
^done,args=["a","b","c"]
(gdb)
The 'invoke' method of the new command must return a dictionary. The
keys of this dictionary are then used as the field names in the mi
command output (e.g. 'args' in the above).
The values of the result returned by invoke can be dictionaries,
lists, iterators, or an object that can be converted to a string.
These are processed recursively to create the mi output. And so, this
is valid:
class new_command(gdb.MICommand):
def invoke(self,args):
return { 'result_one': { 'abc': 123, 'def': 'Hello' },
'result_two': [ { 'a': 1, 'b': 2 },
{ 'c': 3, 'd': 4 } ] }
Which produces output like:
(gdb)
-new-command
^done,result_one={abc="123",def="Hello"},result_two=[{a="1",b="2"},{c="3",d="4"}]
(gdb)
I have required that the fields names used in mi result output must
match the regexp: "^[a-zA-Z][-_a-zA-Z0-9]*$" (without the quotes).
This restriction was never written down anywhere before, but seems
sensible to me, and we can always loosen this rule later if it proves
to be a problem. Much harder to try and add a restriction later, once
people are already using the API.
What follows are some details about how this implementation differs
from the original patch that was posted to the mailing list.
In this patch, I have changed how the lifetime of the Python
gdb.MICommand objects is managed. In the original patch, these object
were kept alive by an owned reference within the mi_command_py object.
As such, the Python object would not be deleted until the
mi_command_py object itself was deleted.
This caused a problem, the mi_command_py were held in the global mi
command table (in mi/mi-cmds.c), which, as a global, was not cleared
until program shutdown. By this point the Python interpreter has
already been shutdown. Attempting to delete the mi_command_py object
at this point was causing GDB to try and invoke Python code after
finalising the Python interpreter, and we would crash.
To work around this problem, the original patch added code in
python/python.c that would search the mi command table, and delete the
mi_command_py objects before the Python environment was finalised.
In contrast, in this patch, I have added a new global dictionary to
the gdb module, gdb._mi_commands. We already have several such global
data stores related to pretty printers, and frame unwinders.
The MICommand objects are placed into the new gdb.mi_commands
dictionary, and it is this reference that keeps the objects alive.
When GDB's Python interpreter is shut down gdb._mi_commands is deleted,
and any MICommand objects within it are deleted at this point.
This change avoids having to make the mi_cmd_table global, and walk
over it from within GDB's python related code.
This patch handles command redefinition entirely within GDB's python
code, though this does impose one small restriction which is not
present in the original code (detailed below), I don't think this is a
big issue. However, the original patch relied on being able to
finish executing the mi_command::do_invoke member function after the
mi_command object had been deleted. Though continuing to execute a
member function after an object is deleted is well defined, it is
also (IMHO) risky, its too easy for someone to later add a use of the
object without realising that the object might sometimes, have been
deleted. The new patch avoids this issue.
The one restriction that is added to avoid this, is that an MICommand
object can't be reinitialised with a different command name, so:
(gdb) python cmd = MyMICommand("-abc")
(gdb) python cmd.__init__("-def")
can't reinitialize object with a different command name
This feels like a pretty weird edge case, and I'm happy to live with
this restriction.
I have also changed how the memory is managed for the command name.
In the most recently posted patch series, the command name is moved
into a subclass of mi_command, the python mi_command_py, which
inherits from mi_command is then free to use a smart pointer to manage
the memory for the name.
In this patch, I leave the mi_command class unchanged, and instead
hold the memory for the name within the Python object, as the lifetime
of the Python object always exceeds the c++ object stored in the
mi_cmd_table. This adds a little more complexity in py-micmd.c, but
leaves the mi_command class nice and simple.
Next, this patch adds some extra functionality, there's a
MICommand.name read-only attribute containing the name of the command,
and a read-write MICommand.installed attribute that can be used to
install (make the command available for use) and uninstall (remove the
command from the mi_cmd_table so it can't be used) the command. This
attribute will be automatically updated if a second command replaces
an earlier command.
This patch adds additional error handling, and makes more use the
gdbpy_handle_exception function.
Co-Authored-By: Jan Vrany <jan.vrany@labware.com>
|
|
Fix for PR gdb/20684. When invoking MI commands with --thread and/or
--frame, the user selected thread and frame was not preserved:
(gdb)
info thread
&"info thread\n"
~" Id Target Id Frame \n"
~"* 1 Thread 0x7ffff7c30740 (LWP 19302) \"user-selected-c\" main () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:60\n"
~" 2 Thread 0x7ffff7c2f700 (LWP 19306) \"user-selected-c\" child_sub_function () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30\n"
~" 3 Thread 0x7ffff742e700 (LWP 19307) \"user-selected-c\" child_sub_function () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30\n"
^done
(gdb)
info frame
&"info frame\n"
~"Stack level 0, frame at 0x7fffffffdf90:\n"
~" rip = 0x555555555207 in main (/home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:60); saved rip = 0x7ffff7c5709b\n"
~" source language c.\n"
~" Arglist at 0x7fffffffdf80, args: \n"
~" Locals at 0x7fffffffdf80, Previous frame's sp is 0x7fffffffdf90\n"
~" Saved registers:\n "
~" rbp at 0x7fffffffdf80, rip at 0x7fffffffdf88\n"
^done
(gdb)
-stack-info-depth --thread 3
^done,depth="4"
(gdb)
info thread
&"info thread\n"
~" Id Target Id Frame \n"
~" 1 Thread 0x7ffff7c30740 (LWP 19302) \"user-selected-c\" main () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:60\n"
~" 2 Thread 0x7ffff7c2f700 (LWP 19306) \"user-selected-c\" child_sub_function () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30\n"
~"* 3 Thread 0x7ffff742e700 (LWP 19307) \"user-selected-c\" child_sub_function () at /home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30\n"
^done
(gdb)
info frame
&"info frame\n"
~"Stack level 0, frame at 0x7ffff742dee0:\n"
~" rip = 0x555555555169 in child_sub_function (/home/uuu/gdb/gdb/testsuite/gdb.mi/user-selected-context-sync.c:30); saved rip = 0x555555555188\n"
~" called by frame at 0x7ffff742df00\n"
~" source language c.\n"
~" Arglist at 0x7ffff742ded0, args: \n"
~" Locals at 0x7ffff742ded0, Previous frame's sp is 0x7ffff742dee0\n"
~" Saved registers:\n "
~" rbp at 0x7ffff742ded0, rip at 0x7ffff742ded8\n"
^done
(gdb)
This caused problems for frontends that provide access to CLI because UI
may silently change the context for CLI commands (as demonstrated above).
This commit fixes the problem by restoring thread and frame in
mi_cmd_execute (). With this change, there are only two GDB/MI commands
that can change user selected context: -thread-select and -stack-select-frame.
This allows us to remove all and rather complicated logic of notifying
about user selected context change from mi_execute_command (), leaving it
to these two commands themselves to notify.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20684
|
|
Following on from the previous commit, where the -add-inferior command
now uses the same connection as the current inferior, this commit adds
a --no-connection option to -add-inferior.
This new option matches the existing option of the same name for the
CLI version of add-inferior; the new inferior is created with no
connection.
I've added a new 'connection' field to the MI output of -add-inferior,
which includes the connection number and short name. I haven't
included the longer description field, this is the MI after all. My
expectation would be that if the frontend wanted to display all the
connection details then this would be looked up from 'info
connection' (or the MI equivalent if/when such a command is added).
The existing -add-inferior tests are updated, as are the docs.
|
|
Prior to the multi-target support commit:
commit 5b6d1e4fa4fc6827c7b3f0e99ff120dfa14d65d2
Date: Fri Jan 10 20:06:08 2020 +0000
Multi-target support
When a new inferior was added using the MI -add-inferior command, the
new inferior would be using the same target as all the other
inferiors. This makes sense, GDB only supported a single target stack
at a time.
After the above commit, each inferior has its own target stack.
To maintain backward compatibility, for the CLI add-inferior command,
when a new inferior is added the above commit has the new inferior
inherit a copy of the target stack from the current inferior.
Unfortunately, this same backward compatibility is missing for the MI.
This commit fixes this oversight.
Now, when the -add-inferior MI command is used, the new inferior will
inherit a copy of the target stack from the current inferior.
|
|
Joel noticed that if the remote dies unexpectedly during a command --
you can simulate this by using "continue" and then killing gdbserver
-- then the CLI will print a new prompt, but MI will not. Later, we
found out that this was also filed in bugzilla as PR mi/23820.
The output looks something like this:
| (gdb)
| cont
| &"cont\n"
| ~"Continuing.\n"
| ^running
| *running,thread-id="all"
| (gdb)
| [... some output from GDB during program startup...]
| =thread-exited,id="1",group-id="i1"
| =thread-group-exited,id="i1"
| &"Remote connection closed\n"
Now, what about that "(gdb)" in the middle?
That prompt comes from this questionable code in
mi-interp.c:mi_on_resume_1:
/* This is what gdb used to do historically -- printing prompt
even if it cannot actually accept any input. This will be
surely removed for MI3, and may be removed even earlier. */
if (current_ui->prompt_state == PROMPT_BLOCKED)
fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
... which seems like something to remove. But maybe the intent here
is that this prompt is sufficient, and MI clients must be ready to
handle output coming after a prompt. On the other hand, if this code
*is* removed, then nothing would print a prompt in this scenario.
Anyway, the CLI and the TUI handle emitting the prompt here by hooking
into gdb::observers::command_error, but MI doesn't install an observer
here.
This patch adds the missing observer and arranges to show the MI
prompt. Regression tested on x86-64 Fedora 34.
It seems like this area could be improved a bit, by having
start_event_loop call the prompt-displaying code directly, rather than
indirecting through an observer. However, I haven't done this.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23820
|
|
While working on function calls, I realized that the thread_fsm member
of struct thread_info is a raw pointer to a resource it owns. This
commit changes the type of the thread_fsm member to a std::unique_ptr in
order to signify this ownership relationship and slightly ease resource
management (no need to manually call delete).
To ensure consistent use, the field is made a private member
(m_thread_fsm). The setter method (set_thread_fsm) can then check
that it is incorrect to associate a FSM to a thread_info object if
another one is already in place. This is ensured by an assertion.
The function run_inferior_call takes an argument as a pointer to a
call_thread_fsm and installs it in it in a thread_info instance. Also
change this function's signature to accept a unique_ptr in order to
signify that the ownership of the call_thread_fsm is transferred during
the call.
No user visible change expected after this commit.
Tested on x86_64-linux with no regression observed.
Change-Id: Ia1224f72a4afa247801ce6650ce82f90224a9ae8
|
|
Add a getter and a setter for a symbol's line. Remove the corresponding macro
and adjust all callers.
Change-Id: I229f2b8fcf938c07975f641361313a8761fad9a5
|
|
Add a getter and a setter for a symbol's type. Remove the corresponding
macro and adjust all callers.
Change-Id: Ie1a137744c5bfe1df4d4f9ae5541c5299577c8de
|
|
Add a getter and a setter for whether a symbol is an argument. Remove
the corresponding macro and adjust all callers.
Change-Id: I71b4f0465f3dfd2ed8b9e140bd3f7d5eb8d9ee81
|
|
Change-Id: I83211d5a47efc0564386e5b5ea4a29c00b1fd46a
|
|
Remove the macro, replace with an equivalent method.
Change-Id: I8f9ecd290ad28502e53c1ceca5006ba78bf042eb
|
|
Add a getter and a setter for a symtab's linetable. Remove the
corresponding macro and adjust all callers.
Change-Id: I159183fc0ccd8e18ab937b3c2f09ef2244ec6e9c
|