Description of problem: GDB is using librpm for the rpm database access. GDB heavily depends on SIGINT handling to get attention from running inferior program. In some moments pressing CTRL-C will terminate whole GDB via librpm. Version-Release number of selected component (if applicable): rpm-4.8.1-5.fc14.x86_64 gdb-7.2-22.fc14.x86_64 How reproducible: One of 20 attempts. Steps to Reproduce: 1. gdb -ex r --args program 2. Heavily start pressing CTRL-C during `program' startup. Actual results: GDB sometimes exits without any message. Exit code is 1. Inferior `program' dumps core with SIGTRAP due to breakpoints forgotten there by GDB. Expected results: GDB gives `(gdb) _' prompt awaiting commands for debugged inferior `program'. Additional info: There should be a way to disable the exit() call at: 686 int rpmdbCheckSignals(void) 687 { 688 if (rpmdbCheckTerminate(0)) { 689 rpmlog(RPMLOG_DEBUG, "Exiting on signal...\n"); 690 exit(EXIT_FAILURE); 691 } Currently going to just nullify rpmsqEnable() (as it is called via PLT) as GDB's signals handling is safe enough to never about librpm processing.
init of the librpm signals handling: #0 rpmsqEnable (signum=2, handler=0) at rpmsq.c:239 #1 openDatabase at rpmdb.c:975 #2 rpmdbOpen at rpmdb.c:1052 #3 rpmtsOpenDB at rpmts.c:82 #4 rpmtsInitIterator at rpmts.c:150 #5 loadKeyringFromDB at rpmts.c:290 #6 loadKeyring at rpmts.c:325 #7 rpmtsInitIterator at rpmts.c:148 #8 missing_rpm_enlist at ../../gdb/elfread.c:1507 #9 debug_print_missing at ../../gdb/elfread.c:1868 #10 svr4_current_sos at ../../gdb/solib-svr4.c:1217 #11 update_solib_list at ../../gdb/solib.c:706 #12 solib_add at ../../gdb/solib.c:929 #13 enable_break at ../../gdb/solib-svr4.c:1414 #14 post_create_inferior at ../../gdb/infcmd.c:414 #15 core_open at ../../gdb/corelow.c:487 #16 catch_command_errors at ../../gdb/exceptions.c:534 #17 captured_main at ../../gdb/main.c:921 #18 catch_errors at ../../gdb/exceptions.c:518 #19 gdb_main at ../../gdb/main.c:1016 #20 main at ../../gdb/gdb.c:48 incorrect exit: #0 raise at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42 #1 exit at exitcore.c:10 #2 rpmdbCheckSignals at rpmdb.c:690 #3 rpmdbFreeIterator at rpmdb.c:1591 #4 rpmdbFindByFile at rpmdb.c:1189 #5 rpmdbInitIterator at rpmdb.c:2298 #6 rpmtsInitIterator at rpmts.c:210 #7 missing_rpm_enlist at ../../gdb/elfread.c:1507 #8 debug_print_missing at ../../gdb/elfread.c:1875 #9 elf_symfile_read at ../../gdb/elfread.c:2109 #10 syms_from_objfile at ../../gdb/symfile.c:1029 #11 symbol_file_add_with_addrs_or_offsets at ../../gdb/symfile.c:1123 #12 solib_read_symbols at ../../gdb/solib.c:649 #13 solib_add at ../../gdb/solib.c:962 #14 bpstat_what at ../../gdb/breakpoint.c:4441 #15 handle_inferior_event at ../../gdb/infrun.c:4097 #16 wait_for_inferior at ../../gdb/infrun.c:2587 #17 proceed at ../../gdb/infrun.c:2096 #18 continue_command at ../../gdb/infcmd.c:788 #19 execute_command at ../../gdb/top.c:423 #20 command_handler at ../../gdb/event-top.c:503 #21 command_line_handler at ../../gdb/event-top.c:707 #22 rl_callback_read_char at ../callback.c:208 #23 rl_callback_read_char_wrapper at ../../gdb/event-top.c:179 #24 process_event at ../../gdb/event-loop.c:399 #25 gdb_do_one_event at ../../gdb/event-loop.c:464 #26 catch_errors at ../../gdb/exceptions.c:518 #27 tui_command_loop at ../../gdb/tui/tui-interp.c:174 #28 captured_command_loop at ../../gdb/main.c:229 #29 catch_errors at ../../gdb/exceptions.c:518 #30 captured_main at ../../gdb/main.c:1006 #31 catch_errors at ../../gdb/exceptions.c:518 #32 gdb_main at ../../gdb/main.c:1016 #33 main at ../../gdb/gdb.c:48
I poked around this recently, I'll probably change the rpmdbCheckSignals() mechanism to a more general signal queue callback which can be specified though the API. The current rpmdbCheckSignals() behavior is only remotely reasonable to rpm cli itself, and even there it has various issues. This is unlikely to change in F14 though, moving to rawhide.
This package has changed ownership in the Fedora Package Database. Reassigning to the new owner of this component.
FWIW I'm running into this too: I have two processes, a parent and a child created via the multiprocessing framework [1]. An RPM transaction is running in the child. If it receives ^C it terminates (without any message) but (I speculate here) it uses exit() system call. That sends SIGCHLD to the parent process which doesn't catch it (why should it, the framework otherwise takes care of everything) and silently terminates too. This looks very odd if witnessed and it would be really nice if we could tell RPM not to do that (but just e.g. terminate the transaction immediately etc.) [1] http://docs.python.org/2/library/multiprocessing.html
Hmm, I am partially wrong in comment 5, the 'silence' of the parent process is not because of the uncaught SIGCHLD, which is ignored by default.
This is workarounded in GDB for those 2.5 years by: http://pkgs.fedoraproject.org/cgit/gdb.git/tree/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch
rpm >= 4.13 (so present in all current Fedora versions) has an special-case API to completely disable rpm's signal queue thingy so you dont need to play tricks to override he rpmsqEnable symbol: https://github.com/rpm-software-management/rpm/commit/56f49d7f5af7c1c8a3eb478431356195adbfdd25 Git master has a more comprehensive rework of the signal queue mechanism but that's not so relevant to something like gdb that just wants to do it's own thing anyway.