Bug 16809 - interrupt -a
Summary: interrupt -a
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 7.7
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-04-04 20:00 UTC by dilyan.palauzov@aegee.org
Modified: 2014-07-15 21:21 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dilyan.palauzov@aegee.org 2014-04-04 20:00:25 UTC
The documentation of "interrupt -a" (node:Background Execution) shall state, that pressing subsequent <RET> does not repeat the command.

This shall be also explicitly stated for the run command, on the place, where the run command is described (node:Starting your program).  This is indeed mentioned for the run command as an example in node:Command syntax, third paragraph, but shall come also where the run command is defined.  E.g. the doucmentation of "attach PROCESS-ID" explicitly states, that <RET> does not repleat the command.

When I run a multi-threaded program with 
set target-async on<RET>
set non-stop on<RET>
run &<RET>
interrupa -a<RET>
<RET>
<RET>

gdb crashes with this backtrace, after printing "readline_callback_read_char() called with no handler!".  Please note, that pagination was on, and I used CLI.

#0  0x00007f29de37a425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#1  0x00007f29de37db8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
No symbol table info available.
#2  0x00000000006a786c in rl_callback_read_char () at ../../../gdb-7.7/readline/callback.c:116
        line = <optimized out>
        eof = <optimized out>
        jcode = <optimized out>
        olevel =           {{__jmpbuf =               {140733193388032,
              -7829082926268286128,
              140733776165500,
              140733776165500,
              0,
              45265200,
              7829445567969491792,
              -7829082536481260720}, __mask_was_saved = 1, __saved_mask = {__val =                 {
                4294967296,
                0 <repeats 15 times>}}}}
#3  0x00000000005a6c19 in rl_callback_read_char_wrapper (client_data=<optimized out>)
    at ../../../gdb-7.7/gdb/event-top.c:164
No locals.
#4  0x00000000005a5e23 in process_event () at ../../../gdb-7.7/gdb/event-loop.c:342
        event_ptr = <optimized out>
        proc = 0x5a5490 <handle_file_event>
        data = {ptr = 0x0, integer = 0}
#5  process_event () at ../../../gdb-7.7/gdb/event-loop.c:314
No locals.
#6  0x00000000005a61df in gdb_do_one_event () at ../../../gdb-7.7/gdb/event-loop.c:406
        event_source_head = 0
        current = <optimized out>
#7  0x0000000000660c05 in gdb_readline_wrapper (
    prompt=prompt@entry=0x7fff22bc52c0 "---Type <return> to continue, or q <return> to quit---")
    at ../../../gdb-7.7/gdb/top.c:815
        back_to = 0x7003ba0
        cleanup = <optimized out>
        retval = <optimized out>
        __PRETTY_FUNCTION__ =           "gdb_readline_wrapper"
#8  0x00000000006639bf in prompt_for_continue () at ../../../gdb-7.7/gdb/utils.c:1837
        ignore = <optimized out>
        cont_prompt =           "---Type <return> to continue, or q <return> to quit---\000\000\335<;\336)\177\000\000\000\000\000\000\000\000\000\000\n\000\000\000\000\000\000\000\310\305{\000\000\000\000\000\360\360\304\002\000\000\000\000\020\025\275\002\000\000\000\000\315\062f\000\000\000\000\000\257Y\000\000\000\000\000"
        prompt_started = {tv_sec = 1396535734, tv_usec = 663351}
        prompt_ended = {tv_sec = 139817802261088, tv_usec = 140733776155456}
        prompt_delta = {tv_sec = 0, tv_usec = 139817798856373}
#9  0x000000000066404d in fputs_maybe_filtered (linebuffer=<optimized out>, stream=<optimized out>, 
    filter=1) at ../../../gdb-7.7/gdb/utils.c:2054
        lineptr = 0x7bc5c8 "["
