public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
@ 2021-01-26 10:04 vries at gcc dot gnu.org
  2021-01-26 10:06 ` [Bug python/27247] " vries at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2021-01-26 10:04 UTC (permalink / raw)
  To: gdb-prs

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

            Bug ID: 27247
           Summary: FAIL: gdb.python/py-finish-breakpoint2.exp: check
                    FinishBreakpoint in catch()
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: python
          Assignee: unassigned at sourceware dot org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

[ Refiling
https://sourceware.org/pipermail/gdb-patches/2021-January/175166.html as PR. ]

When running test-case gdb.python/py-finish-breakpoint2.exp with target board
unix/-m32, we run into:
...
FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
FAIL: gdb.python/py-finish-breakpoint2.exp: check finish BP removal
FAIL: gdb.python/py-finish-breakpoint2.exp: continue to second exception
FAIL: gdb.python/py-finish-breakpoint2.exp: set FinishBP after the exception
...

The first FAIL in more detail:
...
(gdb) continue^M
Continuing.^M
Exception #10^M
^M
Breakpoint 3, throw_exception_1 (e=10) at py-finish-breakpoint2.cc:23^M
23        throw new int (e);^M
(gdb) FAIL: gdb.python/py-finish-breakpoint2.exp: \
  check FinishBreakpoint in catch()
...

With -m64, the test passes.

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
@ 2021-01-26 10:06 ` vries at gcc dot gnu.org
  2022-12-16 10:57 ` vries at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2021-01-26 10:06 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
Relevant bit of the source:
...
    36    try
    37      {
    38        throw_exception_1 (10);
    39      }
    40    catch (const int *e)
    41      {
    42          std::cerr << "Exception #" << *e << std::endl;
    43      }
    44    i += 1; /* Break after exception 1.  */
...

The -m64 scenario in more detail:
- the test-case runs to throw_exception_1.
- it installs a FinishBreakpoint, which is a temporary breakpoint set at the
  return address of a frame.
- for -m64, that address is:
    400c47:       83 45 e4 01             addl   $0x1,-0x1c(%rbp)
  which corresponds the "i += 1 at line 44"
- the test-case then continues
- an exception is throw in throw_execution_1
- the exception is caught at line 40, and a message is printed
- line 44 is executed, and the FinishBreakpoint triggers.

With -m32, we have instead:
- the address where the finish breakpoint is set is:
    8048a0a:       83 c4 10                add    $0x10,%esp
  which is the lasn insn generated for the call at line 38
- the test-case continues
- an exception is throw in throw_execution_1
- consequently, the FinishBreakpoint is not triggered.

In conclusion, the test works by accident for -m64, because the first insn
after the call to throw_exception_1 is also the first insn after the try.
And that just happens to be not the case for -m32.

[ This was also noted by Andrew here (
https://sourceware.org/pipermail/gdb-patches/2012-September/096347.html ):
...
A further issue is that the testing for FinishBreakpoints, in
gdb/testsuite/gdb.python/py-finish-breakpoint2.exp, the test action titled
"check FinishBreakpoint in catch()" expects the "stop" method to fire rather
than the "out_of_scope" method, this is due to the generated code (on x86 and
maybe other targets), the first breakpoint we hit after throwing the exception
happens to be the finish breakpoint, however this is not guaranteed, and means
that (a) the test does not match the documentation, and (b) the test is
platform specific.
... ]

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
  2021-01-26 10:06 ` [Bug python/27247] " vries at gcc dot gnu.org
@ 2022-12-16 10:57 ` vries at gcc dot gnu.org
  2022-12-16 11:38 ` vries at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2022-12-16 10:57 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
Created attachment 14521
  --> https://sourceware.org/bugzilla/attachment.cgi?id=14521&action=edit
Tentative patch

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
  2021-01-26 10:06 ` [Bug python/27247] " vries at gcc dot gnu.org
  2022-12-16 10:57 ` vries at gcc dot gnu.org
@ 2022-12-16 11:38 ` vries at gcc dot gnu.org
  2022-12-16 13:23 ` vries at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2022-12-16 11:38 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #3 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Tom de Vries from comment #2)
> Created attachment 14521 [details]
> Tentative patch

Hmm, reading over Andrew's submission, I've come to the same solution as him,
the tentative patch just tries to solve less problems.

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2022-12-16 11:38 ` vries at gcc dot gnu.org
@ 2022-12-16 13:23 ` vries at gcc dot gnu.org
  2022-12-31  7:51 ` cvs-commit at gcc dot gnu.org
  2022-12-31  7:53 ` vries at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2022-12-16 13:23 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
