[1/3] Fix crash if connection drops in scoped_restore_current_thread's ctor, part 1

Message ID 20200708233125.1030-2-pedro@palves.net
State New
Headers show
Series
  • Fix crash if connection drops in scoped_restore_current_thread's ctor
Related show

Commit Message

Pedro Alves July 8, 2020, 11:31 p.m.
Running the testsuite against an Asan-enabled build of GDB makes
gdb.base/multi-target.exp expose this bug.

scoped_restore_current_thread's ctor calls get_frame_id to record the
selected frame's ID to restore later.  If the frame ID hasn't been
computed yet, it will be computed on the spot, and that will usually
require accessing the target's memory and registers, which requires
remote accesses.  If the remote connection closes while we're
computing the frame ID, the remote target exits its inferiors,
unpushes itself, and throws a TARGET_CLOSE_ERROR error.

If that happens, GDB can currently crash, here:

> ==18555==ERROR: AddressSanitizer: heap-use-after-free on address 0x621004670aa8 at pc 0x0000007ab125 bp 0x7ffdecaecd20 sp 0x7ffdecaecd10

> READ of size 4 at 0x621004670aa8 thread T0

>     #0 0x7ab124 in dwarf2_frame_this_id src/binutils-gdb/gdb/dwarf2/frame.c:1228

>     #1 0x983ec5 in compute_frame_id src/binutils-gdb/gdb/frame.c:550

>     #2 0x9841ee in get_frame_id(frame_info*) src/binutils-gdb/gdb/frame.c:582

>     #3 0x1093faa in scoped_restore_current_thread::scoped_restore_current_thread() src/binutils-gdb/gdb/thread.c:1462

>     #4 0xaee5ba in fetch_inferior_event(void*) src/binutils-gdb/gdb/infrun.c:3968

>     #5 0xaa990b in inferior_event_handler(inferior_event_type, void*) src/binutils-gdb/gdb/inf-loop.c:43

>     #6 0xea61b6 in remote_async_serial_handler src/binutils-gdb/gdb/remote.c:14161

>     #7 0xefca8a in run_async_handler_and_reschedule src/binutils-gdb/gdb/ser-base.c:137

>     #8 0xefcd23 in fd_event src/binutils-gdb/gdb/ser-base.c:188

>     #9 0x15a7416 in handle_file_event src/binutils-gdb/gdbsupport/event-loop.cc:548

>     #10 0x15a7c36 in gdb_wait_for_event src/binutils-gdb/gdbsupport/event-loop.cc:673

>     #11 0x15a5dbb in gdb_do_one_event() src/binutils-gdb/gdbsupport/event-loop.cc:215

>     #12 0xbfe62d in start_event_loop src/binutils-gdb/gdb/main.c:356

>     #13 0xbfe935 in captured_command_loop src/binutils-gdb/gdb/main.c:416

>     #14 0xc01d39 in captured_main src/binutils-gdb/gdb/main.c:1253

>     #15 0xc01dc9 in gdb_main(captured_main_args*) src/binutils-gdb/gdb/main.c:1268

>     #16 0x414ddd in main src/binutils-gdb/gdb/gdb.c:32

>     #17 0x7f590110b82f in __libc_start_main ../csu/libc-start.c:291

>     #18 0x414bd8 in _start (build/binutils-gdb/gdb/gdb+0x414bd8)


What happens is that above, we're in dwarf2_frame_this_id, just after
the dwarf2_frame_cache call.  The "cache" variable that the
dwarf2_frame_cache function returned is already stale.  It's been
released here, from within the dwarf2_frame_cache:

