Bug 17525 - target-async: breakpoint commands not executed when program run from -x script
Summary: target-async: breakpoint commands not executed when program run from -x script
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Pedro Alves
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-30 18:23 UTC by Joel Brobecker
Modified: 2015-01-14 13:48 UTC (History)
2 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 Joel Brobecker 2014-10-30 18:23:28 UTC
We stumbled onto a regression that is making me think we should be making a GDB 7.8.2 release, after all.

On x86_64-linux, with current HEAD or 7.8, consider the following C program:

% cat foo.c
int
increment (int i)
{
  return i + 1;
}

#define N_INCR 20

int
main (void)
{
  int val = 1;
  int j;

  for (j = 0; j < N_INCR; j++)
    val = increment (val);
  return val == N_INCR;
}

And the following GDB script:

% cat cmds.gdb
file foo
break increment
commands
   cont
end
run

The script inserts a breakpoint on a function that gets called repetitively, and adds a commands-list to that breakpoint that just "cont"s (until we reach the end of the program).

However, trying to execute that script by passing it as a -x argument on the command line yields the following behavior:

% /t.a/brobecke/bld/gdb-public/gdb/gdb -q -x cmds.gdb

Breakpoint 1 at 0x40049d: file foo.c, line 4.
Breakpoint 1, increment (i=1) at foo.c:4
4	  return i + 1;

Breakpoint 1, increment (i=2) at foo.c:4
4	  return i + 1;
(gdb)

Adding "maintenance set target-async off" makes the problem disappear.
Comment 1 Joel Brobecker 2014-10-30 18:37:39 UTC
The script works fine when sourced from the GDB prompt, Eg:

    (gdb) source cmds.gdb
    [program runs to completion after hitting breakpoints 20 times]

It also works when the script is piped to GDB's stdin:

    % cat cmds.gdb | gdb

I think the difference is that the script is then executed as part of GDB's global main loop, which calls bpstat_do_actions at the end of each command's execution, whereas "-x cmds.gdb" just results in source_script being called.
The latter ends up executing the "run" command from our script, with the
associated call to bpstat_do_actions, which explains why the commands-list
gets executed once, but then that's it.

Adding bogus commands such as...

   echo
   echo
   echo
   echo

... each cause additional commands to be executed which themselves trigger bpstat_do_actions to be executed, thus each giving us back one of the missing iterations.

But what we need is to be able to loop-until-we're-done after having sourced the script.

One thing thats' interesting which might indicate that I'm missing something is the fact that after the debugger stops (too early), my prompt is not the one I would expect (through .gdbinit). At this point, if:

 - I press ctrl-d, then my normal prompt appears;
 - I type "bogus" as a command, GDB does:

    (gdb) bogus
    Undefined command: "bogus".  Try "help".

 - I type a valid command, the command gets executed, and my program then resumes once:

    (gdb) print 1
    $1 = 1

    Breakpoint 1, increment (i=7) at foo.c:4
    4	  return i + 1;

I have clearly missed something.
Comment 2 Pedro Alves 2015-01-13 19:01:38 UTC
Patch sent:
 https://sourceware.org/ml/gdb-patches/2015-01/msg00353.html
Comment 3 dje 2015-01-13 21:03:54 UTC
As a data point, see also https://sourceware.org/bugzilla/show_bug.cgi?id=17223
Comment 4 cvs-commit@gcc.gnu.org 2015-01-14 12:38:03 UTC
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5589af0e6661abe07e9a997f6324988b4b87c72f

commit 5589af0e6661abe07e9a997f6324988b4b87c72f
Author: Pedro Alves <palves@redhat.com>
Date:   Mon Jan 12 19:30:08 2015 +0000

    PR17525 - breakpoint commands not executed when program run from -x script
    
    Executing a gdb script that runs the inferior (from the command line
    with -x), and has it hit breakpoints with breakpoint commands that
    themselves run the target, is currently broken on async targets
    (Linux, remote).
    
    While we're executing a command list or a script, we force the
    interpreter to be sync, which results in some functions nesting an
    event loop and waiting for the target to stop, instead of returning
    immediately and having the top level event loop handle the stop.
    
    The issue with this bug is simply that bpstat_do_actions misses
    checking whether the interpreter is sync.  When we get here, in the
    case of executing a script (or, when the interpreter is sync), the
    program has already advanced to the next breakpoint, through
    maybe_wait_sync_command_done.  We need to process its breakpoints
    immediately, just like with a sync target.
    
    Tested on x86_64 Fedora 20.
    
    gdb/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    
    	PR gdb/17525
    	* breakpoint.c: Include "interps.h".
    	(bpstat_do_actions_1): Also check whether the interpreter is
    	async.
    
    gdb/testsuite/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    	    Joel Brobecker  <brobecker@adacore.com>
    
    	PR gdb/17525
    	* gdb.base/bp-cmds-execution-x-script.c: New file.
    	* gdb.base/bp-cmds-execution-x-script.exp: New file.
    	* gdb.base/bp-cmds-execution-x-script.gdb: New file.
