Don't throw exception in dis_asm_memory_error
authorYao Qi <yao.qi@linaro.org>
Thu, 26 Jan 2017 14:29:20 +0000 (14:29 +0000)
committerYao Qi <yao.qi@linaro.org>
Thu, 26 Jan 2017 14:29:20 +0000 (14:29 +0000)
commitd8b49cf0c891d09dd58de05ad5cfe396b612cf3b
tree1945cc6c4192def60974bace2ad085169fd43143
parent658ca58c4d41c7512dcabcbc4a5ea2109045c363
Don't throw exception in dis_asm_memory_error

Hi,
GDB calls some APIs from opcodes to do disassembly and provide some
call backs.  This model makes troubles on C++ exception unwinding,
because GDB is a C++ program, and opcodes is still compiled as C.
As we can see, frame #10 and #12 are C++, while #frame 11 is C,

 #10 0x0000000000544228 in memory_error (err=TARGET_XFER_E_IO, memaddr=<optimized out>) at ../../binutils-gdb/gdb/corefile.c:237
 #11 0x00000000006b0a54 in print_insn_aarch64 (pc=0, info=0xffffffffeeb0) at ../../binutils-gdb/opcodes/aarch64-dis.c:3185
 #12 0x0000000000553590 in gdb_pretty_print_insn (gdbarch=gdbarch@entry=0xbbceb0, uiout=uiout@entry=0xbc73d0, di=di@entry=0xffffffffeeb0,
    insn=0xffffffffed40, insn@entry=0xffffffffed90, flags=flags@entry=0,

C++ exception unwinder can't go across frame #11 unless it has
unwind table.  However, C program on many architectures doesn't
have it in default.  As a result, GDB aborts, which is described
in PR 20939.

This is not the first time we see this kind of problem.  We've
had a commit 89525768cd086a0798a504c81fdf7ebcd4c904e1
"Propagate GDB/C++ exceptions across readline using sj/lj-based TRY/CATCH".
We can fix the disassembly bug in a similar way, this is the option one.

Since opcodes is built with gdb, we fix this problem in a different
way as we did for the same issue with readline.  Instead of throwing
exception in dis_asm_memory_error, we record the failed memory
address, and throw exception when GDB returns from opcodes disassemblers.

gdb:

2017-01-26  Yao Qi  <yao.qi@linaro.org>
    Pedro Alves  <palves@redhat.com>

PR gdb/20939
* disasm.c (gdb_disassembler::dis_asm_memory_error): Don't
call memory_error, save memaddr instead.
(gdb_disassembler::print_insn): If gdbarch_print_insn returns
negative, cal memory_error.
* disasm.h (gdb_disassembler) <m_err_memaddr>: New field.

gdb/testsuite:

2017-01-26  Yao Qi  <yao.qi@linaro.org>

* gdb.base/all-architectures.exp.in (do_arch_tests): Test
disassemble on address 0.
gdb/ChangeLog
gdb/disasm.c
gdb/disasm.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/all-architectures.exp.in