public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate
@ 2013-01-09 13:45 tobias at ringis dot se
  2013-01-09 13:52 ` [Bug c++/55918] " redi at gcc dot gnu.org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: tobias at ringis dot se @ 2013-01-09 13:45 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

             Bug #: 55918
           Summary: Stack partially unwound when noexcept causes call to
                    std::terminate
    Classification: Unclassified
           Product: gcc
           Version: 4.7.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: tobias@ringis.se


Created attachment 29123
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29123
Test program to illustrate the problem

When a noexcept function is "violated", std::terminate is called.  While the
standard allows for the stack to be fully unwound, partially unwound, or not
unwound at all, it is impossible to find the location where the exception was
thrown, unless the stack is left unwound.

GCC currently leaves the stack unwound in most cases, but in a very common
case, which is illustrated by the attached example program, the stack is
partially unwound.

If the noexcept is removed to allow the exception to propagate all the way past
main, std::terminate is called with the stack fully unwound, so it seems that
GCC is able to do what I want. It would be highly desirable for the noexcept
case to work in the same way as the unhandled exception case.

# g++ -std=c++0x -g tmp3.cpp
# gdb a.out
[...]
(gdb) bt
#0  0x000000318f036285 in raise () from /lib64/libc.so.6
#1  0x000000318f037b9b in abort () from /lib64/libc.so.6
#2  0x00000031964bbc5d in __gnu_cxx::__verbose_terminate_handler() ()
   from /usr/lib64/libstdc++.so.6
#3  0x00000031964b9e16 in ?? () from /usr/lib64/libstdc++.so.6
#4  0x00000031964b8e49 in ?? () from /usr/lib64/libstdc++.so.6
#5  0x00000031964b973d in __gxx_personality_v0 ()
   from /usr/lib64/libstdc++.so.6
#6  0x000000319000f6fb in ?? () from /lib64/libgcc_s.so.1
#7  0x000000319000fb58 in _Unwind_Resume () from /lib64/libgcc_s.so.1
#8  0x0000000000400911 in level2 () at tmp3.cpp:16
#9  0x000000000040091a in level1 () at tmp3.cpp:20
#10 0x0000000000400925 in main () at tmp3.cpp:24

As you can see, bad_guy is not in the backtrace.

There are two simple modifications that makes the backtrace complete. The first
is to remove the noexcept from level1, and the second is to remove the Foo
declaration in level2 (or delete Foo's destructor).


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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
@ 2013-01-09 13:52 ` redi at gcc dot gnu.org
  2013-01-09 14:43 ` jason at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2013-01-09 13:52 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2013-01-09
                 CC|                            |jason at gcc dot gnu.org
     Ever Confirmed|0                           |1

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-01-09 13:52:18 UTC ---
I guess Jason can say whether this is a bug in the current behaviour or if your
request should be severity=enhancement, but at the very least we need to
document the intended behaviour at
http://gcc.gnu.org/onlinedocs/gcc/Exception-handling.html


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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
  2013-01-09 13:52 ` [Bug c++/55918] " redi at gcc dot gnu.org
@ 2013-01-09 14:43 ` jason at gcc dot gnu.org
  2013-01-09 17:39 ` tobias at ringis dot se
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: jason at gcc dot gnu.org @ 2013-01-09 14:43 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

--- Comment #2 from Jason Merrill <jason at gcc dot gnu.org> 2013-01-09 14:42:54 UTC ---
If you're looking for 'bad_guy' to be in the backtrace, that sounds to me like
you want it to not be unwound at all, and I'm surprised that it doesn't already
work that way.


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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
  2013-01-09 13:52 ` [Bug c++/55918] " redi at gcc dot gnu.org
  2013-01-09 14:43 ` jason at gcc dot gnu.org
@ 2013-01-09 17:39 ` tobias at ringis dot se
  2021-11-15  1:13 ` foom at fuhm dot net
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: tobias at ringis dot se @ 2013-01-09 17:39 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

--- Comment #3 from Tobias Ringström <tobias at ringis dot se> 2013-01-09 17:39:20 UTC ---
Yes, I want 'bad_guy' to be in the backtrace, so you are correct that I don't
want the stack to be unwound at all, but unfortunately it is.  It seems to be
because of the Foo object somehow.  If I remove the Foo object (or it's
destructor), 'bad_guy' is in the backtrace.


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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
                   ` (2 preceding siblings ...)
  2013-01-09 17:39 ` tobias at ringis dot se
@ 2021-11-15  1:13 ` foom at fuhm dot net
  2021-12-05  4:38 ` foom at fuhm dot net
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: foom at fuhm dot net @ 2021-11-15  1:13 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

