While chasing some reverse debugging bugs, I found myself wondering what
was recorded by GDB to undo and redo a certain instruction. This commit
implements a simple way of printing that information.
If there isn't enough history to print the desired instruction (such as
when the user hasn't started recording yet or when they request 2
instructions back but only 1 was recorded), GDB warns the user like so:
(gdb) maint print record-instruction
Not enough recorded history
If there is enough, GDB prints the instruction like so:
(gdb) maint print record-instruction
4 bytes of memory at address 0x00007fffffffd5dc changed from: 01 00 00 00
Register eflags changed: [ IF ]
Register rip changed: (void (*)()) 0x401115 <main+15>
Approved-by: Eli Zaretskii <eliz@gnu.org>
Reviewed-by: Alexandra Hajkova <ahajkova@redhat.com>
Reviewed-by: Lancelot Six <lsix@lancelotsix.com>
Approved-by: Tom Tromey <tom@tromey.com>
This is something I discovered when working on aarch64, though it's
relevant to x86_64 too.
The PE32+ imports are located in the .idata section, which starts off
with a 20-byte structure for each DLL, containing offsets into the rest
of the section. This is the Import Directory Table in
https://learn.microsoft.com/en-us/windows/win32/debug/pe-format, which
is a concatenation of the .idata$2 sections. This is then followed by an
20 zero bytes generated by the linker script, which calls this .idata$3.
After this comes the .idata$4 entries for each function, which the
loader overwrites with the function pointers. Because there's no padding
between .idata$3 and .idata$4, this means that if there's an even number
of DLLs, the function pointers won't be aligned on an 8-byte boundary.
Misaligned reads are slower on x86_64, but this is more important on
aarch64, as the e.g. `ldr x0, [x0, :lo12:__imp__func]` the compiler
might generate requires __imp__func (the .idata$4 entry) to be aligned
to 8 bytes. Without this you get IMAGE_REL_ARM64_PAGEOFFSET_12L overflow
errors.
Those files have changed by regenerating using the maintainer mode.
The first line of sim/ppc/pk.h have changed by an effect of the commit
319e41e83a ("sim: ppc: inline the sim-packages option").
This adds a test case for "finish" with variably-sized types, and for
inferior calls as well. This also extends the "runto" proc to handle
temporary breakpoints.
get_call_return_value can handle RETURN_VALUE_STRUCT_CONVENTION,
because the call is completely managed by gdb. However, it does not
handle variably-sized types correctly. The simplest way to fix this
is to use value_at_non_lval, which does type resolution.
This converts a few selected architectures to use
gdbarch_return_value_as_value rather than gdbarch_return_value. The
architectures are just the ones that I am able to test. This patch
should not introduce any behavior changes.
On PPC, we saw that calling an inferior function could sometimes
change the current language, because gdb would select the call dummy
frame -- associated with _start.
This patch changes gdb so that the current language is never affected
by DWARF property evaluation.
In some cases, while a value might be read from memory, gdb should not
record the value as being equivalent to that memory.
In Ada, the inferior call code will call ada_convert_actual -- and
here, if the argument is already in memory, that address will simply
be reused. However, for a call like "f(g())", the result of "g" might
be on the stack and thus overwritten by the call to "f".
This patch introduces a new function that is like value_at but that
ensures that the result is non-lvalue.
The previous patch introduced a new overload of gdbarch_return_value.
The intent here is that this new overload always be called by the core
of gdb -- the previous implementation is effectively deprecated,
because a call to the old-style method will not work with any
converted architectures (whereas calling the new-style method is will
delegate when needed).
This patch changes gdbarch.py so that the old gdbarch_return_value
wrapper function can be omitted. This will prevent any errors from
creeping in.
The gdbarch "return_value" can't correctly handle variably-sized
types. The problem here is that the TYPE_LENGTH of such a type is 0,
until the type is resolved, which requires reading memory. However,
gdbarch_return_value only accepts a buffer as an out parameter.
Fixing this requires letting the implementation of the gdbarch method
resolve the type and return a value -- that is, both the contents and
the new type.
After an attempt at this, I realized I wouldn't be able to correctly
update all implementations (there are ~80) of this method. So,
instead, this patch adds a new method that falls back to the current
method, and it updates gdb to only call the new method. This way it's
possible to incrementally convert the architectures that I am able to
test.
amd64-tdep.c could crash when 'finish'ing from a function whose return
type had variable length. In this situation, the value will be passed
by reference, and this patch avoids the crash.
(Note that this does not fully fix the bug reported, but it does fix
the crash, so it seems worthwhile to land independently.)
On a x86_64-linux machine with pkru register, I run into:
...
(gdb) PASS: gdb.arch/i386-pkru.exp: set pkru value
info register pkru^M
pkru 0x12345678 305419896^M
(gdb) FAIL: gdb.arch/i386-pkru.exp: read value after setting value
...
This is a regression due to kernel commit e84ba47e313d ("x86/fpu: Hook up PKRU
onto ptrace()"). This is fixed by recent kernel commit 4a804c4f8356
("x86/fpu: Allow PKRU to be (once again) written by ptrace.").
The regression occurs for kernel versions v5.14-rc1 (the first tag containing
the regression) up to but excluding v6.2-rc1 (the first tag containing the fix).
Fix this by adding an xfail for the appropriate kernel versions.
Tested on x86_64-linux.
PR testsuite/29790
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29790
With a simple test-case:
...
$ cat test.c
char *p = "a";
int main (void) {
return strlen (p);
}
$ gcc -g test.c
...
we run into this segfault:
...
$ gdb -q -batch a.out -ex start -ex "p strlen (p)"
Temporary breakpoint 1 at 0x1151: file test.c, line 4.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main () at test.c:4
4 return strlen (p);
Fatal signal: Segmentation fault
...
The strlen is an ifunc, and consequently during the call to
call_function_by_hand_dummy for "p strlen (p)" another call
to call_function_by_hand_dummy is used to resolve the ifunc.
This invalidates the get_current_frame () result in the outer call.
Fix this by using prepare_reinflate and reinflate.
Note that this series (
https://inbox.sourceware.org/gdb-patches/20221214033441.499512-1-simon.marchi@polymtl.ca/ )
should address this problem, but this patch is a simpler fix which is easy to
backport.
Tested on x86_64-linux.
Co-Authored-By: Tom de Vries <tdevries@suse.de>
PR gdb/29941
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29941
This should have been part of the previous commit 80636a54bc
("sim: build: move generated headers to built sources"), but they were
missed because they're .c files effectively treated as .h files.
Rather than rely on SIM_SUBDIRS being set, add a dedicated variable
to track whether to enable the sim. While the current code works
fine, it won't work as we remove the recursive make logic (i.e. the
SIM_SUBDIRS variable).
Automake's automatic header deptracking has a bootstrap problem where
it can't detect generated headers when compiling. We've been handling
that by adding a custom SIM_ALL_RECURSIVE_DEPS variable, but that only
works when building objects recursively in subdirs. As we move those
out to the top-level, we don't have any recursive steps anymore. The
Automake approach is to declare those headers in BUILT_SOURCES.
This isn't completely foolproof as the Automake manual documents: it
only activates for `make all`, not `make foo.o`, but that shouldn't be
a huge limitation as it only affects the initial compile. After that,
rebuilds should work fine.
The rules seem to generate the same output as existing subdir cgen
rules with cgen ports, so hopefully this should be correct. These
are the last set of codegen rules that we run in subdirs, so this
will help unblock killing off subdir builds entirely.
Rather than define our own hack for emitting an include statement,
use the existing Automake include variables. These have the nice
side-effect of being more portable.
The Debugger Adapter Protocol is a JSON-RPC protocol that IDEs can use
to communicate with debuggers. You can find more information here:
https://microsoft.github.io/debug-adapter-protocol/
Frequently this is implemented as a shim, but it seemed to me that GDB
could implement it directly, via the Python API. This patch is the
initial implementation.
DAP is implemented as a new "interp". This is slightly weird, because
it doesn't act like an ordinary interpreter -- for example it doesn't
implement a command syntax, and doesn't use GDB's ordinary event loop.
However, this seemed like the best approach overall.
To run GDB in this mode, use:
gdb -i=dap
The DAP code will accept JSON-RPC messages on stdin and print
responses to stdout. GDB redirects the inferior's stdout to a new
pipe so that output can be encapsulated by the protocol.
The Python code uses multiple threads to do its work. Separate
threads are used for reading JSON from the client and for writing JSON
to the client. All GDB work is done in the main thread. (The first
implementation used asyncio, but this had some limitations, and so I
rewrote it to use threads instead.)
This is not a complete implementation of the protocol, but it does
implement enough to demonstrate that the overall approach works.
There is a rudimentary test suite. It uses a JSON parser written in
pure Tcl. This parser is under the same license as Tcl itself, so I
felt it was acceptable to simply import it into the tree.
There is also a bit of documentation -- just documenting the new
interpreter name.
The cced7cacec ("gdb: preserve `|` in connection details string")
commit added '|' detection and removal to ser-pipe.c, but missed to add it
to ser-mingw.c.
This results in the error message below for MinGW hosts:
error starting child process '| <executable> <args>': CreateProcess: No such file or directory
This commit add the missing '|' detection and removal to ser-mingw.c.
I noticed that, when using gdbserver, gdb might print:
Reading /usr/lib/debug/lib64//libcap.so.2.48-2.48-4.fc36.x86_64.debug from remote target...
Reading target:/usr/lib/debug/lib64//libcap.so.2.48-2.48-4.fc36.x86_64.debug from remote target...
The second line has the "target:" prefix, but from the code it's clear
that this string is being passed verbatim to gdbserver -- which seems
wrong.
I filed PR remote/29929 for this.
The problem here is that find_separate_debug_file uses gdb_sysroot
without checking to see if it starts with the "target:" prefix. This
patch changes this code to be a little more careful.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29929
On x86_64-linux, I run into:
...
(gdb) python hbp1 = gdb.Breakpoint("add", type=gdb.BP_HARDWARE_BREAKPOINT)^M
Hardware assisted breakpoint 2 at 0x40072e: add. (7 locations)^M
(gdb) FAIL: gdb.python/py-breakpoint.exp: test_hardware_breakpoints: \
Set hardware breakpoint
...
due to libstdc++ debug info:
...
$ gdb -q -batch outputs/gdb.python/py-breakpoint/py-breakpoint \
-ex start \
-ex "b add" \
-ex "info break"
Temporary breakpoint 1 at 0x40076a: file py-breakpoint.c, line 50.
Temporary breakpoint 1, main (argc=1, argv=$hex) at py-breakpoint.c:50
50 int foo = 5;
Breakpoint 2 at 0x40072e: add. (7 locations)
Num Type Disp Enb Address What
2 breakpoint keep y <MULTIPLE>
2.1 y 0x000000000040072e in add(int) at \
py-breakpoint.c:39
2.2 y 0x00007ffff7b131de in \
(anonymous namespace)::fast_float::bigint::add at \
../../../../../libstdc++-v3/src/c++17/fast_float/fast_float.h:1815
...
2.7 y 0x00007ffff7b137e4 in \
(anonymous namespace)::fast_float::bigint::add at \
../../../../../libstdc++-v3/src/c++17/fast_float/fast_float.h:1815
...
Fix this by using qualified=True.
Tested on x86_64-linux.
PR testsuite/29910
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29910
Clean up includes a bit by making ports include bfd/ headers
explicitly. This matches other projects, and makes it more clear
where these headers are coming from.
Clean up includes a bit by making ports include opcodes/ headers
explicitly. This matches other projects, and makes it more clear
where these headers are coming from.
Delete a few files only used for obsolete targets, and tidy config,
xfails and other pieces of support specific to those targets. And
since I was editing target triplets in test files, fix the nm
alpha-linuxecoff fails.