boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::thread_resource_error> >

frisco picture frisco · Mar 21, 2013 · Viewed 13.7k times · Source

I need some help with this exception, I am implementing a NPAPI plugin to be able to use local sockets from browser extensions, to do that I am using Firebreath framework.

For socket and connectivity I am using Boost asio with async calls and a thread pool of 5 worker threads. Also I have a deadline per thread to implement a transmission timeout.

My extension workflow with the plugin is as this:

  1. Open socket 1(this starts a async_receive and the deadline async_wait)
  2. Write in the socket 1
  3. Get response 1

  4. Open another socket 2

  5. Write in the socket 2

  6. Write socket 1

  7. Close socket 1 (socket.cancel(), deadline.cancel(), socket.shutdown(), socket release).

  8. Get response 2

  9. Write socket 2
  10. Close socket 2

As everything is cross language and async is really hard to debug but all open, write or close are called from javascript and the read from socket 1 that calls open 2, write 2, write 1 and close 1 in that order.

Maybe evrything I am telling is unrelated as the call stack when the exception is thrown does not show any of my functions and only show that it is inside a malloc that calls _heap_alloc_dbg_impl

As it is it usually fails in the 2nd or 3rd full cycle and it seems that happens between steps 5 and 7.

But, I think that it must be asio related as doing everything with a single worker thread just crashes with the exception on the first cycle.

I am open to publish more information code if you need it.

Update 1:

VS when breaking

Update 2:

There are 10 threads are launched with:

workPtr.reset( new boost::asio::io_service::work(io_service));

for ( int i = 0; i < 10; ++i) {
    m_threadGroup.create_thread( boost::bind(&boost::asio::io_service::run, &io_service) );
}

The 11th _threadstartex I don't know who launched it

On another thread (not the one that VS claims as causing the crash) there is a join_all() in process because my class is being destroyed but I think it shouldn't, so maybe this crash is due to another exception and the Firebreath process to close everything when it crashes.

Answer

frisco picture frisco · Mar 21, 2013

I found the errors by continuing to inspect the other threads. I found that my principal class that Firebreath was invoking was in the process of being destroyed. Inspecting a little more I found that it was totally my fault I have a class for storing the sockets information that needed to use a function in the principal class (I didn't like it but it was the only way I found to use it) so I added a shared_ptr to the principal class. So if it after destroying on of those SocketInfo objects as there were no others the ptr ref count reached 0 and the principal class was being destroyed.

What is fun is that sockets usually close normally after being used so I see no reason why this was not triggered when there were not sockets opened and only happened when 2 sockets where opened and closed in a row.

Anyway I also had a shared_from_this error with the deadline handler but that seemed unrelated.

And now it seems it is working as expected with any number of threads.