(top-gdb) bt
#0  reinit_frame_cache () at src/gdb/frame.c:1855
#1  0x00000000014ff7b0 in switch_to_no_thread () at src/gdb/thread.c:1301
#2  0x0000000000f66d3e in switch_to_inferior_no_thread (inf=0x615000338180) at src/gdb/inferior.c:626
#3  0x00000000012f3826 in remote_unpush_target (target=0x6170000c5900) at src/gdb/remote.c:5521
#4  0x00000000013097e0 in remote_target::readchar (this=0x6170000c5900, timeout=2) at src/gdb/remote.c:9137
#5  0x000000000130be4d in remote_target::getpkt_or_notif_sane_1 (this=0x6170000c5900, buf=0x6170000c5918, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9683
#6  0x000000000130c8ab in remote_target::getpkt_sane (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9790
#7  0x000000000130bc0d in remote_target::getpkt (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9623
#8  0x000000000130838e in remote_target::remote_read_bytes_1 (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len_units=64, unit_size=1, xfered_len_units=0x7fff6a29b9a0) at src/gdb/remote.c:8860
#9  0x0000000001308bd2 in remote_target::remote_read_bytes (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64, unit_size=1, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:8987
#10 0x0000000001311ed1 in remote_target::xfer_partial (this=0x6170000c5900, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:10988
#11 0x00000000014ba969 in raw_memory_xfer_partial (ops=0x6170000c5900, readbuf=0x6080000ad3bc "", writebuf=0x0, memaddr=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:918
#12 0x00000000014bb720 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1148
#13 0x00000000014bc3b5 in target_read_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1380
#14 0x00000000014bc593 in target_read (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64) at src/gdb/target.c:1419
#15 0x00000000014bbd4d in target_read_raw_memory (memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64) at src/gdb/target.c:1252
#16 0x0000000000bf27df in dcache_read_line (dcache=0x6060001eddc0, db=0x6080000ad3a0) at src/gdb/dcache.c:336
#17 0x0000000000bf2b72 in dcache_peek_byte (dcache=0x6060001eddc0, addr=0x7fffffffcdd8, ptr=0x6020001231b0 "") at src/gdb/dcache.c:403
#18 0x0000000000bf3103 in dcache_read_memory_partial (ops=0x6170000c5900, dcache=0x6060001eddc0, memaddr=0x7fffffffcdd8, myaddr=0x6020001231b0 "", len=8, xfered_len=0x7fff6a29bf20) at src/gdb/dcache.c:484
#19 0x00000000014bafe9 in memory_xfer_partial_1 (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1034
#20 0x00000000014bb212 in memory_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1076
#21 0x00000000014bb6b3 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, annex=0x0, readbuf=0x6020001231b0 "", writebuf=0x0, offset=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1133
#22 0x000000000164564d in read_value_memory (val=0x60f000029440, bit_offset=0, stack=1, memaddr=0x7fffffffcdd8, buffer=0x6020001231b0 "", length=8) at src/gdb/valops.c:956
#23 0x0000000001680fff in value_fetch_lazy_memory (val=0x60f000029440) at src/gdb/value.c:3764
#24 0x0000000001681efd in value_fetch_lazy (val=0x60f000029440) at src/gdb/value.c:3910
#25 0x0000000001676143 in value_optimized_out (value=0x60f000029440) at src/gdb/value.c:1411
#26 0x0000000000e0fcb8 in frame_register_unwind (next_frame=0x6210066bfde0, regnum=16, optimizedp=0x7fff6a29c200, unavailablep=0x7fff6a29c240, lvalp=0x7fff6a29c2c0, addrp=0x7fff6a29c300, realnump=0x7fff6a29c280, bufferp=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1144
#27 0x0000000000e10418 in frame_unwind_register (next_frame=0x6210066bfde0, regnum=16, buf=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1196
#28 0x0000000000f00431 in i386_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/i386-tdep.c:1969
#29 0x0000000000e39724 in gdbarch_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/gdbarch.c:3056
#30 0x0000000000c2ea90 in dwarf2_tailcall_sniffer_first (this_frame=0x6210066bfde0, tailcall_cachep=0x6210066bfee0, entry_cfa_sp_offsetp=0x0) at src/gdb/dwarf2/frame-tailcall.c:423
#31 0x0000000000c36bdb in dwarf2_frame_cache (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8) at src/gdb/dwarf2/frame.c:1198
#32 0x0000000000c36eb3 in dwarf2_frame_this_id (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8, this_id=0x6210066bfe40) at src/gdb/dwarf2/frame.c:1226

Note that remote_target::readchar in frame #3 throws
TARGET_CLOSE_ERROR after that remote_unpush_target in frame #3
returns.

The problem is that that TARGET_CLOSE_ERROR is swallowed by
value_optimized_out in frame #25.

If we fix that one, then we run into dwarf2_tailcall_sniffer_first
swallowing the exception in frame #30 too.

The attached patch fixes it by making those spots swallow fewer kinds
of errors.

