← 输入框|github.com|刷新
Skip to content

Terminating with unexpected exception #358

Closed

Description

@ruslo

Example simple_wget crashing from time to time with error:
boost thread: trying joining itself: Resource deadlock avoided

How to reproduce

I turn off wi-fi and run command:
simple_wget https://example.com/some/archive.tar.gz

Usually command exits with code 1 and message:

Saving to: archive.tar.gz
Host not found (authoritative)

which is expected and good, but sometimes application crash in libc++ with message:

libc++abi.dylib: terminating with unexpected exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::thread_resource_error> >: boost thread: trying joining itself: Resource deadlock avoided
Process 75882 stopped

Backtrace can be found here

I can guess that exception which is thrown from join trigger std::terminate
because destructor has nothrow type (async_impl.h):

      ~async_client() throw ()
      {
        sentinel_.reset();
        if (lifetime_thread_.get()) {
          lifetime_thread_->join(); // BOOM!
          lifetime_thread_.reset();
        }
      }

Some tests

  • 5 crash from 1000 run
  • 36 crash from 10000 run

Environment

  • Mac OS X 10.9.1, boost 1.55 (debug build with libc++), openssl (system)
  • iOS, boost 1.55 (debug build with libc++), openssl 1.0.1e
  • I'm using cpp-netlib-0.10.1, but cpp-netlib-0.11.0-rc3 has same behaviour

Also I've tried it on my virtual machine with Mac OS X 10.8.5 (which not using wi-fi),
there is no crashes.

Activity

  1. added a commit that references this issue on Jan 11, 2014
  2. deanberris commented on Jan 13, 2014

    @deanberris
    Member

    So, the simple_wget example needs some love. Can you send a pull request to fix this example? I would greatly appreciate it @ruslo.

  3. ruslo commented on Jan 13, 2014

    @ruslo
    Author

    So, the simple_wget example needs some love.
    I don't think that it's just example issue, I have same troubles in other situations too.

    Can you send a pull request to fix this example?

    The problem is that I don't know how to fix it (: Maybe it some thread management issue,
    async_client ctor called in one thread and dtor called in other. Maybe it's just corrupted memory or double destruction. Simple workaround is to catch expection and ignore it, but it's more like hack...

  4. deanberris commented on Jan 23, 2014

    @deanberris
    Member

    Right, this is not a simple issue to fix. I think it's because during the lifetime of the response object, a resolution error may happen and if there's an exception thrown during the fetching of the body (or any part of the response for that matter) it would cause the destruction of the async client (if they're in the same scope). What's really happening here is a lifetime issue -- perhaps there's a way to change the destruction semantics of the async client, but I'm not entirely sure what that should be. Maybe it's just a matter of swallowing exceptions that are trying to propagate out of the destructor?

  5. ruslo commented on Jan 23, 2014

    @ruslo
    Author

    Maybe it's just a matter of swallowing exceptions that are trying to propagate out of the destructor?

    I don't save logs but last time I try it (see workaround above) I've got Segmentation Fault.
    FYI looks like master branch is not suffering from this issue.

  6. leecoder commented on Jun 17, 2014

    @leecoder

    I think this issue is the same with #232. (client object lifetime)
    So, it will just be fixed by avoiding self join. (leecoder@af17c77)
    And, it will must always be used an outside io_service.

    Then, the following code works!

    #include <boost/network/protocol/http/client.hpp>
    
    int main(int argc, char** argv)
    {
        using namespace boost::network;
        using namespace boost::network::http;
    
        boost::asio::io_service io;
        std::cout << body(client(io).get(client::request("http://boost.org/"))) << std::endl;
    }
  7. deanberris commented on Jun 17, 2014

    @deanberris
    Member

    @leecoder Nice find. Can you send me a pull request on the 0.11-devel branch with that fix?

  8. added 2 commits that reference this issue on Jun 18, 2014
    ce53598
    770858b
  9. added 2 commits that reference this issue on Apr 14, 2015
    d108033
    f6715f0
  10. olegabr commented on Feb 13, 2018

    @olegabr

    I've got the same error in the 0.13-release branch now.

    terminate called after throwing an instance of 'std::system_error'
      what():  Resource deadlock avoided
    

    The patch that fixes it that was applied in the 0.11-devel here: 1b11ec6#diff-c272e324d5e4a6288abe1e22553c4027
    was reverted without any explanations here: 2be7e30#diff-c272e324d5e4a6288abe1e22553c4027

    The question is why? And should we apply it back?

  11. deanberris commented on Feb 14, 2018

    @deanberris
    Member

    I think this was an oversight. Thanks for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions