public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Problem with noexcept and incomplete backtrace
@ 2013-01-08 18:00 Tobias Ringström
  2013-01-08 21:48 ` Ángel González
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Ringström @ 2013-01-08 18:00 UTC (permalink / raw)
  To: gcc-help

I've discovered a problem with backtraces when using noexcept, but I 
don't know if it's a bug, required behaviour, or if I'm missing 
something.  I'd appreciate a little guidance.

The problem is that when an exception is thrown and there's a "noexcept" 
function earlier in the call stack, the backtrace is sometimes 
incomplete, i.e. it ends before the throw location. Specifically, it 
seems to end at the first function above the "noexcept" function that 
has an object with a destructor in it.

It's probably easier to understand with an example:

     class Foo
     {
     public:
         Foo() { }
         ~Foo() { }
     };
     void bad_guy()
     {
         throw "die die die";
     }
     void level2()
     {
         Foo foo;
         bad_guy();
     }
     void level1() noexcept
     {
         level2();
     }
     int main()
     {
         level1();
     }

# 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  0x0000000000400722 in level2 () at tmp3.cpp:14
#9  0x000000000040072b in level1 () at tmp3.cpp:18
#10 0x0000000000400736 in main () at tmp3.cpp:22

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).  I 
really need the noexcept because in my real application, level1 is a 
thread main function, which needs the noexcept, or I don't any call 
stack below libstdc++'s thread caller, because it has a try/catch all 
block to call terminate.

Should I file a bug report?  I've tested 4.6.3, 4.7.2 and 4.8-20130106, 
with identical results.

/Tobias

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

* Re: Problem with noexcept and incomplete backtrace
  2013-01-08 18:00 Problem with noexcept and incomplete backtrace Tobias Ringström
@ 2013-01-08 21:48 ` Ángel González
  2013-01-08 21:53   ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Ángel González @ 2013-01-08 21:48 UTC (permalink / raw)
  To: Tobias Ringström; +Cc: gcc-help

On 08/01/13 17:47, Tobias Ringström wrote:
> I've discovered a problem with backtraces when using noexcept, but I
> don't know if it's a bug, required behaviour, or if I'm missing
> something.  I'd appreciate a little guidance.
>
> The problem is that when an exception is thrown and there's a
> "noexcept" function earlier in the call stack, the backtrace is
> sometimes incomplete, i.e. it ends before the throw location.
> Specifically, it seems to end at the first function above the
> "noexcept" function that has an object with a destructor in it.
>
> It's probably easier to understand with an example:
(...)
> 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).  I
> really need the noexcept because in my real application, level1 is a
> thread main function, which needs the noexcept, or I don't any call
> stack below libstdc++'s thread caller, because it has a try/catch all
> block to call terminate.
>
> Should I file a bug report?  I've tested 4.6.3, 4.7.2 and
> 4.8-20130106, with identical results.
>
> /Tobias
You are lying to the compiler there. OTOH, level1 shall not throw any
exception (has noexcept), OTOH it *is* throwing an exception. So I gues
you're at undefined behavior.
What about surrounding the content of level with a try catch all ?

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

* Re: Problem with noexcept and incomplete backtrace
  2013-01-08 21:48 ` Ángel González
@ 2013-01-08 21:53   ` Jonathan Wakely
  2013-01-08 22:19     ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2013-01-08 21:53 UTC (permalink / raw)
  To: Ángel González; +Cc: Tobias Ringström, gcc-help

On 8 January 2013 21:39, Ángel González wrote:
> You are lying to the compiler there. OTOH, level1 shall not throw any
> exception (has noexcept), OTOH it *is* throwing an exception. So I gues
> you're at undefined behavior.

No, when an exception is thrown and the search for a handler finds a
noexecpt function std::terminate() is called.

You've missed the point of the code, the code is *supposed* to trigger
abnormal termination, the point is about the quality of the backtrace
available after std::terminate is called.

> What about surrounding the content of level with a try catch all ?

That would not help. That would lose all the context of where the
exception was thrown from, so you can't inspect the backtrace (or core
file) to see why an exception terminated your program.

Tobias, please report it to bugzilla. The standard places no
requirements on what happens except that std::terminate is called but
even if it's not a bug there is room for improvement.

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

