Tom de Vries [Sun, 7 Mar 2021 16:58:28 +0000 (17:58 +0100)]
[gdb/symtab] Fix element type modification in read_array_type
When running test-case gdb.fortran/function-calls.exp with target board
unix/gdb:debug_flags=-gdwarf-5, I run into:
...
(gdb) PASS: gdb.fortran/function-calls.exp: \
p derived_types_and_module_calls::pass_cart(c)
p derived_types_and_module_calls::pass_cart_nd(c_nd)^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x0000000000400f73 in derived_types_and_module_calls::pass_cart_nd \
(c=<error reading variable: Cannot access memory at address 0xc>) at \
function-calls.f90:130^M
130 pass_cart_nd = ubound(c%d,1,4)^M
The program being debugged was signaled while in a function called from GDB.^M
GDB has restored the context to what it was before the call.^M
To change this behavior use "set unwindonsignal off".^M
Evaluation of the expression containing the function^M
(derived_types_and_module_calls::pass_cart_nd) will be abandoned.^M
(gdb) FAIL: gdb.fortran/function-calls.exp: p
...
The problem originates in read_array_type, when reading a DW_TAG_array_type
with a dwarf-5 DW_TAG_generic_subrange child. This is not supported, and the
fallout of this is that rather than constructing a new array type, the code
proceeds to modify the element type.
Fix this conservatively by issuing a complaint and bailing out in
read_array_type when not being able to construct an array type, such that we
have:
...
(gdb) maint expand-symtabs function-calls.f90^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
(gdb) KFAIL: gdb.fortran/function-calls.exp: no complaints in srcfile \
(PRMS: symtab/27388)
...
Tested on x86_64-linux.
gdb/ChangeLog:
2021-03-07 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* dwarf2/read.c (read_array_type): Return NULL when not being able to
construct an array type. Add assert to ensure that element_type is
not being modified.
gdb/testsuite/ChangeLog:
2021-03-07 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* lib/gdb.exp (with_complaints): New proc, factored out of ...
(gdb_load_no_complaints): ... here.
* gdb.fortran/function-calls.exp: Add test-case.
Kevin Buettner [Wed, 24 Feb 2021 18:48:04 +0000 (11:48 -0700)]
Fix aarch64-linux-hw-point.c build problem
Due to a recent glibc header file change, the file
nat/aarch64-linux-hw-point.c no longer builds on Fedora rawhide.
An enum for PTRACE_SYSEMU is now provided by <sys/ptrace.h>. In the
past, PTRACE_SYSEMU was defined only in <asm/ptrace.h>. This is
what it looks like...
When <asm/ptrace.h> and <sys/ptrace.h> are both included in a source
file, we run into the following build problem when the former is
included before the latter:
In file included from nat/aarch64-linux-hw-point.c:26:
/usr/include/sys/ptrace.h:86:3: error: expected identifier before numeric constant
86 | PTRACE_SYSEMU = 31,
| ^~~~~~~~~~~~~
(There are more errors after this one too.)
The file builds without error when <asm/ptrace.h> is included after
<sys/ptrace.h>. I found that this is already done in
nat/aarch64-sve-linux-ptrace.h (which is included by
nat/aarch64-linux-ptrace.c).
I've tested this change on Fedora rawhide and Fedora 33, both
running on an aarch64 machine.
gdb/ChangeLog:
PR build/27536
* nat/aarch64-linux-hw-point.c: Include <asm/ptrace.h> after
<sys/ptrace.h>.
Kevin Buettner [Fri, 19 Feb 2021 05:46:58 +0000 (22:46 -0700)]
amd64-linux-siginfo.c: Adjust include order to avoid gnulib error
On Fedora rawhide, after updating to glibc-2.33, I'm seeing the
following build failure:
CXX nat/amd64-linux-siginfo.o
In file included from /usr/include/bits/sigstksz.h:24,
from /usr/include/signal.h:315,
from ../gnulib/import/signal.h:52,
from /ironwood1/sourceware-git/rawhide-gnulib/bld/../../worktree-gnulib/gdbserver/../gdb/nat/amd64-linux-siginfo.c:20:
../gnulib/import/unistd.h:663:3: error: #error "Please include config.h first."
663 | #error "Please include config.h first."
| ^~~~~
glibc-2.33 has changed signal.h to now include <bits/sigstksz.h> which,
in turn, includes <unistd.h>. For a gdb build, this causes the gnulib
version of unistd.h to be pulled in first. The build failure shown
above happens because gnulib's config.h has not been included before
the include of <signal.h>.
The fix is simple - we just rearrange the order of the header file
includes to make sure that gdbsupport/commondefs.h is included before
attempting to include signal.h. Note that gdbsupport/commondefs.h
includes <gnulib/config.h>.
Build and regression tested on Fedora 33. On Fedora rawhide, GDB
builds again.
gdb/ChangeLog:
PR build/27535
* nat/amd64-linux-siginfo.c: Include "gdbsupport/common-defs.h"
(which in turn includes <gnulib/config.h>) before include
of <signal.h>.
Tom de Vries [Fri, 5 Feb 2021 16:47:07 +0000 (17:47 +0100)]
[gdb/symtab] Handle DW_TAG_type_unit in process_psymtab_comp_unit
When running test-case gdb.cp/cpexprs-debug-types.exp with target board
unix/gdb:debug_flags=-gdwarf-5, I run into:
...
(gdb) file cpexprs-debug-types^M
Reading symbols from cpexprs-debug-types...^M
ERROR: Couldn't load cpexprs-debug-types into GDB (eof).
ERROR: Couldn't send delete breakpoints to GDB.
ERROR: GDB process no longer exists
GDB process exited with wait status 23054 exp9 0 0 CHILDKILLED SIGABRT SIGABRT
...
We're running into this abort in process_psymtab_comp_unit:
...
switch (reader.comp_unit_die->tag)
{
case DW_TAG_compile_unit:
this_cu->unit_type = DW_UT_compile;
break;
case DW_TAG_partial_unit:
this_cu->unit_type = DW_UT_partial;
break;
default:
abort ();
}
...
because reader.comp_unit_die->tag == DW_TAG_type_unit.
Simon Marchi [Thu, 4 Mar 2021 15:57:03 +0000 (10:57 -0500)]
gdb: set current thread in sparc_{fetch,collect}_inferior_registers (PR gdb/27147)
PR 27147 shows that on sparc64, GDB is unable to properly unwind:
Expected result (from GDB 9.2):
#0 0x0000000000108de4 in puts ()
#1 0x0000000000100950 in hello () at gdb-test.c:4
#2 0x0000000000100968 in main () at gdb-test.c:8
Actual result (from GDB latest git):
#0 0x0000000000108de4 in puts ()
#1 0x0000000000100950 in hello () at gdb-test.c:4
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
The first failing commit is 5b6d1e4fa4fc ("Multi-target support"). The cause
of the change in behavior is due to (thanks for Andrew Burgess for finding
this):
- inferior_ptid is no longer set on entry of target_ops::wait, whereas
it was set to something valid previously
- deep down in linux_nat_target::wait (see stack trace below), we fetch
the registers of the event thread
- on sparc64, fetching registers involves reading memory (in
sparc_supply_rwindow, see stack trace below)
- reading memory (target_ops::xfer_partial) relies on inferior_ptid
being set to the thread from which we want to read memory
This is where things go wrong:
#0 linux_nat_target::xfer_partial (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x7feffe3b000 "", writebuf=0x0, offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3697
#1 0x00000100007f5b10 in raw_memory_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:912
#2 0x00000100007f60e8 in memory_xfer_partial_1 (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1043
#3 0x00000100007f61b4 in memory_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, readbuf=0x7feffe3b000 "", writebuf=0x0, memaddr=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1072
#4 0x00000100007f6538 in target_xfer_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x7feffe3b000 "", writebuf=0x0, offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1129
#5 0x00000100007f7094 in target_read_partial (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, buf=0x7feffe3b000 "", offset=8791798050744, len=8, xfered_len=0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1375
#6 0x00000100007f721c in target_read (ops=0x10000fa2c40 <the_sparc64_linux_nat_target>, object=TARGET_OBJECT_MEMORY, annex=0x0, buf=0x7feffe3b000 "", offset=8791798050744, len=8) at /home/simark/src/binutils-gdb/gdb/target.c:1415
#7 0x00000100007f69d4 in target_read_memory (memaddr=8791798050744, myaddr=0x7feffe3b000 "", len=8) at /home/simark/src/binutils-gdb/gdb/target.c:1218
#8 0x0000010000758520 in sparc_supply_rwindow (regcache=0x10000fea4f0, sp=8791798050736, regnum=-1) at /home/simark/src/binutils-gdb/gdb/sparc-tdep.c:1960
#9 0x000001000076208c in sparc64_supply_gregset (gregmap=0x10000be3190 <sparc64_linux_ptrace_gregmap>, regcache=0x10000fea4f0, regnum=-1, gregs=0x7feffe3b230) at /home/simark/src/binutils-gdb/gdb/sparc64-tdep.c:1974
#10 0x0000010000751b64 in sparc_fetch_inferior_registers (regcache=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/sparc-nat.c:170
#11 0x0000010000759d68 in sparc64_linux_nat_target::fetch_registers (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, regcache=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/sparc64-linux-nat.c:38
#12 0x00000100008146ec in target_fetch_registers (regcache=0x10000fea4f0, regno=80) at /home/simark/src/binutils-gdb/gdb/target.c:3287
#13 0x00000100006a8c5c in regcache::raw_update (this=0x10000fea4f0, regnum=80) at /home/simark/src/binutils-gdb/gdb/regcache.c:584
#14 0x00000100006a8d94 in readable_regcache::raw_read (this=0x10000fea4f0, regnum=80, buf=0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:598
#15 0x00000100006a93b8 in readable_regcache::cooked_read (this=0x10000fea4f0, regnum=80, buf=0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:690
#16 0x00000100006b288c in readable_regcache::cooked_read<unsigned long, void> (this=0x10000fea4f0, regnum=80, val=0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:777
#17 0x00000100006a9b44 in regcache_cooked_read_unsigned (regcache=0x10000fea4f0, regnum=80, val=0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:791
#18 0x00000100006abf3c in regcache_read_pc (regcache=0x10000fea4f0) at /home/simark/src/binutils-gdb/gdb/regcache.c:1295
#19 0x0000010000507920 in save_stop_reason (lp=0x10000fc5b10) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:2612
#20 0x00000100005095a4 in linux_nat_filter_event (lwpid=520983, status=1407) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3050
#21 0x0000010000509f9c in linux_nat_wait_1 (ptid=..., ourstatus=0x7feffe3c8f0, target_options=...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3194
#22 0x000001000050b1d0 in linux_nat_target::wait (this=0x10000fa2c40 <the_sparc64_linux_nat_target>, ptid=..., ourstatus=0x7feffe3c8f0, target_options=...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3432
#23 0x00000100007f8ac0 in target_wait (ptid=..., status=0x7feffe3c8f0, options=...) at /home/simark/src/binutils-gdb/gdb/target.c:2000
#24 0x00000100004ac17c in do_target_wait_1 (inf=0x1000116d280, ptid=..., status=0x7feffe3c8f0, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3464
#25 0x00000100004ac3b8 in operator() (__closure=0x7feffe3c678, inf=0x1000116d280) at /home/simark/src/binutils-gdb/gdb/infrun.c:3527
#26 0x00000100004ac7cc in do_target_wait (wait_ptid=..., ecs=0x7feffe3c8c8, options=...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3540
#27 0x00000100004ad8c4 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:3880
#28 0x0000010000485568 in inferior_event_handler (event_type=INF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.c:42
#29 0x000001000050d394 in handle_target_event (error=0, client_data=0x0) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:4060
#30 0x0000010000ab5c8c in handle_file_event (file_ptr=0x10001207270, ready_mask=1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:575
#31 0x0000010000ab6334 in gdb_wait_for_event (block=0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:701
#32 0x0000010000ab487c in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212
#33 0x0000010000542668 in start_event_loop () at /home/simark/src/binutils-gdb/gdb/main.c:348
#34 0x000001000054287c in captured_command_loop () at /home/simark/src/binutils-gdb/gdb/main.c:408
#35 0x0000010000544e84 in captured_main (data=0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1242
#36 0x0000010000544f2c in gdb_main (args=0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1257
#37 0x00000100000c1f14 in main (argc=4, argv=0x7feffe3d548) at /home/simark/src/binutils-gdb/gdb/gdb.c:32
There is a target_read_memory call in sparc_supply_rwindow, whose return
value is not checked. That call fails, because inferior_ptid does not
contain a valid ptid, and uninitialized buffer contents is used.
Ultimately it results in a corrupt stop_pc.
target_ops::fetch_registers can be (and should remain, in my opinion)
independent of inferior_ptid, because the ptid of the thread from which
to fetch registers can be obtained from the regcache. In other words,
implementations of target_ops::fetch_registers should not rely on
inferior_ptid having a sensible value on entry.
The sparc64_linux_nat_target::fetch_registers case is special, because it calls
a target method that is dependent on the inferior_ptid value
(target_read_inferior, and ultimately target_ops::xfer_partial). So I would
say it's the responsibility of sparc64_linux_nat_target::fetch_registers to set
up inferior_ptid correctly prior to calling target_read_inferior.
This patch makes sparc64_linux_nat_target::fetch_registers (and
store_registers, since it works the same) temporarily set inferior_ptid. If we
ever make target_ops::xfer_partial independent of inferior_ptid, setting
inferior_ptid won't be necessary, we'll simply pass down the ptid as a
parameter in some way.
I chose to set/restore inferior_ptid in sparc_fetch_inferior_registers, because
I am not convinced that doing so in an inner location (in sparc_supply_rwindow
for instance) would always be correct. We have access to the ptid in
sparc_supply_rwindow (from the regcache), so we _could_ set inferior_ptid
there. However, I don't want to just set inferior_ptid, as that would make it
not desync'ed with `current_thread ()` and `current_inferior ()`. It's
preferable to use switch_to_thread instead, as that switches all the global
"current" stuff in a coherent way. But doing so requires a `thread_info *`,
and getting a `thread_info *` from a ptid requires a `process_stratum_target
*`. We could use `current_inferior()->process_target()` in
sparc_supply_rwindow for this (using target_read_memory uses the current
inferior's target stack anyway). However, sparc_supply_rwindow is also used in
the context of BSD uthreads, where a thread stratum target defines threads. I
presume the ptid in the regcache would be the ptid of the uthread, defined by
the thread stratum target (bsd_uthread_target). Using
`current_inferior()->process_target()` would look up a ptid defined by the
thread stratum target using the process stratum target. I don't think it would
give good results. So I prefer playing it safe and looking up the thread
earlier, in sparc_fetch_inferior_registers.
I added some assertions (in sparc_supply_rwindow and others) to verify
that the regcache's ptid matches inferior_ptid. That verifies that the
caller has properly set the correct global context. This would have
caught (though a failed assertion) the current problem.
This is because darwin_nat_target::kill passes a pid-only ptid to
target_mourn_inferior, with the pid of the current inferior:
target_mourn_inferior (ptid_t (inf->pid));
... which doesn't satisfy the assert in target_mourn_inferior:
gdb_assert (ptid == inferior_ptid);
The reason for this assertion is that target_mourn_inferior is a
prototype shared between GDB and GDBserver, so that shared code in
gdb/nat (used in both GDB and GDBserver) can call target_mourn_inferior.
In GDB's implementation, it is likely that some targets still rely on
inferior_ptid being set to "the current thread we are working on". So
until targets are completely decoupled from inferior_ptid (at least
their mourn_inferior implementations), we need to ensure the passed in
ptid matches inferior_ptid, to ensure the calling code called
target_mourn_inferior with the right global context.
However, I think the assert is a bit too restrictive. The
mourn_inferior operation works on an inferior, not a specific thread.
And by the time we call mourn_inferior, the threads of the inferior
don't exist anymore, the process is gone, so it doesn't really make
sense to require inferior_ptid to point a specific thread.
I looked at all the target_ops::mourn_inferior implementations, those
that read inferior_ptid only care about the pid field, which supports
the idea that only the inferior matters. Other implementations look at
the current inferior (call `current_inferior ()`).
I think it would make sense to change target_mourn_inferior to accept
only a pid rather than a ptid. It would then assert that the pid is the
same as the current inferior's pid. However, this would be a quite
involved change, so I'll keep it for later.
To fix the macOS issue immediately, I propose to relax the assert to
only compare the pids, as is done in this patch.
Another solution would obviously be to make darwin_nat_target::kill pass
inferior_ptid to target_mourn_inferior. However, the solution I propose
is more in line with where I think we want to go (passing a pid to
target_mourn_inferior).
gdb/ChangeLog:
PR gdb/26861
* target.c (target_mourn_inferior): Only compare pids in
target_mourn_inferior.
Simon Marchi [Tue, 23 Feb 2021 18:37:44 +0000 (13:37 -0500)]
gdb/dwarf: create and destroy dwarf2_per_bfd's CUs-to-expand queue
As described in the log of patch "gdb/dwarf: add assertion in
maybe_queue_comp_unit", it would happen that a call to
maybe_queue_comp_unit would enqueue a CU in the to-expand queue while
nothing up the stack was processing the queue. This is not desirable,
as items are then left lingering in the queue when we exit the
dwarf2/read code. This is an inconsistent state.
The normal case of using the queue is when we go through
dw2_do_instantiate_symtab and process_queue. As depended-on CUs are
found, they get added to the queue. process_queue expands CUs until the
queue is empty.
To catch these cases where things are enqueued while nothing up the
stack is processing the queue, change dwarf2_per_bfd::queue to be an
optional. The optional is instantiated in dwarf2_queue_guard, just
before where we call process_queue. In the dwarf2_queue_guard
destructor, the optional gets reset. Therefore, the queue object is
instantiated only when something up the stack is handling it. If
another entry point tries to enqueue a CU for expansion, an assertion
will fail and we know we have something to fix.
dwarf2_queue_guard sounds like the good place for this, as it's
currently responsible for making sure the queue gets cleared if we exit
due to an error.
This also allows asserting that when age_comp_units or remove_all_cus
run, the queue is not instantiated, and gives us one more level of
assurance that we won't free the DIEs of a CU that is in the
CUs-to-expand queue.
gdb/ChangeLog:
PR gdb/26828
* dwarf2/read.c (dwarf2_queue_guard) <dwarf2_queue_guard>:
Instantiate queue.
(~dwarf2_queue_guard): Clear queue.
(queue_comp_unit): Assert that queue is
instantiated.
(process_queue): Adjust.
* dwarf2/read.h (struct dwarf2_per_bfd) <queue>: Make optional.
Simon Marchi [Tue, 23 Feb 2021 17:07:10 +0000 (12:07 -0500)]
gdb/dwarf: don't enqueue CU in maybe_queue_comp_unit if already expanded
The previous commit log described how items could be left lingering in
the dwarf2_per_bfd::queue and how that could cause trouble.
This patch fixes the issue by changing maybe_queue_comp_unit so that it
doesn't put a CU in the to-expand queue if that CU is already expanded.
This will make it so that when dwarf2_fetch_die_type_sect_off calls
follow_die_offset and maybe_queue_comp_unit, it won't enqueue the target
CU, because it will see the CU is already expanded.
This assumes that if a CU is dwarf2_fetch_die_type_sect_off's target CU,
it will have previously been expanded. I think it is the case, but I
can't be 100% sure. If that's not true, the assertions added in the
following patch will catch it, and it means we'll have to re-think a bit
more how things work (it wouldn't be well handled at all today anyway).
This fixes something else in maybe_queue_comp_unit that looks wrong.
Imagine the DIEs of a CU are loaded in memory, but that CU is not
expanded. In that case, maybe_queue_comp_unit will use this early
return:
/* If the compilation unit is already loaded, just mark it as
used. */
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu != nullptr)
{
cu->last_used = 0;
return 0;
}
... so the CU won't be queued for expansion. Whether the DIEs of a CU
are loaded in memory and whether that CU is expanded are two orthogonal
things, but that function appears to mix them. So, move the queuing
above that check / early return, so that if the CU's DIEs are loaded in
memory but the CU is not expanded yet, it gets enqueued.
I tried to improve maybe_queue_comp_unit's documentation to clarify what
the return value means. By clarifying this, I noticed that two callers
(follow_die_offset and follow_die_sig_1) access the CU's DIEs after
calling maybe_queue_comp_unit, only relying on maybe_queue_comp_unit's
return value to tell whether DIEs need to be loaded first or not. As
explained in the new comment, this is problematic:
maybe_queue_comp_unit's return value doesn't tell whether DIEs are
currently loaded, it means whether maybe_queue_comp_unit requires the
caller to load them. If the CU is already expanded but the DIEs to have
been freed, maybe_queue_comp_unit returns 0, meaning "I don't need you
to load the DIEs". So if these two functions (follow_die_offset and
follow_die_sig_1) need to access the DIEs in any case, for their own
usage, they should make sure to load them if they are not loaded
already. I therefore added an extra check to the condition they use,
making it so they will always load the DIEs if they aren't already.
From what I found, other callers don't care for the CU's DIEs, they call
maybe_queue_comp_unit to ensure the CU gets expanded eventually, but
don't care for it after that.
gdb/ChangeLog:
PR gdb/26828
* dwarf2/read.c (maybe_queue_comp_unit): Check if CU is expanded
to decide whether or not to enqueue it for expansion.
(follow_die_offset, follow_die_sig_1): Ensure we load the DIEs
after calling maybe_queue_comp_unit.
This patch fixes a segfault seen when attaching to a process on Solaris.
The steps leading to the segfault are:
- procfs_target::attach calls do_attach, at this point the inferior's
process slot in the target stack is empty.
- do_attach adds a thread with `add_thread (&the_procfs_target, ptid)`
- in add_thread_silent, the passed target (&the_procfs_target) is
passed to find_inferior_ptid
- find_inferior_ptid returns nullptr, as there is no inferior with this
ptid that has &the_procfs_target as its process target
- the nullptr `inf` is passed to find_thread_ptid, which dereferences
it, causing a segfault
- back in procfs_target::attach, after do_attach, we push the
the_procfs_target on the inferior's target stack, although we never
reach this because the segfault happens before.
To fix this, I think we need to do the same as is done in
inf_ptrace_target::attach: push the target early and unpush it in case
the attach fails (and keep it if the attach succeeds).
Implement it by moving target_unpush_up to target.h, so it can be
re-used here. Make procfs_target::attach use it. Note that just like
is mentioned in inf_ptrace_target::attach, we should push the target
before calling target_pid_to_str, so that calling target_pid_to_str ends
up in procfs_target::pid_to_str.
Tested by trying to attach on a process on gcc211 on the gcc compile
farm.
gdb/ChangeLog:
PR gdb/27435
* inf-ptrace.c (struct target_unpusher): Move to target.h.
(target_unpush_up): Likewise.
* procfs.c (procfs_target::attach): Push target early. Use
target_unpush_up to unpush target in case of error.
* target.h (struct target_unpusher): Move here.
(target_unpush_up): Likewise.
On a system with gcc-4.8 (CentOS 7.x), fails with:
--------8<---------
../../gdb/arch/arc.c:117:43: required from here
/usr/include/c++/4.8.2/bits/hashtable_policy.h:195:39: error: no matching
function for call to 'std::pair<const arc_arch_features, const
std::unique_ptr<target_desc, target_desc_deleter> >::pair(const
arc_arch_features&, target_desc*&)'
: _M_v(std::forward<_Args>(__args)...) { }
^
/usr/include/c++/4.8.2/bits/hashtable_policy.h:195:39: note: candidates are:
In file included from /usr/include/c++/4.8.2/utility:70:0,
from /usr/include/c++/4.8.2/tuple:38,
from /usr/include/c++/4.8.2/functional:55,
from ../../gdb/../gdbsupport/ptid.h:35,
from ../../gdb/../gdbsupport/common-defs.h:123,
from ../../gdb/arch/arc.c:19:
/usr/include/c++/4.8.2/bits/stl_pair.h:206:9: note: template<class ...
_Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int
..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&,
std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>,
std::_Index_tuple<_Indexes2 ...>)
pair(tuple<_Args1...>&, tuple<_Args2...>&,
^
-------->8---------
The corresponding line in arc.c must use an explicit ctor:
--------8<---------
arc_lookup_target_description (...)
{
/* Add the newly created target description to the repertoire. */
- arc_tdesc_cache.emplace (features, tdesc);
+ arc_tdesc_cache.emplace (features, target_desc_up (tdesc));
return tdesc;
}
-------->8---------
See "PR gcc/96537" for more details.
Last but not least, this problem has originally been investigated
by Tom de Vries for RISCV targets (see 38f8aa06d9).
gdb/ChangeLog:
PR build/27385
* arch/arc.c (arc_lookup_target_description): Use
target_desc_up() ctor explicitly.
Here, we are at line 7. Using the "next" command leads no where.
However, setting a breakpoint on line 9 and issuing "continue" works.
Looking at the assembly instructions reveals that we're dealing with the
critical section entry code [1] that should never be interrupted, in this
case by the debugger's implicit breakpoints:
Lines 3 until 5 (inclusive) are supposed to be executed atomically.
Therefore, GDB should never (implicitly) insert a breakpoint on lines
4 and 5, else the program will try to acquire the lock again by jumping
back to line 3 and gets stuck in an infinite loop.
The solution is to make GDB aware of these patterns so it inserts
breakpoints after the sequence -- line 6 in this example.
[1]
https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/sysdeps/linux/arc/bits/atomic.h#n46
------8<-------
({ \
__typeof(oldval) prev; \
\
__asm__ __volatile__( \
"1: llock %0, [%1] \n" \
" brne %0, %2, 2f \n" \
" scond %3, [%1] \n" \
" bnz 1b \n" \
"2: \n" \
: "=&r"(prev) \
: "r"(mem), "ir"(oldval), \
"r"(newval) /* can't be "ir". scond can't take limm for "b" */\
: "cc", "memory"); \
\
prev; \
})
------>8-------
"llock" (Load Locked) loads the 32-bit word pointed by the source
operand. If the load is completed without any interruption or
exception, the physical address is remembered, in Lock Physical Address
(LPA), and the Lock Flag (LF) is set to 1. LF is a non-architecturally
visible flag and is cleared whenever an interrupt or exception takes
place. LF is also cleared (atomically) whenever another process writes
to the LPA.
"scond" (Store Conditional) will write to the destination address if
and only if the LF is set to 1. When finished, with or without a write,
it atomically copies the LF value to ZF (Zero Flag).
These two instructions together provide the mechanism for entering a
critical section. The code snippet above comes from uClibc:
-----------------------
v3 (after Tom's remarks[2]):
handle_atomic_sequence()
- no need to initialize the std::vector with "{}"
- fix typo in comments: "conditial" -> "conditional"
- add braces to the body of "if" condition because of the comment line
arc_linux_software_single_step()
- make the performance slightly more efficient by moving a few
variables after the likely "return" point.
v2 (after Simon's remarks[3]):
- handle_atomic_sequence() gets a copy of an instruction instead of
a reference.
- handle_atomic_sequence() asserts if the given instruction is an llock.
Tom de Vries [Fri, 5 Feb 2021 19:54:39 +0000 (20:54 +0100)]
[gdb/breakpoints] Handle glibc with debuginfo in create_exception_master_breakpoint
The test-case nextoverthrow.exp is failing on targets with unstripped libc.
This is a regression since commit 1940319c0ef "[gdb] Fix internal-error in
process_event_stop_test".
The problem is that this code in create_exception_master_breakpoint:
...
for (objfile *sepdebug = obj->separate_debug_objfile;
sepdebug != nullptr; sepdebug = sepdebug->separate_debug_objfile)
if (create_exception_master_breakpoint_hook (sepdebug))
...
iterates over all the separate debug object files, but fails to handle the
case that obj itself has the debug info we're looking for.
Fix this by using the separate_debug_objfiles () range instead, which does
iterate both over obj and the obj->separate_debug_objfile chain.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-05 Tom de Vries <tdevries@suse.de>
PR breakpoints/27330
* breakpoint.c (create_exception_master_breakpoint): Handle case that
glibc object file has debug info.
Simon Marchi [Tue, 2 Feb 2021 15:40:53 +0000 (10:40 -0500)]
gdb/testsuite: add test for .debug_{rng,loc}lists section without offset array
It is possible for the tables in the .debug_{rng,loc}lists sections to
not have an array of offsets. In that case, the offset_entry_count
field of the header is 0. The forms DW_FORM_{rng,loc}listx (reference
by index) can't be used with that table. Instead, the
DW_FORM_sec_offset form, which references a {rng,loc}list by direct
offset in the section, must be used. From what I saw, this is what GCC
currently produces.
Add tests for this case. I didn't see any bug related to this, I just
think that it would be nice to have coverage for this. A new
`-with-offset-array` option is added to the `table` procs, used when
generating {rng,loc}lists, to decide whether to generate the offset
array.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp (rnglists): Add -no-offset-array option to
table proc.
* gdb.dwarf2/rnglists-sec-offset.exp: Add test for
.debug_rnglists table without offset array.
* gdb.dwarf2/loclists-sec-offset.exp: Add test for
.debug_loclists table without offset array.
Simon Marchi [Tue, 2 Feb 2021 15:40:52 +0000 (10:40 -0500)]
gdb/testsuite: DWARF assembler: add context parameters to _location
The _location proc is used to assemble a location description. It needs
to know some contextual information:
- size of an address
- size of an offset (into another DWARF section)
- DWARF version
It currently get all this directly from global variables holding the
compilation unit information. This is fine because as of now, all
location descriptions are generated in the context of creating a
compilation unit. However, a subsequent patch will generate location
descriptions while generating a .debug_loclists section. _location
should therefore no longer rely on the current compilation unit's
properties.
Change it to accept these values as parameters instead of accessing the
values for the CU.
Simon Marchi [Tue, 2 Feb 2021 15:40:52 +0000 (10:40 -0500)]
gdb/testsuite: add .debug_rnglists tests
Add tests for the various issues fixed in the previous patches.
Add a new "rnglists" procedure to the DWARF assembler, to allow
generating .debug_rnglists sections. A trivial change is required to
support the DWARF 5 CU header layout.
gdb/testsuite/ChangeLog:
PR gdb/26813
* lib/dwarf.exp (_handle_DW_FORM): Handle DW_FORM_rnglistx.
(cu): Generate header for DWARF 5.
(rnglists): New proc.
* gdb.dwarf2/rnglists-multiple-cus.exp: New.
* gdb.dwarf2/rnglists-sec-offset.exp: New.
Simon Marchi [Tue, 2 Feb 2021 15:40:51 +0000 (10:40 -0500)]
gdb/dwarf: read correct rnglist/loclist header in read_{rng,loc}list_index
When loading the binary from PR 26813 in GDB, we get:
DW_FORM_rnglistx index pointing outside of .debug_rnglists offset array [in module /home/simark/build/binutils-gdb/gdb/MagicPurse]
... and the symbols fail to load.
In read_rnglist_index and read_loclist_index, we read the header
(documented in sections 7.28 and 7.29 of DWARF 5) of the CU's
contribution to the .debug_rnglists / .debug_loclists sections to
validate that the index we want to read makes sense. However, we always
read the header at the beginning of the section, rather than the header
for the contribution from which we want to read the index.
To illustrate, here's what the binary from PR 26813 contains. There are
two compile units:
The layout of the .debug_rnglists is the following:
[0x00, 0x0B]: header for CU 1's contribution
[0x0C, 0x0F]: list of offsets for CU 1 (1 element)
[0x10, 0x78]: range lists data for CU 1
[0x79, 0x84]: header for CU 2's contribution
[0x85, 0xB4]: list of offsets for CU 2 (12 elements)
[0xB5, 0xBD7]: range lists data for CU 2
The DW_AT_rnglists_base attrbute points to the beginning of the list of
offsets for that CU, relative to the start of the .debug_rnglists
section. That's right after the header for that contribution.
When we try to read the DW_AT_ranges attribute for CU 2,
read_rnglist_index reads the header for CU 1 instead of the one for CU
2. Since there's only one element in CU 1's offset list, it believes
(wrongfully) that the index 0xB is out of range.
Fix it by reading the header just before where DW_AT_rnglists_base
points to. With this patch, I am able to load GDB built with clang-11
and -gdwarf-5 in itself, with and without -readnow.
gdb/ChangeLog:
PR gdb/26813
* dwarf2/read.c (read_loclists_rnglists_header): Add
header_offset parameter and use it.
(read_loclist_index): Read header of the current contribution,
not the one at the beginning of the section.
(read_rnglist_index): Likewise.
Simon Marchi [Tue, 2 Feb 2021 15:40:51 +0000 (10:40 -0500)]
gdb/dwarf: add missing bound check to read_loclist_index
read_rnglist_index has a bound check to make sure that we don't go past
the end of the section while reading the offset, but read_loclist_index
doesn't. Add it to read_loclist_index.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Add bound check for the end
of the offset.
Simon Marchi [Tue, 2 Feb 2021 15:40:50 +0000 (10:40 -0500)]
gdb/dwarf: fix bound check in read_rnglist_index
I think this check in read_rnglist_index is wrong:
/* Validate that reading won't go beyond the end of the section. */
if (start_offset + cu->header.offset_size > rnglist_base + section->size)
error (_("Reading DW_FORM_rnglistx index beyond end of"
".debug_rnglists section [in module %s]"),
objfile_name (objfile));
The addition `rnglist_base + section->size` doesn't make sense.
rnglist_base is an offset into `section`, so it doesn't make sense to
add it to `section`'s size. `start_offset` also is an offset into
`section`, so we should just compare it to just `section->size`.
Simon Marchi [Tue, 2 Feb 2021 15:40:50 +0000 (10:40 -0500)]
gdb/dwarf: change read_loclist_index complaints into errors
Unlike read_rnglists_index, read_loclist_index uses complaints when it
detects an inconsistency (a DW_FORM_loclistx value without a
.debug_loclists section or an offset outside of the section). I really
think they should be errors, since there's no point in continuing if
this situation happens, we will likely segfault or read garbage.
gdb/ChangeLog:
* dwarf2/read.c (read_loclist_index): Change complaints into
errors.
Tom de Vries [Fri, 8 Jan 2021 10:58:41 +0000 (11:58 +0100)]
[gdb] Fix internal-error in process_event_stop_test
The function create_exception_master_breakpoint in gdb/breakpoint.c attempts
to set a master exception breakpoint in each objfile. It tries this using
a libgcc/unwind probe, and if that fails then using the
_Unwind_DebugHook symbol:
...
for (objfile *objfile : current_program_space->objfiles ())
{
/* Try using probes. */
if (/* successful */)
continue;
/* Try using _Unwind_DebugHook */
}
...
The preference scheme works ok both if the objfile has debug info, and if it's
stripped.
But it doesn't work when the objfile has a .gnu_debuglink to a .debug file
(and the .debug file is present). What happens is that:
- we first encounter objfile libgcc.debug
- we try using probes, and this fails
- so we try _Unwind_DebugHook, which succeeds
- next we encounter objfile libgcc
- we try using probes, and this succeeds.
So, we end up with a master exception breakpoint in both libgcc (using probes)
and libgcc.debug (using _Unwind_DebugHook).
This eventually causes:
...
(gdb) PASS: gdb.cp/nextoverthrow.exp: post-check - next over a throw 3
next^M
src/gdb/infrun.c:6384: internal-error: \
void process_event_stop_test(execution_control_state*): \
Assertion `ecs->event_thread->control.exception_resume_breakpoint != NULL' \
failed.^M
A problem internal to GDB has been detected,^M
further debugging may prove unreliable.^M
Quit this debugging session? (y or n) FAIL: gdb.cp/nextoverthrow.exp: next
past catch (GDB internal error)
...
To trigger this internal-error, we need to use gcc-10 or later to compile the
test-case, such that it contains the fix for gcc PR97774 - "Incorrect line
info for try/catch".
Fix this by only trying to install the master exception breakpoint in
libgcc.debug using the _Unwind_DebugHook method, if the install using probes
in libgcc failed.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-01-08 Tom de Vries <tdevries@suse.de>
PR gdb/26881
* breakpoint.c (create_exception_master_breakpoint_probe)
(create_exception_master_breakpoint_hook): Factor out
of ...
(create_exception_master_breakpoint): ... here. Only try to install
the master exception breakpoint in objfile.debug using the
_Unwind_DebugHook method, if the install using probes in objfile
failed.
Pedro Alves [Thu, 7 Jan 2021 20:41:03 +0000 (21:41 +0100)]
[gdb/remote] Fix invalid pointer in remote_async_serial_handler
On rare occasions, we run into this ERROR/UNRESOLVED on gdb-10-branch:
...
(gdb) PASS: gdb.multi/multi-target.exp: continue: non-stop=on: inferior 2
Remote debugging from host ::1, port 34088^M
Process outputs/gdb.multi/multi-target/multi-target created; pid = 8649^M
monitor exit^M
(gdb) Killing process(es): 8649^M
ERROR: GDB process no longer exists
GDB process exited with wait status 8627 exp14 0 0 CHILDKILLED SIGABRT SIGABRT
UNRESOLVED: gdb.multi/multi-target.exp: continue: non-stop=on: inferior 5
...
A trigger patch makes the crash happen all the time:
...
diff --git a/gdb/remote.c b/gdb/remote.c
index 71f814efb365..53ff8b63a1dc 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -14161,14 +14161,12 @@ remote_target::is_async_p ()
will be able to delay notifying the client of an event until the
point where an entire packet has been received. */
-static serial_event_ftype remote_async_serial_handler;
-
static void
remote_async_serial_handler (struct serial *scb, void *context)
{
- /* Don't propogate error information up to the client. Instead let
- the client find out about the error by querying the target. */
- inferior_event_handler (INF_REG_EVENT);
+ remote_state *rs = (remote_state *) context;
+
+ mark_async_event_handler (rs->remote_async_inferior_event_token);
}
static void
...
And using -fsanitizer=address we can get a more elaborate error message:
...
==7196==ERROR: AddressSanitizer: heap-use-after-free on address \
0x6170000bf258 at pc 0x000001481755 bp 0x7fff05b20840 sp 0x7fff05b20838
READ of size 8 at 0x6170000bf258 thread T0
#0 0x1481754 in std::_Hashtable<gdbarch*, std::pair<gdbarch* const,
remote_arch_state>, std::allocator<std::pair<gdbarch* const,
remote_arch_state> >, std::__detail::_Select1st, std::equal_to<gdbarch*>,
std::hash<gdbarch*>, std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,
std::__detail::_Hashtable_traits<false, false, true>
>::_M_bucket_index(unsigned long) const
/usr/include/c++/11/bits/hashtable.h:719
#1 0x147c8ab in std::_Hashtable<gdbarch*, std::pair<gdbarch* const,
remote_arch_state>, std::allocator<std::pair<gdbarch* const,
remote_arch_state> >, std::__detail::_Select1st, std::equal_to<gdbarch*>,
std::hash<gdbarch*>, std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,
std::__detail::_Hashtable_traits<false, false, true> >::find(gdbarch*
const&) /usr/include/c++/11/bits/hashtable.h:1500
#2 0x147852c in std::unordered_map<gdbarch*, remote_arch_state,
std::hash<gdbarch*>, std::equal_to<gdbarch*>,
std::allocator<std::pair<gdbarch* const, remote_arch_state> >
>::find(gdbarch* const&) /usr/include/c++/11/bits/unordered_map.h:869
#3 0x14306db in remote_state::get_remote_arch_state(gdbarch*)
src/gdb/remote.c:1203
#4 0x14309dc in remote_target::get_remote_state() src/gdb/remote.c:1232
#5 0x1470c08 in remote_async_inferior_event_handler src/gdb/remote.c:14169
#6 0xaa9f6b in check_async_event_handlers() src/gdb/async-event.c:295
#7 0x1e93ab4 in gdb_do_one_event() src/gdbsupport/event-loop.cc:194
#8 0x118f5f9 in start_event_loop src/gdb/main.c:356
#9 0x118f8ed in captured_command_loop src/gdb/main.c:416
#10 0x1192d6a in captured_main src/gdb/main.c:1253
#11 0x1192dfa in gdb_main(captured_main_args*) src/gdb/main.c:1268
#12 0x97b380 in main src/gdb/gdb.c:32
#13 0x7f550c211349 in __libc_start_main ../csu/libc-start.c:308
#14 0x97b199 in _start (build/gdb/gdb+0x97b199)
0x6170000bf258 is located 600 bytes inside of 648-byte region \
[0x6170000bf000,0x6170000bf288)
freed by thread T0 here:
#0 0x7f550f516a57 in operator delete(void*, unsigned long)
(/usr/lib64/libasan.so.6+0xaea57)
#1 0x148b1fe in extended_remote_target::~extended_remote_target()
src/gdb/remote.c:958
#2 0x143b483 in remote_target::close() src/gdb/remote.c:4074
#3 0x16cb90f in target_close(target_ops*) src/gdb/target.c:3230
#4 0x16a2635 in decref_target(target_ops*) src/gdb/target.c:557
#5 0x16a2abb in target_stack::unpush(target_ops*) src/gdb/target.c:645
#6 0x16d01ef in inferior::unpush_target(target_ops*)
src/gdb/inferior.h:356
#7 0x16a2877 in unpush_target(target_ops*) src/gdb/target.c:607
#8 0x16a2adf in unpush_target_and_assert src/gdb/target.c:655
#9 0x16a2c57 in pop_all_targets_at_and_above(strata) src/gdb/target.c:678
#10 0x1442749 in remote_unpush_target src/gdb/remote.c:5522
#11 0x1458c16 in remote_target::readchar(int) src/gdb/remote.c:9137
#12 0x145b25b in remote_target::getpkt_or_notif_sane_1(std::vector<char,
gdb::default_init_allocator<char, std::allocator<char> > >*, int, int,
int*) src/gdb/remote.c:9683
#13 0x145bc9a in remote_target::getpkt_sane(std::vector<char,
gdb::default_init_allocator<char, std::allocator<char> > >*, int)
src/gdb/remote.c:9790
#14 0x145b040 in remote_target::getpkt(std::vector<char,
gdb::default_init_allocator<char, std::allocator<char> > >*, int)
src/gdb/remote.c:9623
#15 0x145780b in remote_target::remote_read_bytes_1(unsigned long,
unsigned char*, unsigned long, int, unsigned long*) src/gdb/remote.c:8860
#16 0x145805e in remote_target::remote_read_bytes(unsigned long,
unsigned char*, unsigned long, int, unsigned long*) src/gdb/remote.c:8987
#17 0x146113a in remote_target::xfer_partial(target_object, char const*,
unsigned char*, unsigned char const*, unsigned long, unsigned long,
unsigned long*) src/gdb/remote.c:10987
#18 0x16a4004 in raw_memory_xfer_partial(target_ops*, unsigned char*,
unsigned char const*, unsigned long, long, unsigned long*)
src/gdb/target.c:918
#19 0x16a4fcf in target_xfer_partial(target_ops*, target_object, char
const*, unsigned char*, unsigned char const*, unsigned long, unsigned
long, unsigned long*) src/gdb/target.c:1156
#20 0x16a5d65 in target_read_partial src/gdb/target.c:1387
#21 0x16a5f19 in target_read(target_ops*, target_object, char const*,
unsigned char*, unsigned long, long) src/gdb/target.c:1427
#22 0x16a5666 in target_read_raw_memory(unsigned long, unsigned char*,
long) src/gdb/target.c:1260
#23 0xd22f2a in dcache_read_line src/gdb/dcache.c:336
#24 0xd232b7 in dcache_peek_byte src/gdb/dcache.c:403
#25 0xd23845 in dcache_read_memory_partial(target_ops*, dcache_struct*,
unsigned long, unsigned char*, unsigned long, unsigned long*) src/gdb/dcache.c:484
#26 0x16a47da in memory_xfer_partial_1 src/gdb/target.c:1041
#27 0x16a4a1e in memory_xfer_partial src/gdb/target.c:1084
#28 0x16a4f44 in target_xfer_partial(target_ops*, target_object,
char const*, unsigned char*, unsigned char const*, unsigned long,
unsigned long, unsigned long*) src/gdb/target.c:1141
#29 0x18203d4 in read_value_memory(value*, long, int, unsigned long,
unsigned char*, unsigned long) src/gdb/valops.c:956
previously allocated by thread T0 here:
#0 0x7f550f515c37 in operator new(unsigned long)
(/usr/lib64/libasan.so.6+0xadc37)
#1 0x14429f0 in remote_target::open_1(char const*, int, int)
src/gdb/remote.c:5562
#2 0x14405e6 in extended_remote_target::open(char const*, int)
src/gdb/remote.c:4907
#3 0x16a0f3c in open_target src/gdb/target.c:242
#4 0xc19ff5 in do_sfunc src/gdb/cli/cli-decode.c:111
#5 0xc221db in cmd_func(cmd_list_element*, char const*, int)
src/gdb/cli/cli-decode.c:2181
#6 0x16feda6 in execute_command(char const*, int) src/gdb/top.c:668
#7 0xee9dc9 in command_handler(char const*) src/gdb/event-top.c:588
#8 0xeea6a8 in command_line_handler(std::unique_ptr<char,
gdb::xfree_deleter<char> >&&) src/gdb/event-top.c:773
#9 0xee8a12 in gdb_rl_callback_handler src/gdb/event-top.c:219
#10 0x7f550f24aead in rl_callback_read_char
(/lib64/libreadline.so.7+0x31ead)
...
The problem is here in remote_async_inferior_event_handler:
...
static void
remote_async_inferior_event_handler (gdb_client_data data)
{
inferior_event_handler (INF_REG_EVENT);
The remote target (passed in the data argument) can be destroyed during the
call to inferior_event_handler. If so, the call to remote->get_remote_state
() is done using a dangling pointer.
Fix this by increasing the reference count on the remote target before calling
inferior_event_handler, such that it won't get destroyed until right before
returning from remote_async_inferior_event_handler.
Tested on x86_64-linux.
Intended for gdb-10-branch.
The problem has stopped reproducing with the trigger patch since master commit 79952e69634 "Make scoped_restore_current_thread's cdtors exception free
(RFC)". We could still apply this to master though.
gdb/ChangeLog:
2021-01-07 Pedro Alves <pedro@palves.net>
Simon Marchi <simon.marchi@polymtl.ca>
Tom de Vries <tdevries@suse.de>
PR remote/26614
* remote.c (remote_async_inferior_event_handler): Hold a strong
reference to the remote target while handling an event.
Joel Brobecker [Fri, 1 Jan 2021 07:56:12 +0000 (11:56 +0400)]
gdb/copyright.py: Also update sources in "gdbserver" and "gdbsupport"
This commit adjusts GDB's copyright.py script, following two past changes:
- gdb/gdbserver/ being move to the toplevel directory;
- gdb/common/ being renamed to gdbsupport/.
gdb/ChangeLog:
* copyright.py (get_update_list): Add "gdbserver" and "gdbsupport"
to the list of directories to update.