gdb/ChangeLog:

	* frame-tailcall.c (dwarf2_tailcall_sniffer_first): Only swallow
	NO_ENTRY_VALUE_ERROR.
	* value.c (value_optimized_out): Only swallow OPTIMIZED_OUT_ERROR.
---
 gdb/dwarf2/frame-tailcall.c | 18 ++++++++++++++++--
 gdb/value.c                 | 13 ++++++++++++-
 2 files changed, 28 insertions(+), 3 deletions(-)

-- 
2.14.5

Comments

Simon Marchi July 9, 2020, 3:17 a.m. | #1
On 2020-07-08 7:31 p.m., Pedro Alves wrote:
> Running the testsuite against an Asan-enabled build of GDB makes

> gdb.base/multi-target.exp expose this bug.

> 

> scoped_restore_current_thread's ctor calls get_frame_id to record the

> selected frame's ID to restore later.  If the frame ID hasn't been

> computed yet, it will be computed on the spot, and that will usually

> require accessing the target's memory and registers, which requires

> remote accesses.  If the remote connection closes while we're

> computing the frame ID, the remote target exits its inferiors,

> unpushes itself, and throws a TARGET_CLOSE_ERROR error.

> 

> If that happens, GDB can currently crash, here:

> 

>> ==18555==ERROR: AddressSanitizer: heap-use-after-free on address 0x621004670aa8 at pc 0x0000007ab125 bp 0x7ffdecaecd20 sp 0x7ffdecaecd10

>> READ of size 4 at 0x621004670aa8 thread T0

>>     #0 0x7ab124 in dwarf2_frame_this_id src/binutils-gdb/gdb/dwarf2/frame.c:1228

>>     #1 0x983ec5 in compute_frame_id src/binutils-gdb/gdb/frame.c:550

>>     #2 0x9841ee in get_frame_id(frame_info*) src/binutils-gdb/gdb/frame.c:582

>>     #3 0x1093faa in scoped_restore_current_thread::scoped_restore_current_thread() src/binutils-gdb/gdb/thread.c:1462

>>     #4 0xaee5ba in fetch_inferior_event(void*) src/binutils-gdb/gdb/infrun.c:3968

>>     #5 0xaa990b in inferior_event_handler(inferior_event_type, void*) src/binutils-gdb/gdb/inf-loop.c:43

>>     #6 0xea61b6 in remote_async_serial_handler src/binutils-gdb/gdb/remote.c:14161

>>     #7 0xefca8a in run_async_handler_and_reschedule src/binutils-gdb/gdb/ser-base.c:137

>>     #8 0xefcd23 in fd_event src/binutils-gdb/gdb/ser-base.c:188

>>     #9 0x15a7416 in handle_file_event src/binutils-gdb/gdbsupport/event-loop.cc:548

>>     #10 0x15a7c36 in gdb_wait_for_event src/binutils-gdb/gdbsupport/event-loop.cc:673

>>     #11 0x15a5dbb in gdb_do_one_event() src/binutils-gdb/gdbsupport/event-loop.cc:215

>>     #12 0xbfe62d in start_event_loop src/binutils-gdb/gdb/main.c:356

>>     #13 0xbfe935 in captured_command_loop src/binutils-gdb/gdb/main.c:416

>>     #14 0xc01d39 in captured_main src/binutils-gdb/gdb/main.c:1253

>>     #15 0xc01dc9 in gdb_main(captured_main_args*) src/binutils-gdb/gdb/main.c:1268

>>     #16 0x414ddd in main src/binutils-gdb/gdb/gdb.c:32

>>     #17 0x7f590110b82f in __libc_start_main ../csu/libc-start.c:291

>>     #18 0x414bd8 in _start (build/binutils-gdb/gdb/gdb+0x414bd8)

> 

> What happens is that above, we're in dwarf2_frame_this_id, just after

> the dwarf2_frame_cache call.  The "cache" variable that the

> dwarf2_frame_cache function returned is already stale.  It's been

> released here, from within the dwarf2_frame_cache:

> 

> (top-gdb) bt

> #0  reinit_frame_cache () at src/gdb/frame.c:1855

> #1  0x00000000014ff7b0 in switch_to_no_thread () at src/gdb/thread.c:1301

> #2  0x0000000000f66d3e in switch_to_inferior_no_thread (inf=0x615000338180) at src/gdb/inferior.c:626

> #3  0x00000000012f3826 in remote_unpush_target (target=0x6170000c5900) at src/gdb/remote.c:5521

