Running
$ make check TESTS="gdb.gdb/unittest.exp" RUNTESTFLAGS="--target_board=native-extended-gdbserver"
I get some failures:
Running selftest regcache::cooked_write_test::i386.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i386:intel.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i386:x64-32.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i386:x64-32:intel.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i386:x86-64.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i386:x86-64:intel.^M
Self test failed: target already pushed^M
Running selftest regcache::cooked_write_test::i8086.^M
Self test failed: target already pushed^M
This is because the native-extended-gdbserver automatically connects GDB
to a GDBserver on startup, and therefore pushes a remote target on the
initial inferior. cooked_write_test is currently written in a way that
errors out if the current inferior has a process_stratum_target pushed.
Rewrite it to use scoped_mock_context, so it doesn't depend on the
current inferior (the current one upon entering the function).
Change-Id: I0357f989eacbdecc4bf88b043754451b476052ad
Various packages (glib and gtk4 for example) produces data-only objects
using `ld -r -b binary` or `objcopy`, with no elf header flags set. But
these files also have no code sections, so they should be compatible
with all ABIs.
bfd/
* elfnn-loongarch.c (elfNN_loongarch_merge_private_bfd_data):
Skip ABI checks if the input has no code sections.
Reported-by: Wu Xiaotian <yetist@gmail.com>
Suggested-by: Wang Xuerui <i@xen0n.name>
Signed-off-by: Xi Ruoyao <xry111@mengyan1223.wang>
opcodes/
* s390-opc.c (INSTR_RRF_R0RER): New instruction type.
(MASK_RRF_R0RER): Define mask for new instruction type.
* s390-opc.txt: Use RRF_R0RER for mgrk and RXY_RERRD for mg.
When an IR symbol SYM is referenced in IR via __real_SYM, its resolution
should be LDPR_PREVAILING_DEF, not PREVAILING_DEF_IRONLY, since LTO
doesn't know that __real_SYM should be resolved by SYM.
bfd/
PR ld/29086
* linker.c (bfd_wrapped_link_hash_lookup): Mark SYM is referenced
via __real_SYM.
include/
PR ld/29086
* bfdlink.h (bfd_link_hash_entry): Add ref_real.
ld/
PR ld/29086
* plugin.c (get_symbols): Resolve SYM definition to
LDPR_PREVAILING_DEF for __real_SYM reference.
* testsuite/ld-plugin/lto.exp: Run PR ld/29086 test.
* testsuite/ld-plugin/pr29086.c: New file.
cris support will be built into a 32-bit bfd if using --enable-targets=all
on a 32-bit host, so we may as well make targmatch.h include cris.
* config.bfd (cris): Remove #idef BFD64.
Tidy the dynamic reloc handling code in check_relocs, removing
leftover comments and code from when check_relocs was called as each
object file was read in.
* elf64-ppc.c (ppc64_elf_check_relocs): Tidy dynamic reloc
handling code.
(dec_dynrel_count): Do the same here.
My patches yesterday to unify the DWARF index base classes had a bug
-- namely, I did the wholesale dynamic_cast-to-static_cast too hastily
and introduced a crash. This can be seen by trying to add an index to
a file that has an index, or by running a test like gdb-index-cxx.exp
using the cc-with-debug-names.exp target board.
This patch fixes the crash by introducing a new virtual method and
removing some of the static casts.
For some reason g++ 11.2.1 on s390x produces a spurious warning for
stringop-overread in debuginfod_is_enabled for url_view. Add a new
DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD macro to suppress this warning.
include/ChangeLog:
* diagnostics.h (DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD): New
macro.
gdb/ChangeLog:
* debuginfod-support.c (debuginfod_is_enabled): Use
DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD on s390x.
Luis noticed that the recent changes to gdbserver to make it track
process and threads independently regressed a few gdb.multi/*.exp
tests for aarch64-linux.
We started seeing the following internal error for
gdb.multi/multi-target-continue.exp for example:
Starting program: binutils-gdb/gdb/testsuite/outputs/gdb.multi/multi-target-continue/multi-target-continue ^M
Error in re-setting breakpoint 2: Remote connection closed^M
../../../repos/binutils-gdb/gdb/thread.c:85: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.^M
A problem internal to GDB has been detected,^M
further debugging may prove unreliable.
A backtrace looks like:
#0 thread_regcache_data (thread=thread@entry=0x0) at ../../../repos/binutils-gdb/gdbserver/inferiors.cc:120
#1 0x0000aaaaaaabf0e8 in get_thread_regcache (thread=0x0, fetch=fetch@entry=0) at ../../../repos/binutils-gdb/gdbserver/regcache.cc:31
#2 0x0000aaaaaaad785c in is_64bit_tdesc () at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:194
#3 0x0000aaaaaaad8a48 in aarch64_target::sw_breakpoint_from_kind (this=<optimized out>, kind=4, size=0xffffffffef04) at ../../../repos/binutils-gdb/gdbserver/linux-aarch64-low.cc:3226
#4 0x0000aaaaaaabe220 in bp_size (bp=0xaaaaaab6f3d0) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:226
#5 check_mem_read (mem_addr=187649984471104, buf=buf@entry=0xaaaaaab625d0 "\006", mem_len=mem_len@entry=56) at ../../../repos/binutils-gdb/gdbserver/mem-break.cc:1862
#6 0x0000aaaaaaacc660 in read_inferior_memory (memaddr=<optimized out>, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/target.cc:93
#7 0x0000aaaaaaac3d9c in gdb_read_memory (len=56, myaddr=0xaaaaaab625d0 "\006", memaddr=187649984471104) at ../../../repos/binutils-gdb/gdbserver/server.cc:1071
#8 gdb_read_memory (memaddr=187649984471104, myaddr=0xaaaaaab625d0 "\006", len=56) at ../../../repos/binutils-gdb/gdbserver/server.cc:1048
#9 0x0000aaaaaaac82a4 in process_serial_event () at ../../../repos/binutils-gdb/gdbserver/server.cc:4307
#10 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4520
#11 0x0000aaaaaaafbcd0 in gdb_wait_for_event (block=block@entry=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:700
#12 0x0000aaaaaaafc0b0 in gdb_wait_for_event (block=1) at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:596
#13 gdb_do_one_event () at ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:237
#14 0x0000aaaaaaacacb0 in start_event_loop () at ../../../repos/binutils-gdb/gdbserver/server.cc:3518
#15 captured_main (argc=4, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:3998
#16 0x0000aaaaaaab66dc in main (argc=<optimized out>, argv=<optimized out>) at ../../../repos/binutils-gdb/gdbserver/server.cc:4084
This sequence of functions is invoked due to a series of conditions:
1 - The probe-based breakpoint mechanism failed (for some reason) so ...
2 - ... gdbserver has to know what type of architecture it is dealing
with so it can pick the right breakpoint kind, so it wants to
check if we have a 64-bit target.
3 - To determine the size of a register, we currently fetch the
current thread's register cache, and the current thread pointer
is now nullptr.
In #3, the current thread is nullptr because gdb_read_memory clears it
on purpose, via set_desired_process, exactly to expose code relying on
the current thread when it shouldn't. It was always possible to end
up in this situation (when the current thread exits), but it was
harder to reproduce before.
This commit fixes it by tweaking is_64bit_tdesc to look at the current
process's tdesc instead of the current thread's tdesc.
Note that the thread's tdesc is itself filled from the process's
tdesc, so this should be equivalent:
struct regcache *
get_thread_regcache (struct thread_info *thread, int fetch)
{
struct regcache *regcache;
regcache = thread_regcache_data (thread);
...
if (regcache == NULL)
{
struct process_info *proc = get_thread_process (thread);
gdb_assert (proc->tdesc != NULL);
regcache = new_register_cache (proc->tdesc);
set_thread_regcache_data (thread, regcache);
}
...
Change-Id: Ibc809d7345e70a2f058b522bdc5cdbdca97e2cdc
start_remote_1 calls remote_check_symbols after things are set up to
give the remote side a chance to look up symbols. One call to
remote_check_symbols sets the "general thread", if needed, and sends one
qSymbol packet. However, a remote target could have more than one
process on initial connection, and this would send a qSymbol for only
one of these processes.
Change it to iterate on all the target's inferiors and send a qSymbol
packet for each one.
I tested this by changing gdbserver to spawn two processes on startup:
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 33c42714e72..9b682e9f85f 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -3939,6 +3939,7 @@ captured_main (int argc, char *argv[])
/* Wait till we are at first instruction in program. */
target_create_inferior (program_path.get (), program_args);
+ target_create_inferior (program_path.get (), program_args);
/* We are now (hopefully) stopped at the first instruction of
the target process. This assumes that the target process was
Instead of hacking GDBserver, it should also be possible to test this by
starting manually two inferiors on an "extended-remote" connection,
disconnecting from GDBserver (with the disconnect command), and
re-connecting.
I was able to see qSymbol being sent for each inferior:
[remote] Sending packet: $Hgp828dc.828dc#1f
[remote] Packet received: OK
[remote] Sending packet: $qSymbol::#5b
[remote] Packet received: qSymbol:6764625f6167656e745f6764625f74705f686561705f627566666572
[remote] Sending packet: $qSymbol::6764625f6167656e745f6764625f74705f686561705f627566666572#1e
[remote] Packet received: qSymbol:6e70746c5f76657273696f6e
[remote] Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d
[remote] Packet received: OK
[remote] Sending packet: $Hgp828dd.828dd#21
[remote] Packet received: OK
[remote] Sending packet: $qSymbol::#5b
[remote] Packet received: qSymbol:6764625f6167656e745f6764625f74705f686561705f627566666572
[remote] Sending packet: $qSymbol::6764625f6167656e745f6764625f74705f686561705f627566666572#1e
[remote] Packet received: qSymbol:6e70746c5f76657273696f6e
[remote] Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d
[remote] Packet received: OK
Note that there would probably be more work to be done to fully support
this scenario, more things that need to be done for each discovered
inferior instead of just for one.
Change-Id: I21c4ecf6367391e2e389b560f0b4bd906cf6472f
Commit 152a174956 ("gdb: prune inferiors at end of
fetch_inferior_event, fix intermittent failure of
gdb.threads/fork-plus-threads.exp") broke some tests with the
native-gdbserver board, such as:
(gdb) PASS: gdb.base/step-over-syscall.exp: detach-on-fork=off: follow-fork=child: break cond on target : vfork: break marker
continue^M
Continuing.^M
terminate called after throwing an instance of 'gdb_exception_error'^M
I can manually reproduce the issue by running (just the commands that
the test does as a one liner):
$ ./gdb -q --data-directory=data-directory \
testsuite/outputs/gdb.base/step-over-syscall/step-over-vfork \
-ex "tar rem | ../gdbserver/gdbserver - testsuite/outputs/gdb.base/step-over-syscall/step-over-vfork" \
-ex "b main" \
-ex c \
-ex "d 1" \
-ex "set displaced-stepping off" \
-ex "b *0x7ffff7d7ac5a if main == 0" \
-ex "set detach-on-fork off" \
-ex "set follow-fork-mode child" \
-ex c \
-ex "inferior 1" \
-ex "b marker" \
-ex c
... where 0x7ffff7d7ac5a is the exact address of the vfork syscall
(which can be found by looking at gdb.log).
The important part of the above is that a vfork syscall creates inferior
2, then inferior 2 executes until exit, then we switch back to inferior
1 and try to resume it.
The uncaught exception happens here:
#4 0x00005596969d81a9 in error (fmt=0x559692da9e40 "Cannot execute this command while the target is running.\nUse the \"interrupt\" command to stop the target\nand then try again.")
at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:43
#5 0x0000559695af6f66 in remote_target::putpkt_binary (this=0x617000038080, buf=0x559692da4380 "qSymbol::", cnt=9) at /home/simark/src/binutils-gdb/gdb/remote.c:9560
#6 0x0000559695af6aaf in remote_target::putpkt (this=0x617000038080, buf=0x559692da4380 "qSymbol::") at /home/simark/src/binutils-gdb/gdb/remote.c:9518
#7 0x0000559695ab50dc in remote_target::remote_check_symbols (this=0x617000038080) at /home/simark/src/binutils-gdb/gdb/remote.c:5141
#8 0x0000559695b3cccf in remote_new_objfile (objfile=0x0) at /home/simark/src/binutils-gdb/gdb/remote.c:14600
#9 0x0000559693bc52a9 in std::__invoke_impl<void, void (*&)(objfile*), objfile*> (__f=@0x61b0000167f8: 0x559695b3cb1d <remote_new_objfile(objfile*)>) at /usr/include/c++/11.2.0/bits/invoke.h:61
#10 0x0000559693bb2848 in std::__invoke_r<void, void (*&)(objfile*), objfile*> (__fn=@0x61b0000167f8: 0x559695b3cb1d <remote_new_objfile(objfile*)>) at /usr/include/c++/11.2.0/bits/invoke.h:111
#11 0x0000559693b8dddf in std::_Function_handler<void (objfile*), void (*)(objfile*)>::_M_invoke(std::_Any_data const&, objfile*&&) (__functor=..., __args#0=@0x7ffe0bae0590: 0x0) at /usr/include/c++/11.2.0/bits/std_function.h:291
#12 0x00005596956374b2 in std::function<void (objfile*)>::operator()(objfile*) const (this=0x61b0000167f8, __args#0=0x0) at /usr/include/c++/11.2.0/bits/std_function.h:560
#13 0x0000559695633c64 in gdb::observers::observable<objfile*>::notify (this=0x55969ef5c480 <gdb::observers::new_objfile>, args#0=0x0) at /home/simark/src/binutils-gdb/gdb/../gdbsupport/observable.h:150
#14 0x0000559695df6cc2 in clear_symtab_users (add_flags=...) at /home/simark/src/binutils-gdb/gdb/symfile.c:2873
#15 0x000055969574c263 in program_space::~program_space (this=0x6120000c8a40, __in_chrg=<optimized out>) at /home/simark/src/binutils-gdb/gdb/progspace.c:154
#16 0x0000559694fc086b in delete_inferior (inf=0x61700003bf80) at /home/simark/src/binutils-gdb/gdb/inferior.c:205
#17 0x0000559694fc341f in prune_inferiors () at /home/simark/src/binutils-gdb/gdb/inferior.c:390
#18 0x0000559695017ada in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4293
#19 0x0000559694f629e6 in inferior_event_handler (event_type=INF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.c:41
#20 0x0000559695b3b0e3 in remote_async_serial_handler (scb=0x6250001ef100, context=0x6170000380a8) at /home/simark/src/binutils-gdb/gdb/remote.c:14466
#21 0x0000559695c59eb7 in run_async_handler_and_reschedule (scb=0x6250001ef100) at /home/simark/src/binutils-gdb/gdb/ser-base.c:138
#22 0x0000559695c5a42a in fd_event (error=0, context=0x6250001ef100) at /home/simark/src/binutils-gdb/gdb/ser-base.c:189
#23 0x00005596969d9ebf in handle_file_event (file_ptr=0x60700005af40, ready_mask=1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:574
#24 0x00005596969da7fa in gdb_wait_for_event (block=0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:700
#25 0x00005596969d8539 in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212
If I enable "set debug infrun" just before the last continue, we see:
(gdb) continue
Continuing.
[infrun] clear_proceed_status_thread: 965604.965604.0
[infrun] proceed: enter
[infrun] proceed: addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT
[infrun] scoped_disable_commit_resumed: reason=proceeding
[infrun] start_step_over: enter
[infrun] start_step_over: stealing global queue of threads to step, length = 0
[infrun] operator(): step-over queue now empty
[infrun] start_step_over: exit
[infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [965604.965604.0] at 0x7ffff7d7ac5c
[infrun] do_target_resume: resume_ptid=965604.0.0, step=0, sig=GDB_SIGNAL_0
[infrun] prepare_to_wait: prepare_to_wait
[infrun] reset: reason=proceeding
[infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target remote
[infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target remote
[infrun] proceed: exit
[infrun] fetch_inferior_event: enter
[infrun] scoped_disable_commit_resumed: reason=handling event
[infrun] do_target_wait: Found 2 inferiors, starting at #1
[infrun] random_pending_event_thread: None found.
[infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) =
[infrun] print_target_wait_results: 965604.965604.0 [Thread 965604.965604],
[infrun] print_target_wait_results: status->kind = VFORK_DONE
[infrun] handle_inferior_event: status->kind = VFORK_DONE
[infrun] context_switch: Switching context from 0.0.0 to 965604.965604.0
[infrun] handle_vfork_done: not waiting for a vfork-done event
[infrun] start_step_over: enter
[infrun] start_step_over: stealing global queue of threads to step, length = 0
[infrun] operator(): step-over queue now empty
[infrun] start_step_over: exit
[infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [965604.965604.0] at 0x7ffff7d7ac5c
[infrun] do_target_resume: resume_ptid=965604.0.0, step=0, sig=GDB_SIGNAL_0
[infrun] prepare_to_wait: prepare_to_wait
[infrun] reset: reason=handling event
[infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target remote
[infrun] maybe_call_commit_resumed_all_targets: calling commit_resumed for target remote
terminate called after throwing an instance of 'gdb_exception_error'
What happens is:
- After doing the "continue" on inferior 1, the remote target gives us
a VFORK_DONE event. The core ignores it and resumes inferior 1.
- Since prune_inferiors is now called after each handled event, in
fetch_inferior_event, it is called after we handled that VFORK_DONE
event and resumed inferior 1.
- Inferior 2 is pruned, which (see backtrace above) causes its program
space to be deleted, which clears the symtabs for that program space,
which calls the new_objfile observable and remote_new_objfile
observer (with a nullptr objfile, to indicate that the previously
loaded symbols have been discarded), which calls
remote_check_symbols.
remote_check_symbols is the function that sends the qSymbol packet, to
let the remote side ask for symbol addresses. The problem is that the
remote target is working in all-stop / sync mode and is currently
resumed. It has sent a vCont packet to resume the target and is waiting
for a stop reply. It can't send any packets in the mean time. That
causes the exception to be thrown.
This wasn't a problem before, when prune_inferiors was called in
normal_stop, because it was always called at a time the target was not
resumed.
An important observation here is that the new_objfile observable is
invoked for a change in inferior 2's program space (inferior 2's program
space is the current program space). Inferior 2 isn't bound to any
process on the remote side (it has exited, that's why it's being
pruned). It doesn't make sense to try to send a qSymbol packet for a
process that doesn't exist on the remote side. remote_check_symbols
actually attempts to avoid that:
/* The remote side has no concept of inferiors that aren't running
yet, it only knows about running processes. If we're connected
but our current inferior is not running, we should not invite the
remote target to request symbol lookups related to its
(unrelated) current process. */
if (!target_has_execution ())
return;
The problem here is that while inferior 2's program space is the current
program space, inferior 1 is the current inferior. So the check above
passes, since inferior has execution. We therefore try to send a
qSymbol packet for inferior 1 in reaction to a change in inferior 2's
program space, that's wrong.
This exposes a conceptual flaw in remote_new_objfile. The "new_objfile"
event concerns a specific program space, which can concern multiple
inferiors, as inferiors can share a program space. We shouldn't
consider the current inferior at all, but instead all inferiors bound to
the affected program space. Especially since the current inferior can
be unrelated to the current program space at that point.
To be clear, we are in this state because ~program_space sets itself as
the current program space, but there is no more inferior having that
program space to switch to, inferior 2 has already been unlinked.
To fix this, make remote_new_objfile iterate on all inferiors bound to
the affected program space. Remove the target_has_execution check from
remote_check_symbols, replace it with an assert. All callers must
ensure that the current inferior has execution before calling it.
Change-Id: Ica643145bcc03115248290fd310cadab8ec8371c
As before, on sufficiently old glibc this conflicts with a global
identifier in the library headers. While there also zap the unusual
padding by blanks.
As already done for PowerPC64, fix dynamic relocs for absolute symbols.
The patch also tidies the dynamic reloc handling code in check_relocs,
removing leftover comments and code from when check_relocs was called
as each object file was read in.
bfd/
* elf32-ppc.c (ppc_elf_check_relocs): Set isym and ifunc earlier.
Rearrange tests for dynamic relocs, handling absolute symbols.
(allocate_dynrelocs): Don't allocate dynamic relocs for locally
defined absolute symbols.
(ppc_elf_size_dynamic_sections): Similarly.
(ppc_elf_relocate_section): Similarly.
ld/
* testsuite/ld-powerpc/abs32-pie.d,
* testsuite/ld-powerpc/abs32-pie.r,
* testsuite/ld-powerpc/abs32-reloc.s,
* testsuite/ld-powerpc/abs32-shared.d,
* testsuite/ld-powerpc/abs32-shared.r,
* testsuite/ld-powerpc/abs32-static.d,
* testsuite/ld-powerpc/abs32-static.r: New tests.
* testsuite/ld-powerpc/powerpc.exp: Run them.
FreeBSD's kernel has recently added PT_GETREGSET and PT_SETREGSET
operations to fetch a register set named by an ELF note type. These
helper routines provide helpers to check for a register set's
existence, fetch registers for a register set, and store registers to
a register set.
The recent commit 421490af33 ("gdbserver/linux: Access memory even
if threads are running") caused a regression in
gdb.threads/access-mem-running-thread-exit.exp with gdbserver, which I
somehow missed. Like so:
(gdb) print global_var
Cannot access memory at address 0x555555558010
(gdb) FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: access mem (print global_var after writing, inf=2, iter=1)
The problem starts with GDB telling GDBserver to select a thread, via
the Hg packet, which GDBserver complies with, then that thread exits,
and GDB, without knowing the thread is gone, tries to write to memory,
through the context of the previously selected Hg thread.
GDBserver's GDB-facing memory access routines, gdb_read_memory and
gdb_write_memory, call set_desired_thread to make GDBserver re-select
the thread that GDB has selected with the Hg packet. Since the thread
is gone, set_desired_thread returns false, and the memory access
fails.
Now, to access memory, it doesn't really matter which thread is
selected. All we should need is the target process. Even if the
thread that GDB previously selected is gone, and GDB does not yet know
about that exit, it shouldn't matter, GDBserver should still know
which process that thread belonged to.
Fix this by making GDBserver track the current process separately,
like GDB also does. Add a new set_desired_process routine that is
similar to set_desired_thread, but just sets the current process,
leaving the current thread as NULL. Use it in the GDB-facing memory
read and write routines, to avoid failing if the selected thread is
gone, but the process is still around.
Change-Id: I4ff97cb6f42558efbed224b30d5c71f6112d44cd
When testing gdb.threads/access-mem-running-thread-exit.exp with
--target_board=native-extended-gdbserver, we get:
Running gdb.threads/access-mem-running-thread-exit.exp ...
FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: second inferior: runto: run to main
WARNING: Timed out waiting for EOF in server after monitor exit
=== gdb Summary ===
# of expected passes 3
# of unexpected failures 1
# of unsupported tests 1
The problem is that the testcase spawns a second inferior with
-no-connection, and then runto_main does "run", which fails like so:
(gdb) run
Don't know how to run. Try "help target".
(gdb) FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: second inferior: runto: run to main
That "run" above failed because native-extended-gdbserver forces "set
auto-connect-native-target off", to prevent testcases from mistakenly
running programs with the native target, which would exactly be the
case here.
Fix this by letting the second inferior share the first inferior's
connection everywhere except on targets that do reload on run (e.g.,
--target_board=native-gdbserver).
Change-Id: Ib57105a238cbc69c57220e71261219fa55d329ed
While working on this patch:
https://sourceware.org/pipermail/gdb-patches/2022-January/185109.html
I found it really useful to print the executing/resumed status of all
threads (or all threads in a particular inferior) at various
places (e.g. when a new inferior is started, when GDB attaches, etc).
This debug was originally part of the above patch, but I wanted to
rewrite this as a separate patch and move the code into a new function
in infrun.h, which is what this patch does.
Unless 'set debug infrun on' is in effect, then there should be no
user visible changes after this commit.
It is not necessary to pass an empty string to mi_gdb_start, passing
the empty string is equivalent to passing no arguments, which is what
we do everywhere else (that we don't need to specify an actual
argument).
The only place we use 'mi_gdb_start ""' is in
gdb.mi/mi-break-qualified.exp, so in this commit I just replace that
with a call to 'mi_gdb_start' - just for consistency.
There should be no change in what is tested after this commit.
After this previous commit I was thinking about the API of
mi_gdb_start. I felt that the idea of passing flags as separate
arguments and using 'args' to gather these into a list, though clever,
was not an intuitive API.
In this commit I modify mi_gdb_start so that it expects a single
argument, which should be a list of flags. Thus, where we previously
would have said:
mi_gdb_start separate-mi-tty separate-inferior-tty
We would now say:
mi_gdb_start { separate-mi-tty separate-inferior-tty }
However, it turns out we never actually call mi_gdb_start passing two
arguments in this way at all. We do in some places do this:
mi_gdb_start separate-inferior-tty
But that's fine, a single string like this works equally well as a
single item list, so this will not need updating.
There is also one place where we do this:
eval mi_gdb_start $start_ops
where $start_ops is a list that might contains 0, 1, or 2 items. The
eval here is used to expand the $start_ops list so mi_gdb_start sees
the list contents as separate arguments. In this case we just need to
drop the use of eval.
I think that the new API is more intuitive, but others might
disagree, in which case I can drop this change.
There should be no change in what is tested after this commit.
When running with the native-extended-gdbserver board, I currently see
one failure in gdb.mi/mi-exec-run.exp:
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=separate: mi=separate: force-fail=0: breakpoint hit reported on console (timeout)
In this test the MI interface should be started in a separate tty,
which means we should have a CLI tty and an MI tty, however, this is
not happening. Instead GDB is just started in MI mode and there is no
CLI tty.
The test script tries to switch between the CLI an MI terminals and
look for some expected output on each, however, as there is no CLI
terminal the expected output never arrives, and the test times out.
It turns out that this is not a GDB problem, rather, this is an issue
with argument passing within the test script.
The proc default_mi_gdb_start expects to take a set of flags (strings)
as arguments, each of flag is expected to be a separate argument. The
default_mi_gdb_start proc collects all its arguments into a list using
the special 'args' parameter name, and then iterates over this list to
see which flags were passed.
In mi_gdb_start, which forwards to default_mi_gdb_start, the arguments
are also gathered into the 'args' parameter list, but are then
expanded back to be separate arguments using the eval trick, i.e.:
proc mi_gdb_start { args } {
return [eval default_mi_gdb_start $args]
}
This ensures that when we arrive in default_mi_gdb_start each flag is
a separate argument, rather than appearing as a single list containing
all arguments.
When using the native-extended-gdbserver board however, the file
boards/native-extended-gdbserver.exp is loaded, and this file replaces
the default mi_gdb_start with its own version.
This new mi_gdb_start also gathers the arguments into an 'args' list,
but forgets to expand the arguments out using the eval trick.
As a result, when using the native-extended-gdbserver board, by the
time we get to default_mi_gdb_start, we end up with the args list
containing a single item, which is a list containing all the arguments
the user passed.
What this means is that if the user passes two arguments, then, in
default_mi_gdb_start, instead of seeing two separate arguments, we see
a single argument made by concatenating the two arguments together.
The only place this is a problem is in the test mi-exec-run.exp,
which (as far as I can see) is the only test where we might try to
pass both arguments at the same time. Currently we think we passed
both arguments to mi_gdb_start, but mi_gdb_start behaves as if no
arguments were passed.
This commit fixes the problem by making use of the eval trick within
the native-extended-gdbserver version of mi_gdb_start. After this,
the FAIL listed at the top of this message is resolved.
When running the gdb.mi/mi-exec-run.exp test using the
native-extended-gdbserver I see failures like this:
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=main: mi=main: force-fail=1: run failure detected
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=main: mi=separate: force-fail=1: run failure detected
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=separate: mi=separate: force-fail=1: run failure detected
There's a race condition here, so you might see a slightly different
set of failures, but I always see some from the 'run failure detected'
test.
NOTE: I also see an additional test failure:
FAIL: gdb.mi/mi-exec-run.exp: inferior-tty=separate: mi=separate: force-fail=0: breakpoint hit reported on console (timeout)
but that is a completely different issue, and is not being addressed
in this commit.
The problem for the 'run failure detected' test is that we end up
in gdb_expect looking for output from two spawn-ids, one from
gdbserver, and one from gdb. We're looking for one output pattern
from each spawn-id, and for the test to pass we need to see both
patterns.
Now, if gdb exits then this is a test failure (this would indicate gdb
crashing, which is bad), so we have an eof pattern associated with
the gdb spawn-id.
However, in this particular test we expect gdbserver to fail to
execute the binary (the test binary is set non-executable), and so we
get an error message from gdbserver (which matches the pattern), and
then gdbserver exits, this is expected.
The problem is that after spotting the pattern from gdbserver, we
often see the eof from gdbserver before we see the pattern from gdb.
If this happens then we drop out of the gdb_expect without ever seeing
the pattern from gdb, and fail the test.
In this commit, I place the spawn-id of gdbserver into a global
variable, and then use this global variable as the -i option within
the gdb_expect.
Now, once we have seen the expected pattern on the gdbserver spawn-id,
the global variable is cleared. After this the gdb_expect no longer
checks the gdbserver spawn-id for additional output, and so never sees
the eof event. This leaves the gdb_expect running, which allows the
pattern from gdb to be seen, and for the test to pass.
I now see no failures relating to 'run failure detected'.
Starting with gcc 12.1 / gcc 11.3, for test-case gdb.cp/align.exp we run into:
...
align.cc:29:23: error: invalid application of 'alignof' to a void type^M
29 | unsigned a_void = alignof (void);^M
| ^~~~~~~~~~~~~~^M
...
Fix this by using __alignof__ instead.
Tested on x86_64-linux, with gcc 7.5.0, gcc 12.1 and clang 12.0.1.
Currently debuginfod is disabled when the string of server URLs
is unset or set to be the empty string (via the $DEBUGINFOD_URLS
environment variable or the 'set debuginfod urls' gdb command).
Extend this functionality so that a whitespace-only URL also disables
debuginfod.
Modify a testcase to verify that a whitespace-only URL disables
debuginfod.
The type_wanted value, passed down to the create_sals_from_location
callback, is never used. Remove it.
Change-Id: Ic363ee13f6af593a3e875ff7fe46de130cdc190c
Update the gnulib import to fixes these issues:
- GDB build with clang + glibc < 2.33.
https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=d6a07b4dc21b3118727743142c678858df442853https://lists.gnu.org/archive/html/bug-gnulib/2022-04/msg00072.html
With glibc < 2.33, gnulib (since relatively recently) enables a
replacement for free (see gnulib/import/m4/free.m4). In that path,
clang shows this error:
make[2]: Entering directory '/home/smarchi/build/binutils-gdb-clang/gdbsupport'
CXX agent.o
In file included from /home/smarchi/src/binutils-gdb/gdbsupport/agent.cc:20:
In file included from /home/smarchi/src/binutils-gdb/gdbsupport/common-defs.h:95:
../gnulib/import/string.h:636:19: error: exception specification in declaration does not match previous declaration
_GL_EXTERN_C void free (void *) throw ();
^
../gnulib/import/stdlib.h:737:17: note: expanded from macro 'free'
# define free rpl_free
^
../gnulib/import/stdlib.h:739:1: note: previous declaration is here
_GL_FUNCDECL_RPL (free, void, (void *ptr));
^
../gnulib/import/sys/select.h:251:23: note: expanded from macro '_GL_FUNCDECL_RPL'
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
^
<scratch space>:139:1: note: expanded from here
rpl_free
^
The gnulib commit mentioned fixes the exception specification of `free`.
- GDB build on RHEL 7:
CC libgnu_a-openat-proc.o
In file included from /usr/include/string.h:633,
from ./string.h:41,
from ../../../binutils-gdb/gnulib/import/openat-proc.c:30:
./string.h:1105:1: error: expected identifier or '(' before '__extension__'
1105 | _GL_FUNCDECL_SYS (strndup, char *,
| ^~~~~~~~~~~~~~~~
https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=84863a1c4dc8cca8fb0f6f670f67779cdd2d543bhttps://lists.gnu.org/archive/html/bug-gnulib/2022-04/msg00075.html
Change-Id: Ibd51302feece6f385d0c53e0d08921b5d95e2776