Bug 17431 - follow-exec, "always-inserted on", breakpoints inserted too soon
Summary: follow-exec, "always-inserted on", breakpoints inserted too soon
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: breakpoints (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 7.9
Assignee: Pedro Alves
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-09-24 14:57 UTC by Pedro Alves
Modified: 2016-08-09 21:05 UTC (History)
0 users

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 Pedro Alves 2014-09-24 14:57:46 UTC
Following an exec with "breakpoint always-inserted on" tries to insert breakpoints in the image at the addresses the symbols had in the old image.

With "always-inserted off", we see:

gdb testsuite/gdb.multi/multi-arch-exec -ex "set breakpoint always-inserted off" -ex "cd testsuite"
GNU gdb (GDB) 7.8.50.20140924-cvs
...
(gdb) b main
Breakpoint 1 at 0x400664: file gdb.multi/multi-arch-exec.c, line 24.
                ^^^^^^^^
(gdb) c
The program is not being run.
(gdb) r
Starting program: testsuite/gdb.multi/multi-arch-exec 

Breakpoint 1, main () at gdb/testsuite/gdb.multi/multi-arch-exec.c:24
24        execl (BASEDIR "/multi-arch-exec-hello",
(gdb) c
Continuing.
process 9212 is executing new program: gdb/testsuite/gdb.multi/multi-arch-exec-hello

Breakpoint 1, main () at gdb/testsuite/gdb.multi/hello.c:40
40        bar();
(gdb) info breakpoints 
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080484e4 in main at gdb/testsuite/gdb.multi/hello.c:40
                                ^^^^^^^^^^
        breakpoint already hit 2 times
(gdb)


Note how main was 0x400664 in multi-arch-exec, but is 0x080484e4 in gdb.multi/hello.

With "always-inserted on", we get:

Breakpoint 1, main () at gdb/testsuite/gdb.multi/multi-arch-exec.c:24
24        execl (BASEDIR "/multi-arch-exec-hello",
(gdb) c
Continuing.
infrun: target_wait (-1, status) =
infrun:   9444 [process 9444],
infrun:   status->kind = execd
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_EXECD
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x400664

(gdb)
Comment 1 Pedro Alves 2014-09-24 14:58:04 UTC
I've got a patch.
Comment 3 cvs-commit@gcc.gnu.org 2014-10-02 09:08:09 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  13fd3ff34329b882503c7c1ef44b3656d6ebb022 (commit)
      from  32990adaadc1b119700cd0dfd2dd8849114e0135 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

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

commit 13fd3ff34329b882503c7c1ef44b3656d6ebb022
Author: Pedro Alves <palves@redhat.com>
Date:   Thu Oct 2 09:55:38 2014 +0100

    PR17431: following execs with "breakpoint always-inserted on"
    
    Following an exec with "breakpoint always-inserted on" tries to insert
    breakpoints in the new image at the addresses the symbols had in the
    old image.
    
    With "always-inserted off", we see:
    
     gdb gdb.multi/multi-arch-exec -ex "set breakpoint always-inserted off"
     GNU gdb (GDB) 7.8.50.20140924-cvs
     ...
     (gdb) b main
     Breakpoint 1 at 0x400664: file gdb.multi/multi-arch-exec.c, line 24.
    		 ^^^^^^^^
     (gdb) c
     The program is not being run.
     (gdb) r
     Starting program: testsuite/gdb.multi/multi-arch-exec
    
     Breakpoint 1, main () at gdb/testsuite/gdb.multi/multi-arch-exec.c:24
     24        execl (BASEDIR "/multi-arch-exec-hello",
     (gdb) c
     Continuing.
     process 9212 is executing new program: gdb/testsuite/gdb.multi/multi-arch-exec-hello
    
     Breakpoint 1, main () at gdb/testsuite/gdb.multi/hello.c:40
     40        bar();
     (gdb) info breakpoints
     Num     Type           Disp Enb Address    What
     1       breakpoint     keep y   0x080484e4 in main at gdb/testsuite/gdb.multi/hello.c:40
    				 ^^^^^^^^^^
    	 breakpoint already hit 2 times
     (gdb)
    
    Note how main was 0x400664 in multi-arch-exec, and 0x080484e4 in
    gdb.multi/hello.
    
    With "always-inserted on", we get:
    
     Breakpoint 1, main () at gdb/testsuite/gdb.multi/multi-arch-exec.c:24
     24        execl (BASEDIR "/multi-arch-exec-hello",
     (gdb) c
     Continuing.
     infrun: target_wait (-1, status) =
     infrun:   9444 [process 9444],
     infrun:   status->kind = execd
     infrun: infwait_normal_state
     infrun: TARGET_WAITKIND_EXECD
     Warning:
     Cannot insert breakpoint 1.
     Cannot access memory at address 0x400664
    
    (gdb)
    
    That is, GDB is trying to insert a breakpoint at 0x400664, after the
    exec, and then that address happens to not be mapped at all in the new
    image.
    
    The problem is that update_breakpoints_after_exec is creating
    breakpoints, which ends up in update_global_location_list immediately
    inserting breakpoints if "breakpoints always-inserted" is "on".
    update_breakpoints_after_exec is called very early when we see an exec
    event.  At that point, we haven't loaded the symbols of the new
    post-exec image yet, and thus haven't reset breakpoint's addresses to
    whatever they may be in the new image.  All we should be doing in
    update_breakpoints_after_exec is deleting breakpoints that no longer
    make sense after an exec.  So the fix removes those breakpoint
    creations.
    
    The question is then, if not here, where are those breakpoints
    re-created?  Turns out we don't need to do anything else, because at
    the end of follow_exec, we call breakpoint_re_set, whose tail is also
    creating exactly the same breakpoints update_breakpoints_after_exec is
    currently creating:
    
      breakpoint_re_set (void)
      {
      ...
        create_overlay_event_breakpoint ();
        create_longjmp_master_breakpoint ();
        create_std_terminate_master_breakpoint ();
        create_exception_master_breakpoint ();
      }
    
    A new test is added to exercise this.
    
    Tested on x86_64 Fedora 20.
    
    gdb/
    2014-10-02  Pedro Alves  <palves@redhat.com>
    
    	PR breakpoints/17431
    	* breakpoint.c (update_breakpoints_after_exec): Don't create
    	overlay, longjmp, std terminate nor exception breakpoints here.
    
    gdb/testsuite/
    2014-10-02  Pedro Alves  <palves@redhat.com>
    
    	PR breakpoints/17431
    	* gdb.base/execl-update-breakpoints.c: New file.
    	* gdb.base/execl-update-breakpoints.exp: New file.

-----------------------------------------------------------------------

Summary of changes:
 gdb/ChangeLog                                      |    6 +
 gdb/breakpoint.c                                   |    5 -
 gdb/testsuite/ChangeLog                            |    6 +
 gdb/testsuite/gdb.base/execl-update-breakpoints.c  |   38 +++++++
 .../gdb.base/execl-update-breakpoints.exp          |  114 ++++++++++++++++++++
 5 files changed, 164 insertions(+), 5 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/execl-update-breakpoints.c
 create mode 100644 gdb/testsuite/gdb.base/execl-update-breakpoints.exp
Comment 4 Pedro Alves 2014-10-02 16:14:16 UTC
Fixed.
Comment 5 Pedro Alves 2016-08-09 21:05:11 UTC
Actually closing.