> #4  0x00000000013097e0 in remote_target::readchar (this=0x6170000c5900, timeout=2) at src/gdb/remote.c:9137

> #5  0x000000000130be4d in remote_target::getpkt_or_notif_sane_1 (this=0x6170000c5900, buf=0x6170000c5918, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9683

> #6  0x000000000130c8ab in remote_target::getpkt_sane (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9790

> #7  0x000000000130bc0d in remote_target::getpkt (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9623

> #8  0x000000000130838e in remote_target::remote_read_bytes_1 (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len_units=64, unit_size=1, xfered_len_units=0x7fff6a29b9a0) at src/gdb/remote.c:8860

> #9  0x0000000001308bd2 in remote_target::remote_read_bytes (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64, unit_size=1, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:8987

> #10 0x0000000001311ed1 in remote_target::xfer_partial (this=0x6170000c5900, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:10988

> #11 0x00000000014ba969 in raw_memory_xfer_partial (ops=0x6170000c5900, readbuf=0x6080000ad3bc "", writebuf=0x0, memaddr=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:918

> #12 0x00000000014bb720 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1148

> #13 0x00000000014bc3b5 in target_read_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1380

> #14 0x00000000014bc593 in target_read (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64) at src/gdb/target.c:1419

> #15 0x00000000014bbd4d in target_read_raw_memory (memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64) at src/gdb/target.c:1252

> #16 0x0000000000bf27df in dcache_read_line (dcache=0x6060001eddc0, db=0x6080000ad3a0) at src/gdb/dcache.c:336

> #17 0x0000000000bf2b72 in dcache_peek_byte (dcache=0x6060001eddc0, addr=0x7fffffffcdd8, ptr=0x6020001231b0 "") at src/gdb/dcache.c:403

> #18 0x0000000000bf3103 in dcache_read_memory_partial (ops=0x6170000c5900, dcache=0x6060001eddc0, memaddr=0x7fffffffcdd8, myaddr=0x6020001231b0 "", len=8, xfered_len=0x7fff6a29bf20) at src/gdb/dcache.c:484

> #19 0x00000000014bafe9 in memory_xfer_partial_1 (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1034

> #20 0x00000000014bb212 in memory_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1076

> #21 0x00000000014bb6b3 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, annex=0x0, readbuf=0x6020001231b0 "", writebuf=0x0, offset=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1133

> #22 0x000000000164564d in read_value_memory (val=0x60f000029440, bit_offset=0, stack=1, memaddr=0x7fffffffcdd8, buffer=0x6020001231b0 "", length=8) at src/gdb/valops.c:956

> #23 0x0000000001680fff in value_fetch_lazy_memory (val=0x60f000029440) at src/gdb/value.c:3764

> #24 0x0000000001681efd in value_fetch_lazy (val=0x60f000029440) at src/gdb/value.c:3910

> #25 0x0000000001676143 in value_optimized_out (value=0x60f000029440) at src/gdb/value.c:1411

> #26 0x0000000000e0fcb8 in frame_register_unwind (next_frame=0x6210066bfde0, regnum=16, optimizedp=0x7fff6a29c200, unavailablep=0x7fff6a29c240, lvalp=0x7fff6a29c2c0, addrp=0x7fff6a29c300, realnump=0x7fff6a29c280, bufferp=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1144

> #27 0x0000000000e10418 in frame_unwind_register (next_frame=0x6210066bfde0, regnum=16, buf=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1196

> #28 0x0000000000f00431 in i386_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/i386-tdep.c:1969

> #29 0x0000000000e39724 in gdbarch_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/gdbarch.c:3056

> #30 0x0000000000c2ea90 in dwarf2_tailcall_sniffer_first (this_frame=0x6210066bfde0, tailcall_cachep=0x6210066bfee0, entry_cfa_sp_offsetp=0x0) at src/gdb/dwarf2/frame-tailcall.c:423

> #31 0x0000000000c36bdb in dwarf2_frame_cache (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8) at src/gdb/dwarf2/frame.c:1198

> #32 0x0000000000c36eb3 in dwarf2_frame_this_id (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8, this_id=0x6210066bfe40) at src/gdb/dwarf2/frame.c:1226

> 

> Note that remote_target::readchar in frame #3 throws

> TARGET_CLOSE_ERROR after that remote_unpush_target in frame #3

> returns.

> 