#10 0x0000000000591416 in print_signal_received_reason (siggnal=<optimized out>)
    at ../../../gdb-7.7/gdb/infrun.c:5958
        t = 0x5d6b140
        uiout = 0x2e18dc0
#11 handle_signal_stop (ecs=0x7fff22bc5510) at ../../../gdb-7.7/gdb/infrun.c:4337
        printed = 1
        inf = 0x2bfcdf0
        stop_signal = <optimized out>
        frame = 0x2bd1510
        gdbarch = <optimized out>
        stopped_by_watchpoint = <optimized out>
        stop_soon = NO_STOP_QUIETLY
        random_signal = <optimized out>
#12 handle_inferior_event (ecs=0x7fff22bc5510) at ../../../gdb-7.7/gdb/infrun.c:3745
        stop_soon = NO_STOP_QUIETLY
#13 handle_inferior_event (ecs=0x7fff22bc5510) at ../../../gdb-7.7/gdb/infrun.c:3191
No locals.
#14 0x0000000000591995 in fetch_inferior_event (client_data=client_data@entry=0x0)
    at ../../../gdb-7.7/gdb/infrun.c:2858
        ecss = {ptid = {pid = 22939, lwp = 22959, tid = 0}, event_thread = 0x5d6b140, ws = {
            kind = TARGET_WAITKIND_STOPPED, value = {integer = 0, sig = GDB_SIGNAL_0, related_pid = {
                pid = 0, lwp = 0, tid = 0}, execd_pathname = 0x0, syscall_number = 0}}, 
          stop_func_filled_in = 0, stop_func_start = 0, stop_func_end = 0, stop_func_name = 0x0, 
          wait_some_more = 0, stepped_after_stopped_by_watchpoint = 0}
        ecs = 0x7fff22bc5510
        old_chain = 0x7a7fc0 <sentinel_cleanup>
        ts_old_chain = 0x2dcadd0
        was_sync = 0
        cmd_done = 0
#15 0x00000000005a7a59 in fetch_inferior_event_wrapper (client_data=client_data@entry=0x0)
    at ../../../gdb-7.7/gdb/inf-loop.c:145
No locals.
#16 0x000000000059df4e in catch_errors (func=func@entry=0x5a7a50 <fetch_inferior_event_wrapper>, 
    func_args=func_args@entry=0x0, errstring=errstring@entry=0x7682f0 "", 
    mask=mask@entry=RETURN_MASK_ALL) at ../../../gdb-7.7/gdb/exceptions.c:524
        val = 0
        exception = {reason = 0, error = GDB_NO_ERROR, message = 0x0}
        saved_uiout = 0x2e18dc0
#17 0x00000000005a7adf in inferior_event_handler (event_type=INF_REG_EVENT, client_data=0x0)
    at ../../../gdb-7.7/gdb/inf-loop.c:53
        cleanup_if_error = 0x7a7fc0 <sentinel_cleanup>
#18 0x00000000005a5e23 in process_event () at ../../../gdb-7.7/gdb/event-loop.c:342
        event_ptr = <optimized out>
        proc = 0x5a5490 <handle_file_event>
        data = {ptr = 0x7fff00000007, integer = 7}
#19 process_event () at ../../../gdb-7.7/gdb/event-loop.c:314
No locals.
#20 0x00000000005a61af in gdb_do_one_event () at ../../../gdb-7.7/gdb/event-loop.c:394
        event_source_head = 0
        current = <optimized out>
#21 0x00000000005a6365 in start_event_loop () at ../../../gdb-7.7/gdb/event-loop.c:431
        ex = {reason = 0, error = GDB_NO_ERROR, message = 0x0}
        result = 0