James Y Knight <foom at fuhm dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |foom at fuhm dot net

--- Comment #5 from James Y Knight <foom at fuhm dot net> ---
The originally-reported program still appears to exhibit the issue.

Just looking at the unwind code -- and without attempting to test anything --
it appears that the solution may be as simple as inserting two lines:
      if (found_type == found_terminate)
        return _URC_FATAL_PHASE1_ERROR;

at line 651 of eh_personality.cc
(https://github.com/gcc-mirror/gcc/blob/b85a03ae11b157d60ddf93b71632efe0bde3bafd/libstdc%2B%2B-v3/libsupc%2B%2B/eh_personality.cc#L651)

I believe that would abort the search phase (similarly to what happens if you
run out of unwind frames before finding any catch handler) and cause
_Unwind_RaiseException to return _URC_FATAL_PHASE1_ERROR, which then causes
_cxa_throw to call terminate().

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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
                   ` (3 preceding siblings ...)
  2021-11-15  1:13 ` foom at fuhm dot net
@ 2021-12-05  4:38 ` foom at fuhm dot net
  2022-12-16 15:13 ` m101010a at gmail dot com
  2023-08-11 17:39 ` jason at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: foom at fuhm dot net @ 2021-12-05  4:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

--- Comment #6 from James Y Knight <foom at fuhm dot net> ---
I realize that my suggestion above could only solve _most_ of the problem --
e.g. the original example, where the noexcept function doesn't have a try/catch
in it.

In that original example, there's no entry for the IP of the call in the LSDA
table. The personality fn already knows during phase1 that this indicates
termination -- but it simply fails to actually trigger the terminate in phase1,
even though it easily could (& should!).


However, in the example from comment #4, there _WILL_ be an entry in the
callsite table covering the throw (necessarily, in order to to catch type
"float"), so the "missing callsite => terminate" mechanism isn't applicable in
that case. As the comment mentioned, to handle that, we'd need some alternative
indication for termination which can be put in the action list.

ISTM this could be done most straightforwardly by using an action record with a
ttype pointing to a new ABI-defined special-purpose symbol (e.g.
"__cxxabiv1::__eh_noexcept"). In libsupc++'s impl, that symbol can be an object
whose type is a new std::type_info subclass, whose __do_catch overload calls
terminate. Thus, when the personality fn falls through all the _actual_ catch
action records, and comes to this, last one, it will query whether it can catch
an exception by calling its __do_catch, and immediately trigger termination.

GCC, then, can emit that as the last "catch" action in the chain for a
try/catch in a noexcept function (instead of the cleanup action with code that
calls std::terminate explicitly in the cleanup, that it does now).

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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
                   ` (4 preceding siblings ...)
  2021-12-05  4:38 ` foom at fuhm dot net
@ 2022-12-16 15:13 ` m101010a at gmail dot com
  2023-08-11 17:39 ` jason at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: m101010a at gmail dot com @ 2022-12-16 15:13 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

m101010a at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |m101010a at gmail dot com

--- Comment #7 from m101010a at gmail dot com ---
I have written a GCC plugin (available at
https://github.com/m42a/gcc-noexcept-plugin ) based on comment #6 that
consistently prevents stack unwinding in this case.

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

* [Bug c++/55918] Stack partially unwound when noexcept causes call to std::terminate
  2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
                   ` (5 preceding siblings ...)
  2022-12-16 15:13 ` m101010a at gmail dot com
@ 2023-08-11 17:39 ` jason at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: jason at gcc dot gnu.org @ 2023-08-11 17:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55918

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=97720

--- Comment #8 from Jason Merrill <jason at gcc dot gnu.org> ---
As discussed on PR97720, I think we could address this by changing noexcept
regions to be represented as exception-specifications in the action table, and
for C++17 and up using a different personality routine that knows that
exception-specifications are noexcept.

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

end of thread, other threads:[~2023-08-11 17:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-09 13:45 [Bug c++/55918] New: Stack partially unwound when noexcept causes call to std::terminate tobias at ringis dot se
2013-01-09 13:52 ` [Bug c++/55918] " redi at gcc dot gnu.org
2013-01-09 14:43 ` jason at gcc dot gnu.org
2013-01-09 17:39 ` tobias at ringis dot se
2021-11-15  1:13 ` foom at fuhm dot net
2021-12-05  4:38 ` foom at fuhm dot net
2022-12-16 15:13 ` m101010a at gmail dot com
2023-08-11 17:39 ` jason 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).