> The problem is that that TARGET_CLOSE_ERROR is swallowed by


`that that`

Otherwise, LGTM.

Simon
Pedro Alves July 9, 2020, 10:51 a.m. | #2
On 7/9/20 4:17 AM, Simon Marchi wrote:
> On 2020-07-08 7:31 p.m., Pedro Alves wrote:

>> Running the testsuite against an Asan-enabled build of GDB makes

>> gdb.base/multi-target.exp expose this bug.

>>

>> scoped_restore_current_thread's ctor calls get_frame_id to record the

>> selected frame's ID to restore later.  If the frame ID hasn't been

>> computed yet, it will be computed on the spot, and that will usually

>> require accessing the target's memory and registers, which requires

>> remote accesses.  If the remote connection closes while we're

>> computing the frame ID, the remote target exits its inferiors,

>> unpushes itself, and throws a TARGET_CLOSE_ERROR error.

>>

>> If that happens, GDB can currently crash, here:

>>

>>> ==18555==ERROR: AddressSanitizer: heap-use-after-free on address 0x621004670aa8 at pc 0x0000007ab125 bp 0x7ffdecaecd20 sp 0x7ffdecaecd10

>>> READ of size 4 at 0x621004670aa8 thread T0

>>>     #0 0x7ab124 in dwarf2_frame_this_id src/binutils-gdb/gdb/dwarf2/frame.c:1228

>>>     #1 0x983ec5 in compute_frame_id src/binutils-gdb/gdb/frame.c:550

>>>     #2 0x9841ee in get_frame_id(frame_info*) src/binutils-gdb/gdb/frame.c:582

>>>     #3 0x1093faa in scoped_restore_current_thread::scoped_restore_current_thread() src/binutils-gdb/gdb/thread.c:1462

>>>     #4 0xaee5ba in fetch_inferior_event(void*) src/binutils-gdb/gdb/infrun.c:3968

>>>     #5 0xaa990b in inferior_event_handler(inferior_event_type, void*) src/binutils-gdb/gdb/inf-loop.c:43

>>>     #6 0xea61b6 in remote_async_serial_handler src/binutils-gdb/gdb/remote.c:14161

>>>     #7 0xefca8a in run_async_handler_and_reschedule src/binutils-gdb/gdb/ser-base.c:137

>>>     #8 0xefcd23 in fd_event src/binutils-gdb/gdb/ser-base.c:188

>>>     #9 0x15a7416 in handle_file_event src/binutils-gdb/gdbsupport/event-loop.cc:548

>>>     #10 0x15a7c36 in gdb_wait_for_event src/binutils-gdb/gdbsupport/event-loop.cc:673

>>>     #11 0x15a5dbb in gdb_do_one_event() src/binutils-gdb/gdbsupport/event-loop.cc:215

>>>     #12 0xbfe62d in start_event_loop src/binutils-gdb/gdb/main.c:356

>>>     #13 0xbfe935 in captured_command_loop src/binutils-gdb/gdb/main.c:416

>>>     #14 0xc01d39 in captured_main src/binutils-gdb/gdb/main.c:1253

>>>     #15 0xc01dc9 in gdb_main(captured_main_args*) src/binutils-gdb/gdb/main.c:1268

>>>     #16 0x414ddd in main src/binutils-gdb/gdb/gdb.c:32

>>>     #17 0x7f590110b82f in __libc_start_main ../csu/libc-start.c:291

>>>     #18 0x414bd8 in _start (build/binutils-gdb/gdb/gdb+0x414bd8)

>>

>> What happens is that above, we're in dwarf2_frame_this_id, just after

>> the dwarf2_frame_cache call.  The "cache" variable that the

>> dwarf2_frame_cache function returned is already stale.  It's been

>> released here, from within the dwarf2_frame_cache:

>>

>> (top-gdb) bt

>> #0  reinit_frame_cache () at src/gdb/frame.c:1855

>> #1  0x00000000014ff7b0 in switch_to_no_thread () at src/gdb/thread.c:1301

>> #2  0x0000000000f66d3e in switch_to_inferior_no_thread (inf=0x615000338180) at src/gdb/inferior.c:626

>> #3  0x00000000012f3826 in remote_unpush_target (target=0x6170000c5900) at src/gdb/remote.c:5521

>> #4  0x00000000013097e0 in remote_target::readchar (this=0x6170000c5900, timeout=2) at src/gdb/remote.c:9137