Comment 5 cvs-commit@gcc.gnu.org 2015-01-14 12:43:33 UTC
The gdb-7.9-branch branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e18fc124cef918e6a7d9de89804850a6f8f765b4

commit e18fc124cef918e6a7d9de89804850a6f8f765b4
Author: Pedro Alves <palves@redhat.com>
Date:   Wed Jan 14 12:38:47 2015 +0000

    PR17525 - breakpoint commands not executed when program run from -x script
    
    Executing a gdb script that runs the inferior (from the command line
    with -x), and has it hit breakpoints with breakpoint commands that
    themselves run the target, is currently broken on async targets
    (Linux, remote).
    
    While we're executing a command list or a script, we force the
    interpreter to be sync, which results in some functions nesting an
    event loop and waiting for the target to stop, instead of returning
    immediately and having the top level event loop handle the stop.
    
    The issue with this bug is simply that bpstat_do_actions misses
    checking whether the interpreter is sync.  When we get here, in the
    case of executing a script (or, when the interpreter is sync), the
    program has already advanced to the next breakpoint, through
    maybe_wait_sync_command_done.  We need to process its breakpoints
    immediately, just like with a sync target.
    
    Tested on x86_64 Fedora 20.
    
    gdb/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    
    	PR gdb/17525
    	* breakpoint.c: Include "interps.h".
    	(bpstat_do_actions_1): Also check whether the interpreter is
    	async.
    
    gdb/testsuite/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    	    Joel Brobecker  <brobecker@adacore.com>
    
    	PR gdb/17525
    	* gdb.base/bp-cmds-execution-x-script.c: New file.
    	* gdb.base/bp-cmds-execution-x-script.exp: New file.
    	* gdb.base/bp-cmds-execution-x-script.gdb: New file.
Comment 6 cvs-commit@gcc.gnu.org 2015-01-14 13:18:07 UTC
The gdb-7.8-branch branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d2c8f4be20a4213ea64b0ede63c2fcde69c637a1

commit d2c8f4be20a4213ea64b0ede63c2fcde69c637a1
Author: Pedro Alves <palves@redhat.com>
Date:   Wed Jan 14 12:38:47 2015 +0000

    PR17525 - breakpoint commands not executed when program run from -x script
    
    Executing a gdb script that runs the inferior (from the command line
    with -x), and has it hit breakpoints with breakpoint commands that
    themselves run the target, is currently broken on async targets
    (Linux, remote).
    
    While we're executing a command list or a script, we force the
    interpreter to be sync, which results in some functions nesting an
    event loop and waiting for the target to stop, instead of returning
    immediately and having the top level event loop handle the stop.
    
    The issue with this bug is simply that bpstat_do_actions misses
    checking whether the interpreter is sync.  When we get here, in the
    case of executing a script (or, when the interpreter is sync), the
    program has already advanced to the next breakpoint, through
    maybe_wait_sync_command_done.  We need to process its breakpoints
    immediately, just like with a sync target.
    
    Tested on x86_64 Fedora 20.
    
    gdb/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    
    	PR gdb/17525
    	* breakpoint.c: Include "interps.h".
    	(bpstat_do_actions_1): Also check whether the interpreter is
    	async.
    
    gdb/testsuite/
    2015-01-14  Pedro Alves  <palves@redhat.com>
    	    Joel Brobecker  <brobecker@adacore.com>
    
    	PR gdb/17525
    	* gdb.base/bp-cmds-execution-x-script.c: New file.
    	* gdb.base/bp-cmds-execution-x-script.exp: New file.
    	* gdb.base/bp-cmds-execution-x-script.gdb: New file.
Comment 7 Pedro Alves 2015-01-14 13:48:27 UTC
Fixed in 7.8, 7.9 and master.