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