>> #5  0x000000000130be4d in remote_target::getpkt_or_notif_sane_1 (this=0x6170000c5900, buf=0x6170000c5918, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9683

>> #6  0x000000000130c8ab in remote_target::getpkt_sane (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9790

>> #7  0x000000000130bc0d in remote_target::getpkt (this=0x6170000c5900, buf=0x6170000c5918, forever=0) at src/gdb/remote.c:9623

>> #8  0x000000000130838e in remote_target::remote_read_bytes_1 (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len_units=64, unit_size=1, xfered_len_units=0x7fff6a29b9a0) at src/gdb/remote.c:8860

>> #9  0x0000000001308bd2 in remote_target::remote_read_bytes (this=0x6170000c5900, memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64, unit_size=1, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:8987

>> #10 0x0000000001311ed1 in remote_target::xfer_partial (this=0x6170000c5900, object=TARGET_OBJECT_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/remote.c:10988

>> #11 0x00000000014ba969 in raw_memory_xfer_partial (ops=0x6170000c5900, readbuf=0x6080000ad3bc "", writebuf=0x0, memaddr=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:918

>> #12 0x00000000014bb720 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, readbuf=0x6080000ad3bc "", writebuf=0x0, offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1148

>> #13 0x00000000014bc3b5 in target_read_partial (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64, xfered_len=0x7fff6a29b9a0) at src/gdb/target.c:1380

>> #14 0x00000000014bc593 in target_read (ops=0x6170000c5900, object=TARGET_OBJECT_RAW_MEMORY, annex=0x0, buf=0x6080000ad3bc "", offset=140737488342464, len=64) at src/gdb/target.c:1419

>> #15 0x00000000014bbd4d in target_read_raw_memory (memaddr=0x7fffffffcdc0, myaddr=0x6080000ad3bc "", len=64) at src/gdb/target.c:1252

>> #16 0x0000000000bf27df in dcache_read_line (dcache=0x6060001eddc0, db=0x6080000ad3a0) at src/gdb/dcache.c:336

>> #17 0x0000000000bf2b72 in dcache_peek_byte (dcache=0x6060001eddc0, addr=0x7fffffffcdd8, ptr=0x6020001231b0 "") at src/gdb/dcache.c:403

>> #18 0x0000000000bf3103 in dcache_read_memory_partial (ops=0x6170000c5900, dcache=0x6060001eddc0, memaddr=0x7fffffffcdd8, myaddr=0x6020001231b0 "", len=8, xfered_len=0x7fff6a29bf20) at src/gdb/dcache.c:484

>> #19 0x00000000014bafe9 in memory_xfer_partial_1 (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1034

>> #20 0x00000000014bb212 in memory_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, readbuf=0x6020001231b0 "", writebuf=0x0, memaddr=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1076

>> #21 0x00000000014bb6b3 in target_xfer_partial (ops=0x6170000c5900, object=TARGET_OBJECT_STACK_MEMORY, annex=0x0, readbuf=0x6020001231b0 "", writebuf=0x0, offset=140737488342488, len=8, xfered_len=0x7fff6a29bf20) at src/gdb/target.c:1133

>> #22 0x000000000164564d in read_value_memory (val=0x60f000029440, bit_offset=0, stack=1, memaddr=0x7fffffffcdd8, buffer=0x6020001231b0 "", length=8) at src/gdb/valops.c:956

>> #23 0x0000000001680fff in value_fetch_lazy_memory (val=0x60f000029440) at src/gdb/value.c:3764

>> #24 0x0000000001681efd in value_fetch_lazy (val=0x60f000029440) at src/gdb/value.c:3910

>> #25 0x0000000001676143 in value_optimized_out (value=0x60f000029440) at src/gdb/value.c:1411

>> #26 0x0000000000e0fcb8 in frame_register_unwind (next_frame=0x6210066bfde0, regnum=16, optimizedp=0x7fff6a29c200, unavailablep=0x7fff6a29c240, lvalp=0x7fff6a29c2c0, addrp=0x7fff6a29c300, realnump=0x7fff6a29c280, bufferp=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1144

>> #27 0x0000000000e10418 in frame_unwind_register (next_frame=0x6210066bfde0, regnum=16, buf=0x7fff6a29c3a0 "@\304)j\377\177") at src/gdb/frame.c:1196