#22 0x000000000059fa13 in captured_command_loop (data=data@entry=0x0) at ../../../gdb-7.7/gdb/main.c:267
No locals.
#23 0x000000000059df4e in catch_errors (func=func@entry=0x59fa00 <captured_command_loop>, 
    func_args=func_args@entry=0x0, errstring=errstring@entry=0x7682f0 "", 
    mask=mask@entry=RETURN_MASK_ALL) at ../../../gdb-7.7/gdb/exceptions.c:524
        val = 0
        exception = {reason = 0, error = GDB_NO_ERROR, message = 0x0}
        saved_uiout = 0x2e18dc0
#24 0x00000000005a025e in captured_main (data=data@entry=0x7fff22bc58b0)
    at ../../../gdb-7.7/gdb/main.c:1067
        context = 0x7fff22bc58b0
        argc = <optimized out>
        argv = <optimized out>
        quiet = 1
        set_args = 0
        inhibit_home_gdbinit = 0
        symarg = 0x7fff22bc7a7c "./ConGWd"
        execarg = 0x7fff22bc7a7c "./ConGWd"
        pidarg = 0x0
        corearg = 0x0
        pid_or_core_arg = 0x0
        cdarg = 0x0
        ttyarg = 0x0
        print_help = 0
        print_version = 0
        print_configuration = 0
        cmdarg_vec = 0x0
        cmdarg_p = 0x0
        dirarg = 0x2b2b130
        dirsize = <optimized out>
        ndir = 0
        system_gdbinit = 0x0
        home_gdbinit = 0x2d1c3f0 "/home/dilyan/.gdbinit"
        local_gdbinit = 0x0
        i = <optimized out>
        save_auto_load = <optimized out>
        objfile = <optimized out>
        pre_stat_chain = 0x7a7fc0 <sentinel_cleanup>
#25 0x000000000059df4e in catch_errors (func=func@entry=0x59fbf0 <captured_main>, 
    func_args=func_args@entry=0x7fff22bc58b0, errstring=errstring@entry=0x7682f0 "", 
    mask=mask@entry=RETURN_MASK_ALL) at ../../../gdb-7.7/gdb/exceptions.c:524
        val = 0
        exception = {reason = 0, error = GDB_NO_ERROR, message = 0x0}
        saved_uiout = 0xb95ba0 <def_uiout>
#26 0x00000000005a0ba4 in gdb_main (args=args@entry=0x7fff22bc58b0) at ../../../gdb-7.7/gdb/main.c:1076
No locals.
#27 0x000000000045b01e in main (argc=<optimized out>, argv=<optimized out>)
    at ../../../gdb-7.7/gdb/gdb.c:34
        args = {argc = 4, argv = 0x7fff22bc59b8, use_windows = 0, interpreter_p = 0x75c324 "console"}
  Id   Target Id         Frame 
* 1    Thread 0x7f29dffa5700 (LWP 22937) 0x00007f29de37a425 in raise ()
   from /lib/x86_64-linux-gnu/libc.so.6
Comment 1 Doug Evans 2014-07-12 19:02:02 UTC
See also bug 14236.
I'd be interested to know if the patch for that fixes this (possible).
Comment 2 dilyan.palauzov@aegee.org 2014-07-13 21:58:16 UTC
I use gdb-7.7.1 and the changes from https://sourceware.org/ml/gdb-patches/2014-07/msg00304.html were already applied.

In 7.7.1 I applied only the patch from gdb/infcmd.c on interrupt_target_command(), because there is no interrupt_command().  I cannot link gdb:

infcmd.o: In function `wait_thread_stopped':
gdb-7.7.1/gdb/infcmd.c:2818: undefined reference to `print_stop_event'
infcmd.o: In function `interrupt_target_command':
gdb-7.7.1/gdb/infcmd.c:2921: undefined reference to `prepare_execution_command'

Please provide patch toward gdb771.

Sample program, that leads to the described error:

#include <iostream>
#include <unistd.h>
#include <thread>

void f() {
  std::cout << "A" << std::endl;
  sleep (10);
  std::cout << "Z" << std::endl;
}

