http://sourceware.org/ml/gdb-patches/2009-11/msg00596.html Subject: [gdb FYI-patch] callback-mode readline-6.0 regression Hi Chet, FSF GDB currently ships bundled with readline-5.2 which works fine. But using --with-system-readline and readline-6.0-patchlevel4 has a regression: readline-5.2: Run `gdb -nx -q' and type CTRL-C: (gdb) Quit (gdb) _ readline-6.0: Run `gdb -nx -q' and type CTRL-C: (gdb) _ = nothing happens (it gets buffered and executed later) (It does also FAIL on gdb.gdb/selftest.exp.) It is because GDB waits in its own poll() mainloop and readline uses via rl_callback_handler_install and rl_callback_handler_remove. This way the readline internal variable _rl_interrupt_immediately remains 0 and CTRL-C gets only stored to _rl_caught_signal but not executed. Seen in rl_signal_handler even if _rl_interrupt_immediately is set and _rl_handle_signal is called then the signal is still stored to _rl_caught_signal. In the _rl_interrupt_immediately case it should not be stored when it was already processed. rl_signal_handler does `_rl_interrupt_immediately = 0;' - while I am not aware of its meaning it breaks the nest-counting of other routines which do `_rl_interrupt_immediately++;' and `_rl_interrupt_immediately--;' possibly creating problematic `_rl_interrupt_immediately == -1'. `_rl_interrupt_immediately' is an internal variable, how it could be accessed by a readline application? (OK, maybe it should not be used.) Attaching a current GDB-side patch but it must access readline internal variable _rl_caught_signal and it is generally just a workaround. Could you please include support for signals in this asynchronous mode in readline-6.1? I find it would be enough to make RL_CHECK_SIGNALS public? GDB: No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu. But this is not a patch intended to be accepted. Thanks, Jan gdb/ 2009-11-29 Jan Kratochvil * config.in, configure: Regenerate. * configure.ac (for readline_echoing_p): Move inside $LIBS change. (for _rl_caught_signal): New. * event-loop.c: Include readline/readline.h. (gdb_do_one_event) [HAVE_READLINE_CAUGHT_SIGNAL]: New. gdb/testsuite/ 2009-11-29 Jan Kratochvil * gdb.gdb/selftest.exp (backtrace through signal handler): Move before SIGINT pass, drop the timeout case. (send SIGINT signal to child process): Use gdb_test. (backtrace through readline handler): New. Index: gdb-7.0.50.20100115/gdb/config.in =================================================================== --- gdb-7.0.50.20100115.orig/gdb/config.in 2010-01-15 12:48:04.000000000 +0100 +++ gdb-7.0.50.20100115/gdb/config.in 2010-01-15 12:48:40.000000000 +0100 @@ -359,6 +359,9 @@ /* Define if Python interpreter is being linked in. */ #undef HAVE_PYTHON +/* readline-6.0 workaround of blocked signals. */ +#undef HAVE_READLINE_CAUGHT_SIGNAL + /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH Index: gdb-7.0.50.20100115/gdb/configure.ac =================================================================== --- gdb-7.0.50.20100115.orig/gdb/configure.ac 2010-01-15 12:48:04.000000000 +0100 +++ gdb-7.0.50.20100115/gdb/configure.ac 2010-01-15 12:48:40.000000000 +0100 @@ -777,17 +777,25 @@ if test "$with_system_readline" = yes; t # readline-6.0 started to use the name `_rl_echoing_p'. # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. - AC_MSG_CHECKING([for readline_echoing_p]) save_LIBS=$LIBS LIBS="$LIBS $READLINE" + AC_MSG_CHECKING([for readline_echoing_p]) AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int readline_echoing_p; return readline_echoing_p;]]), [READLINE_ECHOING_P=yes], [READLINE_ECHOING_P=no AC_DEFINE([readline_echoing_p], [_rl_echoing_p], [readline-6.0 started to use different name.])]) - LIBS="$save_LIBS" AC_MSG_RESULT([$READLINE_ECHOING_P]) + AC_MSG_CHECKING([for _rl_caught_signal]) + AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int volatile _rl_caught_signal; + return _rl_caught_signal;]]), + [READLINE_CAUGHT_SIGNAL=yes + AC_DEFINE([HAVE_READLINE_CAUGHT_SIGNAL],, + [readline-6.0 workaround of blocked signals.])], + [READLINE_CAUGHT_SIGNAL=no]) + AC_MSG_RESULT([$READLINE_CAUGHT_SIGNAL]) + LIBS="$save_LIBS" else READLINE='$(READLINE_DIR)/libreadline.a' READLINE_DEPS='$(READLINE)' Index: gdb-7.0.50.20100115/gdb/event-loop.c =================================================================== --- gdb-7.0.50.20100115.orig/gdb/event-loop.c 2010-01-01 08:31:31.000000000 +0100 +++ gdb-7.0.50.20100115/gdb/event-loop.c 2010-01-15 12:48:40.000000000 +0100 @@ -37,6 +37,7 @@ #include "exceptions.h" #include "gdb_assert.h" #include "gdb_select.h" +#include "readline/readline.h" /* Data point to pass to the event handler. */ typedef union event_data @@ -411,6 +412,9 @@ gdb_do_one_event (void *data) static int event_source_head = 0; const int number_of_sources = 3; int current = 0; +#ifdef HAVE_READLINE_CAUGHT_SIGNAL + extern int volatile _rl_caught_signal; +#endif /* Any events already waiting in the queue? */ if (process_event ()) @@ -455,6 +459,16 @@ gdb_do_one_event (void *data) if (gdb_wait_for_event (1) < 0) return -1; +#ifdef HAVE_READLINE_CAUGHT_SIGNAL + if (async_command_editing_p && RL_ISSTATE (RL_STATE_CALLBACK) + && _rl_caught_signal) + { + /* Call RL_CHECK_SIGNALS this way. */ + rl_callback_handler_remove (); + rl_callback_handler_install (NULL, input_handler); + } +#endif + /* Handle any new events occurred while waiting. */ if (process_event ()) return 1; Index: gdb-7.0.50.20100115/gdb/testsuite/gdb.gdb/selftest.exp =================================================================== --- gdb-7.0.50.20100115.orig/gdb/testsuite/gdb.gdb/selftest.exp 2010-01-15 12:48:01.000000000 +0100 +++ gdb-7.0.50.20100115/gdb/testsuite/gdb.gdb/selftest.exp 2010-01-15 12:48:40.000000000 +0100 @@ -471,31 +471,42 @@ GDB.*Copyright \[0-9\]+ Free Software Fo fail "$description (timeout)" } } - - set description "send SIGINT signal to child process" - send_gdb "signal SIGINT\n" - gdb_expect { - -re "Continuing with signal SIGINT.*$gdb_prompt $" { + + # get a stack trace with the poll function + # + # This fails on some linux systems for unknown reasons. On the + # systems where it fails, sometimes it works fine when run manually. + # The testsuite failures may not be limited to just aout systems. + setup_xfail "i*86-pc-linuxaout-gnu" + set description "backtrace through signal handler" + gdb_test_multiple "backtrace" $description { + -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { pass "$description" } -re ".*$gdb_prompt $" { + # On the alpha, we hit the infamous problem about gdb + # being unable to get the frame pointer (mentioned in + # gdb/README). As it is intermittent, there is no way to + # XFAIL it which will give us an XPASS if the problem goes + # away. + setup_xfail "alpha*-*-osf*" fail "$description" } - timeout { - fail "$description (timeout)" - } } - # get a stack trace + gdb_test "signal SIGINT" "Continuing with signal SIGINT.*" \ + "send SIGINT signal to child process" + + # get a stack trace being redelivered by readline # # This fails on some linux systems for unknown reasons. On the # systems where it fails, sometimes it works fine when run manually. # The testsuite failures may not be limited to just aout systems. + # Optional system readline may not have symbols to be shown. setup_xfail "i*86-pc-linuxaout-gnu" - set description "backtrace through signal handler" - send_gdb "backtrace\n" - gdb_expect { - -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { + set description "backtrace through readline handler" + gdb_test_multiple "backtrace" $description { + -re "#0.*gdb_do_one_event.*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { pass "$description" } -re ".*$gdb_prompt $" { @@ -507,9 +518,6 @@ GDB.*Copyright \[0-9\]+ Free Software Fo setup_xfail "alpha*-*-osf*" fail "$description" } - timeout { - fail "$description (timeout)" - } } Index: gdb-7.0.50.20100115/gdb/configure =================================================================== --- gdb-7.0.50.20100115.orig/gdb/configure 2010-01-15 12:48:04.000000000 +0100 +++ gdb-7.0.50.20100115/gdb/configure 2010-01-15 12:48:46.000000000 +0100 @@ -6772,6 +6772,185 @@ else fi + + + + +# Check whether --with-separate-debug-dir was given. +if test "${with_separate_debug_dir+set}" = set; then : + withval=$with_separate_debug_dir; + DEBUGDIR=$withval +else + DEBUGDIR=${libdir}/debug +fi + + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $DEBUGDIR` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define DEBUGDIR "$ac_define_dir" +_ACEOF + + + + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix + fi + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac + +cat >>confdefs.h <<_ACEOF +#define DEBUGDIR_RELOCATABLE $value +_ACEOF + + + +# GDB's datadir relocation + + + +# Check whether --with-gdb-datadir was given. +if test "${with_gdb_datadir+set}" = set; then : + withval=$with_gdb_datadir; + GDB_DATADIR=$withval +else + GDB_DATADIR=${datadir}/gdb +fi + + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $GDB_DATADIR` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define GDB_DATADIR "$ac_define_dir" +_ACEOF + + + + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix + fi + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac + +cat >>confdefs.h <<_ACEOF +#define GDB_DATADIR_RELOCATABLE $value +_ACEOF + + + + +# Check whether --with-relocated-sources was given. +if test "${with_relocated_sources+set}" = set; then : + withval=$with_relocated_sources; reloc_srcdir="${withval}" + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $reloc_srcdir` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define RELOC_SRCDIR "$ac_define_dir" +_ACEOF + + + +fi + + +# GDB's datadir relocation + +gdbdatadir=${datadir}/gdb + + +# Check whether --with-gdb-datadir was given. +if test "${with_gdb_datadir+set}" = set; then : + withval=$with_gdb_datadir; gdbdatadir="${withval}" +fi + + + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $gdbdatadir` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define GDB_DATADIR "$ac_define_dir" +_ACEOF + + + +if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi +else + test_prefix=$exec_prefix +fi + +case ${gdbdatadir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + +$as_echo "#define GDB_DATADIR_RELOCATABLE 1" >>confdefs.h + + ;; +esac +GDB_DATADIR_PATH=${gdbdatadir} + + + +# Check whether --with-pythondir was given. +if test "${with_pythondir+set}" = set; then : + withval=$with_pythondir; pythondir="${withval}" +else + pythondir=no +fi + + +# If the user passed in a path, define it. Otherwise, compute it at +# runtime based on the possibly-relocatable datadir. +if test "$pythondir" = "no"; then + pythondir='$(GDB_DATADIR_PATH)/python' +else + +cat >>confdefs.h <<_ACEOF +#define PYTHONDIR "$pythondir" +_ACEOF + +fi + + # Integration with rpm library to support missing debuginfo suggestions. # --without-rpm: Disable any rpm support. # --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. @@ -7255,185 +7434,6 @@ fi - -# Check whether --with-separate-debug-dir was given. -if test "${with_separate_debug_dir+set}" = set; then : - withval=$with_separate_debug_dir; - DEBUGDIR=$withval -else - DEBUGDIR=${libdir}/debug -fi - - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $DEBUGDIR` - ac_define_dir=`eval echo $ac_define_dir` - -cat >>confdefs.h <<_ACEOF -#define DEBUGDIR "$ac_define_dir" -_ACEOF - - - - if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi - else - test_prefix=$exec_prefix - fi - value=0 - case ${ac_define_dir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - value=1 - ;; - esac - -cat >>confdefs.h <<_ACEOF -#define DEBUGDIR_RELOCATABLE $value -_ACEOF - - - -# GDB's datadir relocation - - - -# Check whether --with-gdb-datadir was given. -if test "${with_gdb_datadir+set}" = set; then : - withval=$with_gdb_datadir; - GDB_DATADIR=$withval -else - GDB_DATADIR=${datadir}/gdb -fi - - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $GDB_DATADIR` - ac_define_dir=`eval echo $ac_define_dir` - -cat >>confdefs.h <<_ACEOF -#define GDB_DATADIR "$ac_define_dir" -_ACEOF - - - - if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi - else - test_prefix=$exec_prefix - fi - value=0 - case ${ac_define_dir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - value=1 - ;; - esac - -cat >>confdefs.h <<_ACEOF -#define GDB_DATADIR_RELOCATABLE $value -_ACEOF - - - - -# Check whether --with-relocated-sources was given. -if test "${with_relocated_sources+set}" = set; then : - withval=$with_relocated_sources; reloc_srcdir="${withval}" - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $reloc_srcdir` - ac_define_dir=`eval echo $ac_define_dir` - -cat >>confdefs.h <<_ACEOF -#define RELOC_SRCDIR "$ac_define_dir" -_ACEOF - - - -fi - - -# GDB's datadir relocation - -gdbdatadir=${datadir}/gdb - - -# Check whether --with-gdb-datadir was given. -if test "${with_gdb_datadir+set}" = set; then : - withval=$with_gdb_datadir; gdbdatadir="${withval}" -fi - - - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $gdbdatadir` - ac_define_dir=`eval echo $ac_define_dir` - -cat >>confdefs.h <<_ACEOF -#define GDB_DATADIR "$ac_define_dir" -_ACEOF - - - -if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi -else - test_prefix=$exec_prefix -fi - -case ${gdbdatadir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - -$as_echo "#define GDB_DATADIR_RELOCATABLE 1" >>confdefs.h - - ;; -esac -GDB_DATADIR_PATH=${gdbdatadir} - - - -# Check whether --with-pythondir was given. -if test "${with_pythondir+set}" = set; then : - withval=$with_pythondir; pythondir="${withval}" -else - pythondir=no -fi - - -# If the user passed in a path, define it. Otherwise, compute it at -# runtime based on the possibly-relocatable datadir. -if test "$pythondir" = "no"; then - pythondir='$(GDB_DATADIR_PATH)/python' -else - -cat >>confdefs.h <<_ACEOF -#define PYTHONDIR "$pythondir" -_ACEOF - -fi - - - - - subdirs="$subdirs doc testsuite" @@ -9290,10 +9290,10 @@ if test "$with_system_readline" = yes; t # readline-6.0 started to use the name `_rl_echoing_p'. # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline_echoing_p" >&5 -$as_echo_n "checking for readline_echoing_p... " >&6; } save_LIBS=$LIBS LIBS="$LIBS $READLINE" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline_echoing_p" >&5 +$as_echo_n "checking for readline_echoing_p... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9316,9 +9316,35 @@ $as_echo "#define readline_echoing_p _rl fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LIBS="$save_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_ECHOING_P" >&5 $as_echo "$READLINE_ECHOING_P" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _rl_caught_signal" >&5 +$as_echo_n "checking for _rl_caught_signal... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +extern int volatile _rl_caught_signal; + return _rl_caught_signal; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + READLINE_CAUGHT_SIGNAL=yes + +$as_echo "#define HAVE_READLINE_CAUGHT_SIGNAL /**/" >>confdefs.h + +else + READLINE_CAUGHT_SIGNAL=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_CAUGHT_SIGNAL" >&5 +$as_echo "$READLINE_CAUGHT_SIGNAL" >&6; } + LIBS="$save_LIBS" else READLINE='$(READLINE_DIR)/libreadline.a' READLINE_DEPS='$(READLINE)'