This is the mail archive of the gdb-prs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug breakpoints/17000] user breakpoint not inserted if software-single-step at same location


https://sourceware.org/bugzilla/show_bug.cgi?id=17000

--- Comment #3 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
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  ef370185fcf955b1273c2c6bcbe0b406ec1cbd83 (commit)
      from  c32abae8456a2cb959862626b5ff9ebdd1543514 (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=ef370185fcf955b1273c2c6bcbe0b406ec1cbd83

commit ef370185fcf955b1273c2c6bcbe0b406ec1cbd83
Author: Joel Brobecker <brobecker@adacore.com>
Date:   Tue Jun 3 17:42:19 2014 +0100

    User breakpoint ignored if software-single-step at same location

    with the following code...

        12    Nested;   -- break #1
        13    return I; -- break #2
        14  end;

    (line 12 is a call to function Nested)

    ... we have noticed the following errorneous behavior on ppc-aix,
    where, after having inserted a breakpoint at line 12 and line 13,
    and continuing from the breakpoint at line 12, the program never
    stops at line 13, running away until the program terminates:

        % gdb -q func
        (gdb) b func.adb:12
        Breakpoint 1 at 0x10000a24: file func.adb, line 12.
        (gdb) b func.adb:13
        Breakpoint 2 at 0x10000a28: file func.adb, line 13.
        (gdb) run
        Starting program: /[...]/func

        Breakpoint 1, func () at func.adb:12
        12        Nested;   -- break #1
        (gdb) c
        Continuing.
        [Inferior 1 (process 4128872) exited with code 02]

    When resuming from the first breakpoint, GDB first tries to step out
    of that first breakpoint.  We rely on software single-stepping on this
    platform, and it just so happens that the address of the first
    software single-step breakpoint is the same as the user's breakpoint
    #2 (0x10000a28).  So, with infrun and target traces turned on (but
    uninteresting traces snip'ed off), the "continue" operation looks like
    this:

        (gdb) c
        ### First, we insert the user breakpoints (the second one is an
internal
        ### breakpoint on __pthread_init). The first user breakpoint is not
        ### inserted as we need to step out of it first.
        target_insert_breakpoint (0x0000000010000a28, xxx) = 0
        target_insert_breakpoint (0x00000000d03f3800, xxx) = 0
        ### Then we proceed with the step-out-of-breakpoint...
        infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=1, current
thread [process 15335610] at 0x10000a24
        ### That's when we insert the SSS breakpoints...
        target_insert_breakpoint (0x0000000010000a28, xxx) = 0
        target_insert_breakpoint (0x00000000100009ac, xxx) = 0
        ### ... then let the inferior resume...
        target_resume (15335610, continue, 0)
        infrun: wait_for_inferior ()
        target_wait (-1, status, options={}) = 15335610,   status->kind =
stopped, signal = GDB_SIGNAL_TRAP
        infrun: target_wait (-1, status) =
        infrun:   15335610 [process 15335610],
        infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP
        infrun: infwait_normal_state
        infrun: TARGET_WAITKIND_STOPPED
        infrun: stop_pc = 0x100009ac
        ### At this point, we stopped at the second SSS breakpoint...
        target_stopped_by_watchpoint () = 0
        ### We remove the SSS breakpoints...
        target_remove_breakpoint (0x0000000010000a28, xxx) = 0
        target_remove_breakpoint (0x00000000100009ac, xxx) = 0
        target_stopped_by_watchpoint () = 0
        ### We find that we're not done, so we resume....
        infrun: no stepping, continue
        ### And thus insert the user breakpoints again, except we're not
        ### inserting the second breakpoint?!?
        target_insert_breakpoint (0x0000000010000a24, xxx) = 0
        infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current
thread [process 15335610] at 0x100009ac
        target_resume (-1, continue, 0)
        infrun: prepare_to_wait
        target_wait (-1, status, options={}) = 15335610,   status->kind =
exited, status = 2

    What happens is that the removal of the software single-step
    breakpoints effectively removed the breakpoint instruction from
    inferior memory.  But because such breakpoints are inserted directly
    as raw breakpoints rather than through the normal chain of
    breakpoints, we fail to notice that one of the user breakpoints points
    to the same address and that this user breakpoint is therefore
    effectively un-inserted.  When resuming after the single-step, GDB
    thinks that the user breakpoint is still inserted and therefore does
    not need to insert it again.

    This patch teaches the insert and remove routines of both regular and
    raw breakpoints to be aware of each other.  Special care needs to be
    applied in case the target supports evaluation of breakpoint
    conditions or commands.

    gdb/ChangeLog:

        PR breakpoints/17000
        * breakpoint.c (find_non_raw_software_breakpoint_inserted_here):
        New function, extracted from software_breakpoint_inserted_here_p.
        (software_breakpoint_inserted_here_p): Replace factored out code
        by call to find_non_raw_software_breakpoint_inserted_here.
        (bp_target_info_copy_insertion_state): New function.
        (bkpt_insert_location): Handle the case of a single-step
        breakpoint already inserted at the same address.
        (bkpt_remove_location): Handle the case of a single-step
        breakpoint still inserted at the same address.
        (deprecated_insert_raw_breakpoint): Handle the case of non-raw
        breakpoint already inserted at the same address.
        (deprecated_remove_raw_breakpoint): Handle the case of a
        non-raw breakpoint still inserted at the same address.
        (find_single_step_breakpoint): New function, extracted from
        single_step_breakpoint_inserted_here_p.
        (find_single_step_breakpoint): New function,
        factored out from single_step_breakpoint_inserted_here_p.
        (single_step_breakpoint_inserted_here_p): Reimplement.

    gdb/testsuite/ChangeLog:

        PR breakpoints/17000
        * gdb.base/sss-bp-on-user-bp.exp: Remove kfail.
        * gdb.base/sss-bp-on-user-bp-2.exp: Remove kfail.

    Tested on ppc-aix with AdaCore's testsuite.  Tested on x86_64-linux,
    (native and gdbserver) with the official testsuite.  Also tested on
    x86_64-linux through Pedro's branch enabling software single-stepping
    on that platform (native and gdbserver).

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

Summary of changes:
 gdb/ChangeLog                                  |   23 ++++
 gdb/breakpoint.c                               |  141 +++++++++++++++++++++---
 gdb/testsuite/ChangeLog                        |    7 +
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp |    1 -
 gdb/testsuite/gdb.base/sss-bp-on-user-bp.exp   |    3 +-
 5 files changed, 155 insertions(+), 20 deletions(-)

-- 
You are receiving this mail because:
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]