]>
Commit | Line | Data |
---|---|---|
ab050a48 BZ |
1 | http://sourceware.org/ml/gdb-patches/2009-11/msg00596.html |
2 | Subject: [gdb FYI-patch] callback-mode readline-6.0 regression | |
3 | ||
4 | Hi Chet, | |
5 | ||
6 | FSF GDB currently ships bundled with readline-5.2 which works fine. | |
7 | But using --with-system-readline and readline-6.0-patchlevel4 has | |
8 | a regression: | |
9 | ||
10 | readline-5.2: Run `gdb -nx -q' and type CTRL-C: | |
11 | (gdb) Quit | |
12 | (gdb) _ | |
13 | ||
14 | readline-6.0: Run `gdb -nx -q' and type CTRL-C: | |
15 | (gdb) _ | |
16 | = nothing happens (it gets buffered and executed later) | |
17 | (It does also FAIL on gdb.gdb/selftest.exp.) | |
18 | ||
19 | It is because GDB waits in its own poll() mainloop and readline uses via | |
20 | rl_callback_handler_install and rl_callback_handler_remove. This way the | |
21 | readline internal variable _rl_interrupt_immediately remains 0 and CTRL-C gets | |
22 | only stored to _rl_caught_signal but not executed. | |
23 | ||
24 | Seen in rl_signal_handler even if _rl_interrupt_immediately is set and | |
25 | _rl_handle_signal is called then the signal is still stored to | |
26 | _rl_caught_signal. In the _rl_interrupt_immediately case it should not be | |
27 | stored when it was already processed. | |
28 | ||
29 | rl_signal_handler does `_rl_interrupt_immediately = 0;' - while I am not aware | |
30 | of its meaning it breaks the nest-counting of other routines which do | |
31 | `_rl_interrupt_immediately++;' and `_rl_interrupt_immediately--;' possibly | |
32 | creating problematic `_rl_interrupt_immediately == -1'. | |
33 | ||
34 | `_rl_interrupt_immediately' is an internal variable, how it could be accessed | |
35 | by a readline application? (OK, maybe it should not be used.) | |
36 | ||
37 | Attaching a current GDB-side patch but it must access readline internal | |
38 | variable _rl_caught_signal and it is generally just a workaround. Could you | |
39 | please include support for signals in this asynchronous mode in readline-6.1? | |
40 | I find it would be enough to make RL_CHECK_SIGNALS public? | |
41 | ||
42 | ||
43 | GDB: No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu. | |
44 | But this is not a patch intended to be accepted. | |
45 | ||
46 | ||
47 | Thanks, | |
48 | Jan | |
49 | ||
50 | ||
51 | gdb/ | |
52 | 2009-11-29 Jan Kratochvil <jan.kratochvil@redhat.com> | |
53 | ||
54 | * config.in, configure: Regenerate. | |
55 | * configure.ac (for readline_echoing_p): Move inside $LIBS change. | |
56 | (for _rl_caught_signal): New. | |
57 | * event-loop.c: Include readline/readline.h. | |
58 | (gdb_do_one_event) [HAVE_READLINE_CAUGHT_SIGNAL]: New. | |
59 | ||
60 | gdb/testsuite/ | |
61 | 2009-11-29 Jan Kratochvil <jan.kratochvil@redhat.com> | |
62 | ||
63 | * gdb.gdb/selftest.exp (backtrace through signal handler): Move before | |
64 | SIGINT pass, drop the timeout case. | |
65 | (send SIGINT signal to child process): Use gdb_test. | |
66 | (backtrace through readline handler): New. | |
67 | ||
68 | --- a/gdb/config.in | |
69 | +++ b/gdb/config.in | |
70 | @@ -351,6 +351,9 @@ | |
71 | /* Define if Python interpreter is being linked in. */ | |
72 | #undef HAVE_PYTHON | |
73 | ||
74 | +/* readline-6.0 workaround of blocked signals. */ | |
75 | +#undef HAVE_READLINE_CAUGHT_SIGNAL | |
76 | + | |
77 | /* Define to 1 if you have the `realpath' function. */ | |
78 | #undef HAVE_REALPATH | |
79 | ||
80 | --- a/gdb/configure.ac | |
81 | +++ b/gdb/configure.ac | |
82 | @@ -539,17 +539,25 @@ if test "$with_system_readline" = yes; then | |
83 | # readline-6.0 started to use the name `_rl_echoing_p'. | |
84 | # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. | |
85 | ||
86 | - AC_MSG_CHECKING([for readline_echoing_p]) | |
87 | save_LIBS=$LIBS | |
88 | LIBS="$LIBS $READLINE" | |
89 | + AC_MSG_CHECKING([for readline_echoing_p]) | |
90 | AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int readline_echoing_p; | |
91 | return readline_echoing_p;]]), | |
92 | [READLINE_ECHOING_P=yes], | |
93 | [READLINE_ECHOING_P=no | |
94 | AC_DEFINE([readline_echoing_p], [_rl_echoing_p], | |
95 | [readline-6.0 started to use different name.])]) | |
96 | - LIBS="$save_LIBS" | |
97 | AC_MSG_RESULT([$READLINE_ECHOING_P]) | |
98 | + AC_MSG_CHECKING([for _rl_caught_signal]) | |
99 | + AC_LINK_IFELSE(AC_LANG_PROGRAM(,[[extern int volatile _rl_caught_signal; | |
100 | + return _rl_caught_signal;]]), | |
101 | + [READLINE_CAUGHT_SIGNAL=yes | |
102 | + AC_DEFINE([HAVE_READLINE_CAUGHT_SIGNAL],, | |
103 | + [readline-6.0 workaround of blocked signals.])], | |
104 | + [READLINE_CAUGHT_SIGNAL=no]) | |
105 | + AC_MSG_RESULT([$READLINE_CAUGHT_SIGNAL]) | |
106 | + LIBS="$save_LIBS" | |
107 | else | |
108 | READLINE='$(READLINE_DIR)/libreadline.a' | |
109 | READLINE_DEPS='$(READLINE)' | |
110 | --- a/gdb/event-loop.c | |
111 | +++ b/gdb/event-loop.c | |
112 | @@ -37,6 +37,7 @@ | |
113 | #include "exceptions.h" | |
114 | #include "gdb_assert.h" | |
115 | #include "gdb_select.h" | |
116 | +#include "readline/readline.h" | |
117 | ||
118 | /* Data point to pass to the event handler. */ | |
119 | typedef union event_data | |
120 | @@ -411,6 +412,9 @@ gdb_do_one_event (void *data) | |
121 | static int event_source_head = 0; | |
122 | const int number_of_sources = 3; | |
123 | int current = 0; | |
124 | +#ifdef HAVE_READLINE_CAUGHT_SIGNAL | |
125 | + extern int volatile _rl_caught_signal; | |
126 | +#endif | |
127 | ||
128 | /* Any events already waiting in the queue? */ | |
129 | if (process_event ()) | |
130 | @@ -455,6 +459,16 @@ gdb_do_one_event (void *data) | |
131 | if (gdb_wait_for_event (1) < 0) | |
132 | return -1; | |
133 | ||
134 | +#ifdef HAVE_READLINE_CAUGHT_SIGNAL | |
135 | + if (async_command_editing_p && RL_ISSTATE (RL_STATE_CALLBACK) | |
136 | + && _rl_caught_signal) | |
137 | + { | |
138 | + /* Call RL_CHECK_SIGNALS this way. */ | |
139 | + rl_callback_handler_remove (); | |
140 | + rl_callback_handler_install (NULL, input_handler); | |
141 | + } | |
142 | +#endif | |
143 | + | |
144 | /* Handle any new events occurred while waiting. */ | |
145 | if (process_event ()) | |
146 | return 1; | |
147 | --- a/gdb/testsuite/gdb.gdb/selftest.exp | |
148 | +++ b/gdb/testsuite/gdb.gdb/selftest.exp | |
149 | @@ -464,31 +464,42 @@ GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\ | |
150 | fail "$description (timeout)" | |
151 | } | |
152 | } | |
153 | - | |
154 | - set description "send SIGINT signal to child process" | |
155 | - send_gdb "signal SIGINT\n" | |
156 | - gdb_expect { | |
157 | - -re "Continuing with signal SIGINT.*$gdb_prompt $" { | |
158 | + | |
159 | + # get a stack trace with the poll function | |
160 | + # | |
161 | + # This fails on some linux systems for unknown reasons. On the | |
162 | + # systems where it fails, sometimes it works fine when run manually. | |
163 | + # The testsuite failures may not be limited to just aout systems. | |
164 | + setup_xfail "i*86-pc-linuxaout-gnu" | |
165 | + set description "backtrace through signal handler" | |
166 | + gdb_test_multiple "backtrace" $description { | |
167 | + -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { | |
168 | pass "$description" | |
169 | } | |
170 | -re ".*$gdb_prompt $" { | |
171 | + # On the alpha, we hit the infamous problem about gdb | |
172 | + # being unable to get the frame pointer (mentioned in | |
173 | + # gdb/README). As it is intermittent, there is no way to | |
174 | + # XFAIL it which will give us an XPASS if the problem goes | |
175 | + # away. | |
176 | + setup_xfail "alpha*-*-osf*" | |
177 | fail "$description" | |
178 | } | |
179 | - timeout { | |
180 | - fail "$description (timeout)" | |
181 | - } | |
182 | } | |
183 | ||
184 | - # get a stack trace | |
185 | + gdb_test "signal SIGINT" "Continuing with signal SIGINT.*" \ | |
186 | + "send SIGINT signal to child process" | |
187 | + | |
188 | + # get a stack trace being redelivered by readline | |
189 | # | |
190 | # This fails on some linux systems for unknown reasons. On the | |
191 | # systems where it fails, sometimes it works fine when run manually. | |
192 | # The testsuite failures may not be limited to just aout systems. | |
193 | + # Optional system readline may not have symbols to be shown. | |
194 | setup_xfail "i*86-pc-linuxaout-gnu" | |
195 | - set description "backtrace through signal handler" | |
196 | - send_gdb "backtrace\n" | |
197 | - gdb_expect { | |
198 | - -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { | |
199 | + set description "backtrace through readline handler" | |
200 | + gdb_test_multiple "backtrace" $description { | |
201 | + -re "#0.*gdb_do_one_event.*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" { | |
202 | pass "$description" | |
203 | } | |
204 | -re ".*$gdb_prompt $" { | |
205 | @@ -500,9 +510,6 @@ GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\ | |
206 | setup_xfail "alpha*-*-osf*" | |
207 | fail "$description" | |
208 | } | |
209 | - timeout { | |
210 | - fail "$description (timeout)" | |
211 | - } | |
212 | } | |
213 | ||
214 | ||
215 | --- gdb-7.0/gdb/configure 2009-12-07 18:53:30.000000000 +0100 | |
216 | +++ gdb-7.0-x/gdb/configure 2009-12-07 18:53:14.000000000 +0100 | |
217 | @@ -9201,15 +9201,11 @@ if test "$with_system_readline" = yes; t | |
218 | # readline-6.0 started to use the name `_rl_echoing_p'. | |
219 | # `$(READLINE_DIR)/' of bundled readline would not resolve in configure. | |
220 | ||
221 | - echo "$as_me:$LINENO: checking for readline_echoing_p" >&5 | |
222 | -echo $ECHO_N "checking for readline_echoing_p... $ECHO_C" >&6 | |
223 | save_LIBS=$LIBS | |
224 | LIBS="$LIBS $READLINE" | |
225 | - cat >conftest.$ac_ext <<_ACEOF | |
226 | -/* confdefs.h. */ | |
227 | -_ACEOF | |
228 | -cat confdefs.h >>conftest.$ac_ext | |
229 | -cat >>conftest.$ac_ext <<_ACEOF | |
230 | + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline_echoing_p" >&5 | |
231 | +$as_echo_n "checking for readline_echoing_p... " >&6; } | |
232 | + cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
233 | /* end confdefs.h. */ | |
234 | ||
235 | int | |
236 | @@ -9221,45 +9217,45 @@ extern int readline_echoing_p; | |
237 | return 0; | |
238 | } | |
239 | _ACEOF | |
240 | -rm -f conftest.$ac_objext conftest$ac_exeext | |
241 | -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
242 | - (eval $ac_link) 2>conftest.er1 | |
243 | - ac_status=$? | |
244 | - grep -v '^ *+' conftest.er1 >conftest.err | |
245 | - rm -f conftest.er1 | |
246 | - cat conftest.err >&5 | |
247 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
248 | - (exit $ac_status); } && | |
249 | - { ac_try='test -z "$ac_c_werror_flag" | |
250 | - || test ! -s conftest.err' | |
251 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
252 | - (eval $ac_try) 2>&5 | |
253 | - ac_status=$? | |
254 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
255 | - (exit $ac_status); }; } && | |
256 | - { ac_try='test -s conftest$ac_exeext' | |
257 | - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
258 | - (eval $ac_try) 2>&5 | |
259 | - ac_status=$? | |
260 | - echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
261 | - (exit $ac_status); }; }; then | |
262 | +if ac_fn_c_try_link "$LINENO"; then : | |
263 | READLINE_ECHOING_P=yes | |
264 | else | |
265 | - echo "$as_me: failed program was:" >&5 | |
266 | -sed 's/^/| /' conftest.$ac_ext >&5 | |
267 | + READLINE_ECHOING_P=no | |
268 | ||
269 | -READLINE_ECHOING_P=no | |
270 | +$as_echo "#define readline_echoing_p _rl_echoing_p" >>confdefs.h | |
271 | + | |
272 | +fi | |
273 | +rm -f core conftest.err conftest.$ac_objext \ | |
274 | + conftest$ac_exeext conftest.$ac_ext | |
275 | + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_ECHOING_P" >&5 | |
276 | +$as_echo "$READLINE_ECHOING_P" >&6; } | |
277 | + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _rl_caught_signal" >&5 | |
278 | +$as_echo_n "checking for _rl_caught_signal... " >&6; } | |
279 | + cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
280 | +/* end confdefs.h. */ | |
281 | ||
282 | -cat >>confdefs.h <<\_ACEOF | |
283 | -#define readline_echoing_p _rl_echoing_p | |
284 | +int | |
285 | +main () | |
286 | +{ | |
287 | +extern int volatile _rl_caught_signal; | |
288 | + return _rl_caught_signal; | |
289 | + ; | |
290 | + return 0; | |
291 | +} | |
292 | _ACEOF | |
293 | +if ac_fn_c_try_link "$LINENO"; then : | |
294 | + READLINE_CAUGHT_SIGNAL=yes | |
295 | + | |
296 | +$as_echo "#define HAVE_READLINE_CAUGHT_SIGNAL /**/" >>confdefs.h | |
297 | ||
298 | +else | |
299 | + READLINE_CAUGHT_SIGNAL=no | |
300 | fi | |
301 | -rm -f conftest.err conftest.$ac_objext \ | |
302 | - conftest$ac_exeext conftest.$ac_ext | |
303 | +rm -f core conftest.err conftest.$ac_objext \ | |
304 | + conftest$ac_exeext conftest.$ac_ext | |
305 | + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_CAUGHT_SIGNAL" >&5 | |
306 | +$as_echo "$READLINE_CAUGHT_SIGNAL" >&6; } | |
307 | LIBS="$save_LIBS" | |
308 | - echo "$as_me:$LINENO: result: $READLINE_ECHOING_P" >&5 | |
309 | -echo "${ECHO_T}$READLINE_ECHOING_P" >&6 | |
310 | else | |
311 | READLINE='$(READLINE_DIR)/libreadline.a' | |
312 | READLINE_DEPS='$(READLINE)' |