Summary: | Fatal error when the disassemble command is interrupted with SIGINT | ||
---|---|---|---|
Product: | gdb | Reporter: | Dmitry Neverov <dmitry.neverov> |
Component: | gdb | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | tromey, vries |
Priority: | P2 | ||
Version: | 15.1 | ||
Target Milestone: | 15.2 | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Attachments: |
gdb session log
tentative patch |
I'm not 100% sure of what's happening here, but I wonder if your libopcodes is being built in a way that doesn't allow an exception to propagate across it. This could cause a crash. I wonder if something like this would fix it: ... diff --git a/gdb/disasm.c b/gdb/disasm.c index 16736e54997..a642b4634ab 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -197,7 +197,20 @@ gdb_disassembler_memory_reader::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, struct disassemble_info *info) noexcept { - return target_read_code (memaddr, myaddr, len); + try + { + return target_read_code (memaddr, myaddr, len); + } + catch (const gdb_exception_quit &) + { + set_quit_flag (); + } + catch (const gdb_exception_forced_quit &) + { + set_force_quit_flag (); + } + + return -1; } /* Wrapper of memory_error. */ ... I managed to reproduce this on aarch64-linux, leap 15.5 container on fedora 40 host, using this trigger patch: ... diff --git a/gdb/disasm.c b/gdb/disasm.c index 16736e54997..962756415ad 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -197,6 +197,7 @@ gdb_disassembler_memory_reader::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, struct disassemble_info *info) noexcept { + set_quit_flag (); return target_read_code (memaddr, myaddr, len); } ... and this gdb command using a hello world a.out: ... $ gdb -q -batch a.out -ex "disassemble main" Dump of assembler code for function main: terminate called after throwing an instance of 'gdb_exception_quit' Fatal signal: Aborted ----- Backtrace ----- ... Created attachment 15655 [details]
tentative patch
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c45c3b4162148077765e94fd17d4481f18d6d44c commit c45c3b4162148077765e94fd17d4481f18d6d44c Author: Tom de Vries <tdevries@suse.de> Date: Thu Aug 8 23:52:00 2024 +0200 [gdb] Handle ^C during disassembly In PR gdb/32025, a fatal error was reported when sending a SIGINT to gdb while disassembling. I managed to reproduce this on aarch64-linux in a Leap 15.5 container using this trigger patch: ... gdb_disassembler_memory_reader::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, struct disassemble_info *info) noexcept { + set_quit_flag (); return target_read_code (memaddr, myaddr, len); } ... and a simple gdb command line calling the disassemble command: ... $ gdb -q -batch a.out -ex "disassemble main" ... The following scenario leads to the fatal error: - the disassemble command is executed, - set_quit_flag is called in gdb_disassembler_memory_reader::dis_asm_read_memory, pretending that a user pressed ^C, - target_read_code calls QUIT, which throws a gdb_exception_quit, - the exception propagation mechanism reaches c code in libopcodes and a fatal error triggers because the c code is not compiled with -fexception. Fix this by: - wrapping the body of gdb_disassembler_memory_reader::dis_asm_read_memory in catch_exceptions (which consequently needs moving to a header file), and - reraising the caught exception in default_print_insn using QUIT. Tested on aarch64-linux. Approved-By: Andrew Burgess <aburgess@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32025 Fixed. The gdb-15-branch branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=de553d417e1c059edcd33f59fb20c780f6406668 commit de553d417e1c059edcd33f59fb20c780f6406668 Author: Tom de Vries <tdevries@suse.de> Date: Thu Aug 22 11:43:32 2024 +0200 [gdb] Handle ^C during disassembly In PR gdb/32025, a fatal error was reported when sending a SIGINT to gdb while disassembling. I managed to reproduce this on aarch64-linux in a Leap 15.5 container using this trigger patch: ... gdb_disassembler_memory_reader::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, struct disassemble_info *info) noexcept { + set_quit_flag (); return target_read_code (memaddr, myaddr, len); } ... and a simple gdb command line calling the disassemble command: ... $ gdb -q -batch a.out -ex "disassemble main" ... The following scenario leads to the fatal error: - the disassemble command is executed, - set_quit_flag is called in gdb_disassembler_memory_reader::dis_asm_read_memory, pretending that a user pressed ^C, - target_read_code calls QUIT, which throws a gdb_exception_quit, - the exception propagation mechanism reaches c code in libopcodes and a fatal error triggers because the c code is not compiled with -fexception. Fix this by: - wrapping the body of gdb_disassembler_memory_reader::dis_asm_read_memory in catch_exceptions (which consequently needs moving to a header file), and - reraising the caught exception in default_print_insn using QUIT. Tested on aarch64-linux. Approved-By: Andrew Burgess <aburgess@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32025 (cherry picked from commit c45c3b4162148077765e94fd17d4481f18d6d44c) |
Created attachment 15643 [details] gdb session log I was debugging the following program in a graphical gdb client: #include <iostream> void f0() { std::cout << "ok" << std::endl; } void f1() { f0(); } void f2() { f1(); } void f3() { f2(); } void f4() { f3(); } void f5() { f4(); } void f6() { f5(); } void f7() { f6(); } void f8() { f7(); } void f9() { f8(); } int main() { f9(); //break return 0; } When the breakpoint was reached, I disassembled the function and stepped by instruction. When the program suspends, the gdb client tries to load disassembly the current function. When user steps in UI, disassemble is cancelled by sending SIGINT to gdb. Such a signal leads to the fatal error: 0x566d19a476d1 gdb_internal_backtrace_1 gdb/bt-utils.c:121 0x566d19a47794 _Z22gdb_internal_backtracev gdb/bt-utils.c:169 0x566d19c5efe1 handle_fatal_signal gdb/event-top.c:916 0x7c7d8064298f ??? ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 0x7c7d80699a1b __pthread_kill_implementation ./nptl/pthread_kill.c:44 0x7c7d80699a1b __pthread_kill_internal ./nptl/pthread_kill.c:78 0x7c7d80699a1b __GI___pthread_kill ./nptl/pthread_kill.c:89 0x7c7d806428e5 __GI_raise ../sysdeps/posix/raise.c:26 0x7c7d806268b6 __GI_abort ./stdlib/abort.c:79 0x7c7d80aa4f05 _ZN9__gnu_cxx27__verbose_terminate_handlerEv ../../../../src/libstdc++-v3/libsupc++/vterminate.cc:95 0x7c7d80ab6e6b _ZN10__cxxabiv111__terminateEPFvvE ../../../../src/libstdc++-v3/libsupc++/eh_terminate.cc:48 0x7c7d80ab5e18 __cxa_call_terminate ../../../../src/libstdc++-v3/libsupc++/eh_call.cc:54 0x7c7d80ab6588 __gxx_personality_v0 ../../../../src/libstdc++-v3/libsupc++/eh_personality.cc:688 0x7c7d8160ba58 ??? 0x7c7d8160c180 ??? 0x7c7d80ab712a __cxa_throw ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:93 0x566d1a27985c throw_it gdbsupport/common-exceptions.cc:199 0x566d1a2799c4 _Z11throw_vquitPKcP13__va_list_tag gdbsupport/common-exceptions.cc:217 0x566d1a279b60 _Z10throw_quitPKcz gdbsupport/common-exceptions.cc:236 0x566d19c5f3a7 _Z4quitv gdb/event-top.c:1087 0x566d19c5f459 _Z20default_quit_handlerv gdb/event-top.c:1140 0x566d19c5f3e8 _Z10maybe_quitv gdb/event-top.c:1104 0x566d1a011b3c _Z11target_readP10target_ops13target_objectPKcPhml gdb/target.c:1980 0x566d1a011646 _Z16target_read_codemPhl gdb/target.c:1823 0x566d19b4c8c4 _ZN30gdb_disassembler_memory_reader19dis_asm_read_memoryEmPhjP16disassemble_info gdb/disasm.c:200 0x566d1a101cfd fetch_code opcodes/i386-dis.c:342 0x566d1a101f77 ckprefix opcodes/i386-dis.c:8472 0x566d1a10498d print_insn opcodes/i386-dis.c:9530 0x566d1a106154 print_insn_i386 opcodes/i386-dis.c:10024 0x566d199abb60 _Z18default_print_insnmP16disassemble_info gdb/arch-utils.c:1043 0x566d19cdaad3 i386_print_insn gdb/i386-tdep.c:3999 0x566d199b698d _Z18gdbarch_print_insnP7gdbarchmP16disassemble_info gdb/gdbarch.c:3374 0x566d19b4f9bb gdb_print_insn_1 gdb/disasm.c:1102 0x566d19b4fa7d _ZN16gdb_disassembler10print_insnEmPi gdb/disasm.c:1119 0x566d19b4d460 _ZN29gdb_pretty_print_disassembler17pretty_print_insnEPK11disasm_insn10enum_flagsI20gdb_disassembly_flagE gdb/disasm.c:449 0x566d19b4da31 dump_insns gdb/disasm.c:546 0x566d19b4f31b do_assembly_only gdb/disasm.c:960 0x566d19b4ff48 _Z15gdb_disassemblyP7gdbarchP6ui_out10enum_flagsI20gdb_disassembly_flagEimm gdb/disasm.c:1202 0x566d19a9eb5d print_disassembly gdb/cli/cli-cmds.c:1537 0x566d19a9f417 disassemble_command gdb/cli/cli-cmds.c:1717 0x566d19aa6bbc do_simple_func gdb/cli/cli-decode.c:94 0x566d19aacc18 _Z8cmd_funcP16cmd_list_elementPKci gdb/cli/cli-decode.c:2741 0x566d1a045ce7 _Z15execute_commandPKci gdb/top.c:569 0x566d19ab2a6a _ZN10cli_interp4execEPKc gdb/cli/cli-interp.c:241 0x566d19d3f1fb _Z11interp_execP6interpPKc gdb/interps.c:267 0x566d19de1188 _Z23mi_cmd_interpreter_execPKcPKS0_i gdb/mi/mi-interp.c:186 0x566d19dea3c4 captured_mi_execute_command gdb/mi/mi-main.c:1870 0x566d19dea7bb _Z18mi_execute_commandPKci gdb/mi/mi-main.c:1955 0x566d19de1279 mi_execute_command_wrapper gdb/mi/mi-interp.c:219 0x566d19de12f8 mi_execute_command_input_handler gdb/mi/mi-interp.c:241 0x566d19c5ede4 _Z32gdb_readline_no_editing_callbackPv gdb/event-top.c:873 0x566d1a0782a6 stdin_event_handler gdb/ui.c:154 0x566d1a2807ae handle_file_event gdbsupport/event-loop.cc:551 0x566d1a280e2f gdb_wait_for_event gdbsupport/event-loop.cc:672 0x566d1a27fbed _Z16gdb_do_one_eventi gdbsupport/event-loop.cc:263 0x566d19dacc55 start_event_loop gdb/main.c:400 0x566d19dace35 captured_command_loop gdb/main.c:464 0x566d19daea68 captured_main gdb/main.c:1337 0x566d19daeb12 _Z8gdb_mainP18captured_main_args gdb/main.c:1356 0x566d1990d6ae main gdb/gdb.c:38