(gdb) disassemble 0x0,+4 Dump of assembler code from 0x0 to 0x4: terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR' 0x0000000000000000: Aborted This can be reproduced on aarch64-linux and ppc64-linux. #0 __GI_abort () at abort.c:51 #1 0x000000000076bd2c in __gnu_cxx::__verbose_terminate_handler() () #2 0x0000000000766794 in __cxxabiv1::__terminate(void (*)()) () #3 0x00000000007667dc in std::terminate() () #4 0x0000000000764848 in __cxa_throw () #5 0x000000000053e78c in throw_exception_cxx (exception=...) at ../../binutils-gdb/gdb/common/common-exceptions.c:303 #6 0x000000000053e840 in throw_exception (exception=...) at ../../binutils-gdb/gdb/common/common-exceptions.c:317 #7 throw_it (reason=reason@entry=RETURN_ERROR, error=MEMORY_ERROR, fmt=fmt@entry=0x85ec70 "%s", ap=<error reading variable: Cannot access memory at address 0x474e5543432b2b00>) at ../../binutils-gdb/gdb/common/common-exceptions.c:373 #8 0x000000000053ea58 in throw_verror (error=<optimized out>, fmt=fmt@entry=0x85ec70 "%s", ap=<error reading variable: Cannot access memory at address 0x2>) at ../../binutils-gdb/gdb/common/common-exceptions.c:379 #9 0x000000000053eb04 in throw_error (error=<optimized out>, fmt=fmt@entry=0x85ec70 "%s") at ../../binutils-gdb/gdb/common/common-exceptions.c:394 #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, stb=stb@entry=0xbd5100) at ../../binutils-gdb/gdb/disasm.c:276 #13 0x00000000005536c0 in dump_insns (gdbarch=0xbbceb0, gdbarch@entry=0x0, uiout=uiout@entry=0xbc73d0, di=0xffffffffeeb0, di@entry=0xffffffffef90, low=low@entry=0, high=4, high@entry=0, how_many=-1, how_many@entry=0, flags=flags@entry=0, stb=0xbd5100, stb@entry=0x0, end_pc=end_pc@entry=0x0) at ../../binutils-gdb/gdb/disasm.c:303 #14 0x0000000000553f8c in do_assembly_only (stb=0x0, flags=0, how_many=0, high=0, low=0, di=0xffffffffef90, uiout=0xbc73d0, gdbarch=0x0) at ../../binutils-gdb/gdb/disasm.c:745 #15 gdb_disassembly (gdbarch=gdbarch@entry=0xbbceb0, uiout=0xbc73d0, file_string=file_string@entry=0x0, flags=flags@entry=0, how_many=0, how_many@entry=-1, low=low@entry=0, high=0, high@entry=4) at ../../binutils-gdb/gdb/disasm.c:811 #16 0x0000000000485b08 in print_disassembly (gdbarch=0xbbceb0, name=<optimized out>, low=0, high=4, flags=0) at ../../binutils-gdb/gdb/cli/cli-cmds.c:1151 #17 0x00000000004868fc in print_disassembly (flags=0, high=4, low=0, name=0x0, gdbarch=0xbbceb0) at ../../binutils-gdb/gdb/cli/cli-cmds.c:1140 #18 disassemble_command (arg=<optimized out>, from_tty=<optimized out>) at ../../binutils-gdb/gdb/cli/cli-cmds.c:1303 #19 0x000000000048a2fc in cmd_func (cmd=0xaffcf0, args=0xbc967c "0x0,+4", from_tty=1) at ../../binutils-gdb/gdb/cli/cli-decode.c:1913 We need a fix similar to 89525768cd086a0798a504c81fdf7ebcd4c904e1
GDB 7.12 branch is affected too.
To be clear, "This can be reproduced on aarch64-linux and ppc64-linux." in the bug report, means the host rather than target. This can be reproduced on native GDB on aarch64-linux and ppc64-linux host.
It is a regression. GDB 7.11.1 works well (with --enable-build-with-cxx and without --enable-build-with-cxx) on aarch64-linux. (gdb) disassemble 0x0,+4 Dump of assembler code from 0x0 to 0x4: 0x0000000000000000: Cannot access memory at address 0x0
The gdb-7.12-branch branch has been updated by Yao Qi <qiyao@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e2285602341fff057a9b4687b465a9d9cde1303f commit e2285602341fff057a9b4687b465a9d9cde1303f Author: Yao Qi <yao.qi@linaro.org> Date: Fri Jan 20 13:00:52 2017 +0000 Throw SJ/LJ exception on error in disassembly PR 20939 reports that GDB will abort on memory error in disassembly, (gdb) disassemble 0x0,+4 Dump of assembler code from 0x0 to 0x4: terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR' 0x0000000000000000: Aborted (gdb) guile (print (arch-disassemble arch 0 #:size 4))^M terminate called after throwing an instance of 'gdb_exception_RETURN_MASK_ERROR'^M ERROR: Process no longer exists This patch fixes PR 20939 by catching C++ exception, throwing SJ/LJ exception in the call back passed to C functions of opcodes, and catching SJ/LJ exception in gdb, and throw exception. The patch follows this commit 89525768cd086a0798a504c81fdf7ebcd4c904e1 Propagate GDB/C++ exceptions across readline using sj/lj-based TRY/CATCH rather than "backport" the fix to this PR I posted for mainline https://sourceware.org/ml/gdb-patches/2017-01/msg00288.html because the fix for mainline includes 1) some changes to opcodes, 2) some refactors in C++. All of them are risky to backport to 7.12 branch. With this patch applied to 7.12 branch, GDB doesn't abort on memory error in disassembly. It fixes some test failures in gdb.guile/scm-disasm.exp and gdb.python/py-arch.exp on aarch64-linux. -ERROR: Process no longer exists -UNRESOLVED: gdb.guile/scm-disasm.exp: test bad memory access +PASS: gdb.guile/scm-disasm.exp: test bad memory access -ERROR: Process no longer exists -UNRESOLVED: gdb.python/py-arch.exp: test bad memory access +PASS: gdb.python/py-arch.exp: test bad memory access I'll add the scm-disasm test to master later. gdb: 2017-01-20 Yao Qi <yao.qi@linaro.org> PR gdb/20939 * disasm.c (dis_asm_memory_error): Catch the error and rethrow it as a SJ/LJ exception. Add GDB_NOEXCEPT. (disasm_print_insn_noexcept): New function. (disasm_print_insn): New function. (gdb_pretty_print_insn): Call disasm_print_insn instead of gdbarch_print_insn. (gdb_print_insn): Likewise. (gdb_buffered_insn_length): Likewise. * event-top.c (GDB_NOEXCEPT): Move it to ... * exceptions.h (GDB_NOEXCEPT): ... here. * guile/scm-disasm.c (gdbscm_disasm_memory_error): Remove. (gdbscm_print_insn_from_port): Don't set di.memory_errro_func. Call disasm_print_insn rather than gdbarch_print_insn.
Great, thank you Yao!
The master branch has been updated by Yao Qi <qiyao@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d8b49cf0c891d09dd58de05ad5cfe396b612cf3b commit d8b49cf0c891d09dd58de05ad5cfe396b612cf3b Author: Yao Qi <yao.qi@linaro.org> Date: Thu Jan 26 14:29:20 2017 +0000 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.
It is fixed in master too.