int main() {
  std::thread t1 { f }; std::thread t2 { f };
  std::thread t3 { f }; std::thread t4 { f };
  std::thread t5 { f }; std::thread t6 { f };
  std::thread t7 { f }; std::thread t8 { f };
  std::thread t9 { f }; std::thread t10 { f };
  std::thread t11 { f }; std::thread t12 { f };
  sleep (15);
  t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join();
  t7.join(); t8.join(); t9.join(); t10.join(); t11.join(); t12.join();
}
Comment 3 dilyan.palauzov@aegee.org 2014-07-13 23:30:41 UTC
I applied the patches from Bug 14236 against the master branch.  gdb still crashes with the message:
  readline: readline_callback_read_char() called with no handler!

I call "interrupt -a &", as without the ampersand the control does not return to the CLI (and thus I cannot execute several <RET>s after the "interrupt -a" command).
Comment 4 Doug Evans 2014-07-14 00:18:59 UTC
(In reply to dilyan.palauzov@aegee.org from comment #3)
> I applied the patches from Bug 14236 against the master branch.  gdb still
> crashes with the message:
>   readline: readline_callback_read_char() called with no handler!
> 
> I call "interrupt -a &", as without the ampersand the control does not
> return to the CLI (and thus I cannot execute several <RET>s after the
> "interrupt -a" command).

Thanks.
Can I trouble you to include the backtrace (since you were gracious enough to include one for 7.7)?  Thanks!
Comment 5 Doug Evans 2014-07-14 00:30:32 UTC
(In reply to Doug Evans from comment #4)
> (In reply to dilyan.palauzov@aegee.org from comment #3)
> > I applied the patches from Bug 14236 against the master branch.  gdb still
> > crashes with the message:
> >   readline: readline_callback_read_char() called with no handler!
> > 
> > I call "interrupt -a &", as without the ampersand the control does not
> > return to the CLI (and thus I cannot execute several <RET>s after the
> > "interrupt -a" command).
> 
> Thanks.
> Can I trouble you to include the backtrace (since you were gracious enough
> to include one for 7.7)?  Thanks!

No need, thanks.
I was able to repro this with the following script.

---snip---
set trace-commands on
set height 22
set editing on
set non-stop on
file ~/src/play/16809.x64
run &
interrupt -a &
---snip---

bash$ ./gdb -D ./data-directory <foo.gdb

One may have to experiment with the value of height in order to trigger the bug.
22 worked for me.
Comment 6 Doug Evans 2014-07-14 00:51:33 UTC
(In reply to Doug Evans from comment #5)
> (In reply to Doug Evans from comment #4)
> > (In reply to dilyan.palauzov@aegee.org from comment #3)
> > > I applied the patches from Bug 14236 against the master branch.  gdb still
> > > crashes with the message:
> > >   readline: readline_callback_read_char() called with no handler!
> > > 
> > > I call "interrupt -a &", as without the ampersand the control does not
> > > return to the CLI (and thus I cannot execute several <RET>s after the
> > > "interrupt -a" command).
> > 
> > Thanks.
> > Can I trouble you to include the backtrace (since you were gracious enough
> > to include one for 7.7)?  Thanks!
> 
> No need, thanks.
> I was able to repro this with the following script.
> 
> ---snip---
> set trace-commands on
> set height 22
> set editing on
> set non-stop on
> file ~/src/play/16809.x64
> run &
> interrupt -a &
> ---snip---

Correction, cut-n-paste error.

---snip---
set trace-commands on
set height 22
set editing on
set non-stop on
file ~/src/play/16809.x64
run &
interrupt -a &





---snip---
Comment 7 Doug Evans 2014-07-14 03:10:16 UTC
Data point:
I can crash gdb in a similar way by applying this patch to an unpatched copy of trunk, and then using the following script.

---snip--- patch
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 15902d8..2628fba 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -823,7 +823,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
       if (library == NULL)
        library = LIBTHREAD_DB_SO;
 
-      printf_unfiltered (_("Using host libthread_db library \"%s\".\n"),
+      printf_filtered (_("Using host libthread_db library \"%s\".\n"),
                         library);
     }
 
---snip---

---snip--- foo.gdb
set editing on
set height 2
file ~/src/play/forever-threads.x64
run &

shell sleep 1



---snip---

forever-threads.x64 is the testcase from bug 17147.

Repro:

[dje@seba gdb]$ ./gdb -D ./data-directory <foo.gdb 
GNU gdb (GDB) 7.8.50.20140712-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) (gdb) set height 2
(gdb) file ~/src/play/forever-threads.x64
Reading symbols from ~/src/play/forever-threads.x64...done.
(gdb) run &
---Type <return> to continue, or q <return> to quit---
Starting program: /home/dje/src/play/forever-threads.x64 
(gdb) shell sleep 1
(gdb) 
(gdb) [Thread debugging using libthread_db enabled]
---Type <return> to continue, or q <return> to quit---
Using host libthread_db library "/lib64/libthread_db.so.1".
readline: readline_callback_read_char() called with no handler!
Aborted (core dumped)
Comment 8 dje 2014-07-15 06:18:12 UTC
For reference sake, see also bug 17072.
Comment 9 Pedro Alves 2014-07-15 08:19:32 UTC
The patches for PR17072 are now in both master and the 7.8 branch.  Does this readline abort still trigger ?
Comment 10 dilyan.palauzov@aegee.org 2014-07-15 19:48:32 UTC
The readline abort does not trigger anymore.

However, when I do "interrupt -a", gdb prints the prompt, followed by information about individual threads, and eventually puts the cursor on a very biginning of new line (not immediately after the prompt).  This unclear state was the reason to press several times <RET> and to discover this bug.

Does pagination still break non-stop?  If not, remove the relevant text from gdb/doc/gdb.texinfo , node "Non-Stop mode", line 5781-5784.
Comment 11 Doug Evans 2014-07-15 19:58:11 UTC
(In reply to dilyan.palauzov@aegee.org from comment #10)
> However, when I do "interrupt -a", gdb prints the prompt, followed by
> information about individual threads, and eventually puts the cursor on a
> very biginning of new line (not immediately after the prompt).  This unclear
> state was the reason to press several times <RET> and to discover this bug.
> 
> Does pagination still break non-stop?  If not, remove the relevant text from
> gdb/doc/gdb.texinfo , node "Non-Stop mode", line 5781-5784.

The issue here is that messages can be printed by gdb (e.g. to report thread state changes) even while gdb is at the prompt waiting for user input.  This is gdb's async mode and it's now the default.  The "interrupt" command has a bug in that it operates asynchronously (as if you had added a "&") by default.
What should happen is that "interrupt" or "interrupt -a" without an "&" should operate synchronously and not print the gdb prompt until the command has succeeded (just like commands that resume the inferior like run, continue, etc.).
Comment 12 Doug Evans 2014-07-15 19:59:54 UTC
(In reply to Doug Evans from comment #11)
> What should happen is that "interrupt" or "interrupt -a" without an "&"
> should operate synchronously and not print the gdb prompt until the command
> has succeeded (just like commands that resume the inferior like run,

s/succeeded/completed/

> continue, etc.).
Comment 13 Pedro Alves 2014-07-15 21:21:39 UTC
> Does pagination still break non-stop?  If not, remove the relevant text from
> gdb/doc/gdb.texinfo , node "Non-Stop mode", line 5781-5784.

Yeah, that text could use an update / clarification, thanks.

It doesn't break it in the sense that there are no other known issues that weren't fixed by the fixes for PR17072 (both in master and 7.8).

But it still "breaks" it in the sense that if pagination occurs, target event processing is paused until the user proceeds with the pagination.  So, e.g., if the target needs hits a breakpoint that isn't supposed to be reported and needs to be stepped over, it'll remain paused until the pagination is proceeded.