How to get more info about 'bad_function_call' ?

Jonathan Wakely jwakely.gcc@gmail.com
Wed Jan 28 00:45:00 GMT 2015


On 27 January 2015 at 21:56, J. Leslie Turriff wrote:
> On Tuesday 27 January 2015 11:21:22 Jonathan Wakely wrote:
>> On 27 January 2015 at 17:11, Linda A. Walsh <gcc@tlinx.org> wrote:
>> > Jonathan Wakely wrote:
>> >> Look at the stack trace, find out why the std::function object you're
>> >> calling is empty at that point.
>> >
>> > Forgot to include this, but the stack track shows that what I am
>> > calling @ #7 is not empty.  IP = 4141c3, and 'this' is also nonzero.
>> >
>> >
>> > Program terminated with signal SIGABRT, Aborted.
>> > #0  0x0000003002035849 in __GI_raise (sig=sig@entry=6)
>> >    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
>> > 56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
>> > (gdb) where
>> > #0  0x0000003002035849 in __GI_raise (sig=sig@entry=6)
>> >    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
>> > #1  0x0000003002036cd8 in __GI_abort () at abort.c:89
>> > #2  0x0000003006465145 in __gnu_cxx::__verbose_terminate_handler ()
>> >    at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
>> > #3  0x00000030064632e6 in __cxxabiv1::__terminate (handler=<optimized
>> > out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:38
>> > #4  0x0000003006463313 in std::terminate ()
>> >    at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:48
>> > #5  0x0000003006463532 in __cxxabiv1::__cxa_throw (obj=0x511040,
>> >    tinfo=0x30066ef6c0 <typeinfo for std::bad_function_call>,
>> >    dest=0x30064b4c30 <std::bad_function_call::~bad_function_call()>)
>> >    at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:87
>> > #6  0x00000030064b4bc2 in std::__throw_bad_function_call ()
>> >    at ../../../../../libstdc++-v3/src/c++11/functexcept.cc:113
>> > #7  0x00000000004141c3 in std::function<void ()>::operator()() const (
>> >    this=this@entry=0x50ac58) at /usr/include/c++/4.8/functional:2470
>> > #8  0x000000000041408c in Task::run (this=this@entry=0x50ac40) at
>> > ltask.cc:84
>>
>> Your bug is here.
>>
>> It's really quite simple. Instead of looking into the library code,
>> you need to look here.
>>
>> That piece of code is calling an empty std::function object.
>>
>> The _M_empty() condition is true, so __throw_bad_function_call() runs,
>> which ... guess what? Throws std::bad_function_call ... which is what
>> you're seeing.
>>
>> You don't need "more info about bad_function_call" because it tells
>> you exactly one thing: you called an empty std::function. Its sole
>> purpose is to tell you where and when that call happens, which is in
>> the stack trace above but you're insisting on ignoring your own code
>> and digging into the library.
>         Wow.  So simple, but I, for one, can't see any reference in the stack trace
> to _M_empty() that tells this.

*sigh*

I didn't say you could see any. The relevant code is this:

  if (_M_empty())
    __throw_bad_function_call();

So of course you won't see _M_empty(), because at the point where the
exception is thrown _M_empty() has been called and already returned.
And _M_empty() is just an implementation detail anyway, you shouldn't
be looking for that!

The standard says that when you call an empty std::function, you get a
std::bad_function_call exception.

That fact alone should be enough to diagnose the problem when you get
a std::bad_function_call exception.

The stack trace shows Linda's code calls
std::function<void()>::operator()() which calls
__throw_bad_function_call(), which throws a std::bad_function_call
exception.

Again, that's all you need to know. Just look for the call to
operator() and fix that.

Which is exactly what was suggested right away:
https://gcc.gnu.org/ml/libstdc++/2015-01/msg00186.html
https://gcc.gnu.org/ml/libstdc++/2015-01/msg00187.html


If std::function just segfaulted at that point maybe you'd need to
debug it, but it throws an exception of type bad_function_call which
is supposed to tell you what happened without digging through the
library internals.



More information about the Libstdc++ mailing list