3

I'm trying to hunt down why a program is crashing in shared_ptr.

#0  0x00007fff90723212 in __pthread_kill ()
#1  0x00007fff93415b54 in pthread_kill ()
#2  0x00007fff93459dce in abort ()
#3  0x00007fff8a0519eb in abort_message ()
#4  0x00007fff8a04f39a in default_terminate ()
#5  0x00007fff930bf887 in _objc_terminate ()
#6  0x00007fff8a04f3c9 in safe_handler_caller ()
#7  0x00007fff8a04f424 in std::terminate ()
#8  0x00007fff8a05058b in __cxa_throw ()
#9  0x0000000100057cbc in boost::throw_exception<boost::bad_weak_ptr> (e=@0x1002c5b88) at throw_exception.hpp:66
#10 0x0000000100057bf4 in boost::detail::shared_count::shared_count (this=0x1002c5d00, r=@0x100304180) at shared_count.hpp:509
#11 0x0000000100057b7d in boost::detail::shared_count::shared_count (this=0x1002c5d00, r=@0x100304180) at shared_count.hpp:511
#12 0x000000010004ad14 in boost::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass>::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass> (this=0x1002c5cf8, r=@0x100304178) at shared_ptr.hpp:220
#13 0x000000010004acad in boost::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass>::shared_ptr<myns::(anonymous namespace)::MySharedFromThisClass> (this=0x1002c5cf8, r=@0x100304178) at shared_ptr.hpp:223
#14 0x000000010004a9b4 in boost::enable_shared_from_this<myns::(anonymous namespace)::MySharedFromThisClass>::shared_from_this (this=0x100304178) at enable_shared_from_this.hpp:49

MySharedFromThisClass is defined as:

class MySharedFromThis : public boost::enable_shared_from_this<MySharedFromThis> {
    // ....
};

And the instance that was being passed around was defined like:

auto myKlass = std::make_shared<MySharedFromThis>();

And being copied around via:

void myFunction(::boost::shared_ptr<MySharedFromThis> myKlass) {
  myFunction(shared_from_this());
}

What gives? Everything compiles with no warnings or errors, but things very clearly segfault in not so pleasant ways.

4

1 回答 1

4

I'm posting my own answer because this chunk of code compiled without any warnings or errors and took a fair amount of effort to track down.

It should be pretty obvious based on the example above when looking at this line:

auto myKlass = std::make_shared<MySharedFromThis>();

myKlass is of type std::shared_ptr<MySharedFromThis>, not boost::shared_ptr<MySharedFromThis>. Change std::make_shared<> to boost::make_shared<> and everything works as expected/intended.

There are two possible things leading to this crash:

  1. The call to shared_from_this() in myFunction() was being called without an existing ::boost::shared_ptr<> already existing. Instead, what had happened was a std::shared_ptr<> was created, which has a different ABI that a boost::shared_ptr<>. Notably a libboost_thread-mt.dylib expects a boost::enable_shared_from_this<> class and not a std::enable_shared_from_this<> class.
  2. According to the enable_shared_from_this<> documentation, the prerequisite was not satisfied.

    Requires: enable_shared_from_this must be an accessible base class of T. *this must be a subobject of an instance t of type T . There must exist at least one shared_ptr instance p that owns t.

    Instead what had happened was there was a std::shared_ptr<> instance, but not a boost::shared_ptr<> instance.

At least that's my understanding of what was going on. I think #1 is the real problem leading to the segfault, and #2 would have been a problem sooner or later (though I'm not entirely convinced).

于 2013-04-10T05:59:22.520 回答