>> #28 0x0000000000f00431 in i386_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/i386-tdep.c:1969

>> #29 0x0000000000e39724 in gdbarch_unwind_pc (gdbarch=0x6210043d0110, next_frame=0x6210066bfde0) at src/gdb/gdbarch.c:3056

>> #30 0x0000000000c2ea90 in dwarf2_tailcall_sniffer_first (this_frame=0x6210066bfde0, tailcall_cachep=0x6210066bfee0, entry_cfa_sp_offsetp=0x0) at src/gdb/dwarf2/frame-tailcall.c:423

>> #31 0x0000000000c36bdb in dwarf2_frame_cache (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8) at src/gdb/dwarf2/frame.c:1198

>> #32 0x0000000000c36eb3 in dwarf2_frame_this_id (this_frame=0x6210066bfde0, this_cache=0x6210066bfdf8, this_id=0x6210066bfe40) at src/gdb/dwarf2/frame.c:1226

>>

>> Note that remote_target::readchar in frame #3 throws

>> TARGET_CLOSE_ERROR after that remote_unpush_target in frame #3

>> returns.

>>

>> The problem is that that TARGET_CLOSE_ERROR is swallowed by

> 

> `that that`

> 


That wasn't a typo, compare with:

 The problem is that this TARGET_CLOSE_ERROR
 The problem is that those TARGET_CLOSE_ERRORs
 The problem is that these TARGET_CLOSE_ERRORs

https://english.stackexchange.com/questions/3418/how-do-you-handle-that-that-the-double-that-problem

I'll say "that the" instead to avoid confusion.

> Otherwise, LGTM.

> 

> Simon
Simon Marchi July 9, 2020, 2:13 p.m. | #3
On 2020-07-09 6:51 a.m., Pedro Alves wrote:
>> `that that`

>>

> 

> That wasn't a typo, compare with:

> 

>  The problem is that this TARGET_CLOSE_ERROR

>  The problem is that those TARGET_CLOSE_ERRORs

>  The problem is that these TARGET_CLOSE_ERRORs

> 

> https://english.stackexchange.com/questions/3418/how-do-you-handle-that-that-the-double-that-problem

> 

> I'll say "that the" instead to avoid confusion.


Haha, I see now.  Yeah I think any alternative to `that that` is clearer.

Simon

Patch

diff --git a/gdb/dwarf2/frame-tailcall.c b/gdb/dwarf2/frame-tailcall.c
index 16dba2b201..ec6ed6bb00 100644
--- a/gdb/dwarf2/frame-tailcall.c
+++ b/gdb/dwarf2/frame-tailcall.c
@@ -377,7 +377,6 @@  dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
      get_frame_address_in_block will decrease it by 1 in such case.  */
   this_pc = get_frame_address_in_block (this_frame);
 
-  /* Catch any unwinding errors.  */
   try
     {
       int sp_regnum;
@@ -439,7 +438,22 @@  dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
     {
       if (entry_values_debug)
 	exception_print (gdb_stdout, except);
-      return;
+
+      switch (except.error)
+	{
+	case NO_ENTRY_VALUE_ERROR:
+	  /* Thrown by call_site_find_chain.  */
+	case MEMORY_ERROR:
+	case OPTIMIZED_OUT_ERROR:
+	case NOT_AVAILABLE_ERROR:
+	  /* These can normally happen when we try to access an
+	     optimized out or unavailable register, either in a
+	     physical register or spilled to memory.  */
+	  return;
+	}
+
+      /* Let unexpected errors propagate.  */
+      throw;
     }
 
   /* Ambiguous unwind or unambiguous unwind verified as matching.  */
diff --git a/gdb/value.c b/gdb/value.c
index 97a099ddbd..00d8ded2ae 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1412,7 +1412,18 @@  value_optimized_out (struct value *value)
 	}
       catch (const gdb_exception_error &ex)
 	{
-	  /* Fall back to checking value->optimized_out.  */
+	  switch (ex.error)
+	    {
+	    case MEMORY_ERROR:
+	    case OPTIMIZED_OUT_ERROR:
+	    case NOT_AVAILABLE_ERROR:
+	      /* These can normally happen when we try to access an
+		 optimized out or unavailable register, either in a
+		 physical register or spilled to memory.  */
+	      break;
+	    default:
+	      throw;
+	    }
 	}
     }