https://sourceware.org/pipermail/gdb-patches/2022-December/194821.html

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2022-12-16 13:23 ` vries at gcc dot gnu.org
@ 2022-12-31  7:51 ` cvs-commit at gcc dot gnu.org
  2022-12-31  7:53 ` vries at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-12-31  7:51 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #5 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

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

commit 64760036a846099158bb2bab5370ae033dde8db0
Author: Tom de Vries <tdevries@suse.de>
Date:   Sat Dec 31 08:51:40 2022 +0100

    [gdb/python] Fix gdb.python/py-finish-breakpoint2.exp for -m32

    [ Partial resubmission of an earlier submission by Andrew (
    https://sourceware.org/pipermail/gdb-patches/2012-September/096347.html ),
so
    listing him as co-author. ]

    With x86_64-linux and target board unix/-m32, we have:
    ...
    (gdb) continue^M
    Continuing.^M
    Exception #10^M
    ^M
    Breakpoint 3, throw_exception_1 (e=10) at py-finish-breakpoint2.cc:23^M
    23        throw new int (e);^M
    (gdb) FAIL: gdb.python/py-finish-breakpoint2.exp: \
      check FinishBreakpoint in catch()
    ...

    The following scenario happens:
    - set breakpoint in throw_exception_1, a function that throws an exception
    - continue
    - hit breakpoint, with call stack main.c:38 -> throw_exception_1
    - set a finish breakpoint
    - continue
    - hit the breakpoint again, with call stack main.c:48 -> throw_exception
      -> throw_exception_1

    Due to the exception, the function call did not properly terminate, and the
    finish breakpoint didn't trigger.  This is expected behaviour.

    However, the intention is that gdb detects this situation at the next stop
    and calls the out_of_scope callback, which would result here in this
test-case
    in a rather confusing "exception did not finish" message.  So the problem
is
    that this message doesn't show up, in other words, the out_of_scope
callback
    is not called.

    [ Note that the fact that the situation is detected only at the next stop
    (wherever that happens to be) could be improved upon, and the earlier
    submission did that by setting a longjmp breakpoint.  But I'm considering
this
    problem out-of-scope for this patch. ]

    Note that the message does show up later, at thread exit:
    ...
    [Inferior 1 (process 20046) exited with code 0236]^M
    exception did not finish ...^M
    ...

    The decision on whether to call the out_of_scope call back is taken in
    bpfinishpy_detect_out_scope_cb, and the interesting bit is here:
    ...
                 if (b->pspace == current_inferior ()->pspace
                     && (!target_has_registers ()
                         || frame_find_by_id (b->frame_id) == NULL))
                   bpfinishpy_out_of_scope (finish_bp);
    ...

    In the case of the thread exit, the callback triggers because
    target_has_registers () == 0.

    So why doesn't the callback trigger in the case of the breakpoint?

    Well, the b->frame_id is the frame_id of the frame of main (the frame
    in which the finish breakpoint is supposed to trigger), so AFAIU
    frame_find_by_id (b->frame_id) == NULL will only be true once we've
    left main, at which point I guess we don't stop till thread exit.

    Fix this by saving the frame in which the finish breakpoint was created,
and
    using frame_find_by_id () == NULL on that frame instead, such that we have:
    ...
    (gdb) continue^M
    Continuing.^M
    Exception #10^M
    ^M
    Breakpoint 3, throw_exception_1 (e=10) at py-finish-breakpoint2.cc:23^M
    23        throw new int (e);^M
    exception did not finish ...^M
    (gdb) FAIL: gdb.python/py-finish-breakpoint2.exp: \
      check FinishBreakpoint in catch()
    ...

    Still, the test-case is failing because it's setup to match the behaviour
that
    we get on x86_64-linux with target board unix/-m64:
    ...
    (gdb) continue^M
    Continuing.^M
    Exception #10^M
    stopped at ExceptionFinishBreakpoint^M
    (gdb) PASS: gdb.python/py-finish-breakpoint2.exp: \
      check FinishBreakpoint in catch()
    ...

    So what happens here?  Again, due to the exception, the function call did
not
    properly terminate, but the finish breakpoint still triggers.  This is
somewhat
    unexpected.  This happens because it just so happens to be that the frame
    return address at which the breakpoint is set, is also the first
instruction
    after the exception has been handled.  This is a know problem, filed as
    PR29909, so KFAIL it, and modify the test-case to expect the out_of_scope
    callback.

    Also add a breakpoint after setting the finish breakpoint but before
throwing
    the exception, to check that we don't call the out_of_scope callback too
early.

    Tested on x86_64-linux, with target boards unix/-m32.

    Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
    PR python/27247
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27247

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug python/27247] FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
  2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2022-12-31  7:51 ` cvs-commit at gcc dot gnu.org
@ 2022-12-31  7:53 ` vries at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: vries at gcc dot gnu.org @ 2022-12-31  7:53 UTC (permalink / raw)
  To: gdb-prs

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

Tom de Vries <vries at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED
   Target Milestone|---                         |14.1

--- Comment #6 from Tom de Vries <vries at gcc dot gnu.org> ---
Fixed by commit.

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-12-31  7:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-26 10:04 [Bug python/27247] New: FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch() vries at gcc dot gnu.org
2021-01-26 10:06 ` [Bug python/27247] " vries at gcc dot gnu.org
2022-12-16 10:57 ` vries at gcc dot gnu.org
2022-12-16 11:38 ` vries at gcc dot gnu.org
2022-12-16 13:23 ` vries at gcc dot gnu.org
2022-12-31  7:51 ` cvs-commit at gcc dot gnu.org
2022-12-31  7:53 ` vries at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).