* Re: Problem with noexcept and incomplete backtrace
  2013-01-08 21:53   ` Jonathan Wakely
@ 2013-01-08 22:19     ` Jonathan Wakely
  2013-01-09 10:30       ` Tobias Ringström
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2013-01-08 22:19 UTC (permalink / raw)
  To: Ángel González; +Cc: Tobias Ringström, gcc-help

On 8 January 2013 21:48, Jonathan Wakely wrote:
> Tobias, please report it to bugzilla. The standard places no
> requirements on what happens except that std::terminate is called but
> even if it's not a bug there is room for improvement.

I was a bit hasty, the standard does place some requirements:

In the situation where the search for a handler (15.3) encounters the
outermost block of a function with a
noexcept-specification that does not allow the exception (15.4), it is
implementation-defined whether the
stack is unwound, unwound partially, or not unwound at all before
std::terminate() is called. In all other

G++ appears to partially unwind the stack, although that isn't
documented at http://gcc.gnu.org/onlinedocs/gcc/Exception-handling.html

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

* Re: Problem with noexcept and incomplete backtrace
  2013-01-08 22:19     ` Jonathan Wakely
@ 2013-01-09 10:30       ` Tobias Ringström
  2013-01-09 10:44         ` Jonathan Wakely
  0 siblings, 1 reply; 6+ messages in thread
From: Tobias Ringström @ 2013-01-09 10:30 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On 01/08/2013 10:53 PM, Jonathan Wakely wrote:
> On 8 January 2013 21:48, Jonathan Wakely wrote:
>> Tobias, please report it to bugzilla. The standard places no
>> requirements on what happens except that std::terminate is called but
>> even if it's not a bug there is room for improvement.
>
> I was a bit hasty, the standard does place some requirements:
>
> In the situation where the search for a handler (15.3) encounters the
> outermost block of a function with a
> noexcept-specification that does not allow the exception (15.4), it is
> implementation-defined whether the
> stack is unwound, unwound partially, or not unwound at all before
> std::terminate() is called. In all other

That only tells us that GCC's noexcept handling is standard compliant. 
It does not say that it's the least useful.  :)

> G++ appears to partially unwind the stack, although that isn't
> documented at http://gcc.gnu.org/onlinedocs/gcc/Exception-handling.html

That text is probably older than noexcept, and GCC actually does follow 
what's writted there when noexcept isn't used.  If only the noexcept 
case could be handled in the same way as the normal 
unhandled-exception-past-main case, all would be fine.

I'll create a Bugzilla report.

Thanks for your input!

/Tobias

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

* Re: Problem with noexcept and incomplete backtrace
  2013-01-09 10:30       ` Tobias Ringström
@ 2013-01-09 10:44         ` Jonathan Wakely
  0 siblings, 0 replies; 6+ messages in thread
From: Jonathan Wakely @ 2013-01-09 10:44 UTC (permalink / raw)
  To: Tobias Ringström; +Cc: gcc-help

On 9 January 2013 09:13, Tobias Ringström wrote:
> On 01/08/2013 10:53 PM, Jonathan Wakely wrote:
>>
>> On 8 January 2013 21:48, Jonathan Wakely wrote:
>>>
>>> Tobias, please report it to bugzilla. The standard places no
>>> requirements on what happens except that std::terminate is called but
>>> even if it's not a bug there is room for improvement.
>>
>>
>> I was a bit hasty, the standard does place some requirements:
>>
>> In the situation where the search for a handler (15.3) encounters the
>> outermost block of a function with a
>> noexcept-specification that does not allow the exception (15.4), it is
>> implementation-defined whether the
>> stack is unwound, unwound partially, or not unwound at all before
>> std::terminate() is called. In all other
>
>
> That only tells us that GCC's noexcept handling is standard compliant. It
> does not say that it's the least useful.  :)

To be compliant it must document its implementation-defined behaviour..

>> G++ appears to partially unwind the stack, although that isn't
>> documented at http://gcc.gnu.org/onlinedocs/gcc/Exception-handling.html
>
>
> That text is probably older than noexcept, and GCC actually does follow
> what's writted there when noexcept isn't used.

Yes, but the relevant paragraph from the standard says that case and
the noexcept case are distinct, and both (separately) implementation
defined, G++ only defines one of them.

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

end of thread, other threads:[~2013-01-09 10:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-08 18:00 Problem with noexcept and incomplete backtrace Tobias Ringström
2013-01-08 21:48 ` Ángel González
2013-01-08 21:53   ` Jonathan Wakely
2013-01-08 22:19     ` Jonathan Wakely
2013-01-09 10:30       ` Tobias Ringström
2013-01-09 10:44         ` Jonathan Wakely

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).