The executable creates an io_service (io) and pool of worker threads, each
calling io.run(). Afterwards, the executable begins loading DLLs I've
written to add specific functionality (i.e plugins). Each of these plugins
are passed the executable's io_service so that they can perform asynchronous
work against the thread pool.
One of the DLLs creates a boost::asio::ip::tcp::acceptor object, passing the
io_service to its constructor. This, in turn, eventually calls use_service,
which creates a new service and associates it with the service_registry.
This is all happening in the DLL.
At shut down, I begin unloading the DLLs, giving each a chance to shut down
everything (which they do). I then call FreeLibrary() on the DLL's HMODULE
handle.
After my application completes shutdown, all the destructors hit, as
expected. When the destructor of the service_registry hits, I believe its
linked list of services is still pointing to a service located in the memory
space of the DLL. This results in a crash.
I believe this is the case as I can track the pointer to the
acceptor_service in a Watch Window. The pointers and the object remain
valid until I call "FreeLibrary", at which point they become worthless.
I think this is because the DLL and the executable have their own CRT memory
space, due to the way I'm linking in the CRT. The service for the acceptor
is being created in the DLL's space. When FreeLibrary is called, this space
is released to the OS, making the pointer to the object worthless.
If that's the case, I believe I'll need to supply my own service creation
routine for the DLLs so that the services are created in my executable's
memory space. Is this possible? Is there a way to get the service_registry
to release a service when it's no longer in use anywhere, or to specify my
own new/delete routines the use_service calls should use?
Or, is using ASIO in a DLL like this a really really bad idea? If that's the
case, how can I tell what other objects in boost could cause these sorts of
problems?
I'll try to get a project together that reproduces the issue as soon as I
can. I can't use the code I have at the moment as it is proprietary.
Thanks for any input anyone can provide.
--
View this message in context: http://www.nabble.com/-asio--io_service-use-in-dll-leads-to-service_registry-crash-tp22052497p22052497.html
Sent from the Boost - Users mailing list archive at Nabble.com.
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
joshr wrote:
>
> I'll try to get a project together that reproduces the issue as soon as I
> can. I can't use the code I have at the moment as it is proprietary.
>
I've attached a zip of the Visual Studio 2008 solution and project files
that reproduces the issue. The bin folder contains the compiled executable
as well, if for some reason this is useful.
If you need to recreate the projects for another version of studio, here are
the settings I've used:
Solution (Folder for solution):
Project asiodll (Windows Console Application)
Project extension (Windows DLL)
Both Projects have the following settings (Everything else is default):
Output Directory: $(SolutionDir)bin
Character Set: Use Multibyte Character Set
Code Generation (Release): Multi-Threaded (/MT)
Code Generation (Debug): Multi-Threaded Debug (/MTd)
Preprocessor Definitions: STRICT and WIN32_LEAN_AND_MEAN were added
Generate Manifest: No
File: http://www.nabble.com/file/p22062206/asiodll.zip asiodll.zip
--
View this message in context: http://www.nabble.com/-asio--io_service-use-in-dll-leads-to-service_registry-crash-tp22052497p22062206.html
I've attached a zip of the Visual Studio 2008 solution and project files
that reproduces the issue. The bin folder contains the compiled executable
as well, if for some reason this is useful.
Igor R wrote:
>
> I built and run your code. It really crashes if you forcibly unload the
> dll
> but it does *not* crash if I comment-out this line *or* if I remove
> acceptor
> object from the dll code. It seems that the reason of the crash is that a
> dll statically linked to CRT has its own private CRT (including memmoty
> management), so when you free the dll, all the asio objects created from
> within the dll (asio services in this case) become inaccessible.
> Try and build asio, dll and the host app with dynamic CRT - probably this
> will help.
>
This was the same behavior I saw as well after further testing and came to
the same conclusions. Ultimately I want to hide the Boost interface from
plugin developers so that I don't require the use of Boost. For this
initial implementation, which I have to write, I was hoping to pass the
boost objects as a temporary stepping stone.
At any rate, thank you very much for your feedback! It definitely gives me
some things to rethink in my design.
--
View this message in context: http://www.nabble.com/-asio--io_service-use-in-dll-leads-to-service_registry-crash-tp22052497p22085688.html