WSACleanup and atExit - c++

Is it okay to register WSACleanup through atExit function ? We have several applications that can terminate at different points in the code so we would like to avoid putting WSACleanup everywhere throughought the code. Curently we call WSAStartup / WSACleanup through DllMain since we have a dll that is used by all these applications. However, Microsoft strictly advices against the use of WSAStartup / WSACleanup via DllMain since this can cause deadlocks. We can move WSAStarup out of DllMain and call this at one point in the code for all applications before they access the Windows sockets library. And, as soon as we call WSAStartup, we would like to use the atExit function to register a call to WSACleanup. Does anyone have any experiences with this approach ? Thanks!

If you have a multi-threaded app and some of the threads are still connected, the applications at the other end may not like the way the connection is terminated. So it is preferable to close down all communication in an ordered way before main() terminates, and when you have done that, you can just as well call WSACleanup.

I agree that the RAII approach is favourable.
However a word of warning: atExit mixed with dlls and handles is broken on windows. Unfortunately this effects RAII too as this is implemented with atExit handlers by the c++ runtime.
The order that atexit handlers are called on windows:
somewhere exit is called or main() goes out of scope
atexit handlers defined in the process are called.
all handles are destroyed.
atexit handlers defined in dlls are called.
It doesn't matter if atexit handlers in dlls are registered before handlers in the process the process handlers are called first and the handles are destroyed before the dll handlers are called. This results in win32 exceptions, when the clean up code is called as all the handles owned by dlls are no longer valid.
This effects code that holds handles to threads, mutexs, files, sockets etc. If they are allocated in a dll then they must be cleaned up before exit is called or not at all.
By the way I am not anti window, if I am wrong or anyone knows any way around this I would love to know as this causes me untold pain in application clean up. I figured this out be debugging exit handling in the c++ runtime, after getting win32 exceptions when applications exit.
I had to remove all calls to exit from my code. I now ensured that no static data in a dll controls a handle. All static handles are controlled by objects that are destructed when main goes out of scope.

Well I think atExit should not be used. You should follow RAII principle of wrapping of initialization and destruction of socket library in a class.

Related

Crashing when Calling CoUninitialize

Based on this link, I am creating Windows Processing Monitoring and Windows Service Monitoring DLLs that are to be called by the main application and run them in thread(using boost::thread) to get the data asynchronously. Consider that these both dll are run by my application. I get the error Failed to initialize security. Error code = 0x80010119 for one of my app. And also when stopping the threads for these dll, CoUninitialize is called in both of them. Here I get a crash. It might be because the CoUninitialize in latter thread might attempt to clear memory that was cleared by former thread.
If so, how can I check whether the CoUninitialize in one thread was successful so that I would not call it in another thread.
CoUninitialize is a part of COM library, WMI can use COM interface, but has nothing to do with its initialization or disposal. Don't call CoUninitialize twice within one process. Note, that both of your DLL's probably share application context and are executed within it.
"how can I check whether the CoUninitialize in one thread was successful so that I would not call it in another thread."
That tells me your error, but it's not in CoUninitialize. You are assuming that CoUninitialize is process-wide. In reality, CoUninitialize mirrors CoInitializeEx, and that should have de done on every thread. So your crash is almost certainly caused by a CoInitializeEx on one thread and the CoUninitialize on another thread.
The fix is to do CoInitializeEx on both threads, and CoUninitialize also on both threads.

Should I always call Release on COM pointers when my program terminates?

I know that modern Windows versions reclaim memory that was previously acquired with malloc, new and the like, after program termination, but what about COM objects? Should I call obj->Release() on them on program's exit, or will the system do this for me?
My guess it: it depends. For out of process COM, I should probably always call Release(), but for in-process COM, I think it really doesn't matter, because the COM objects die after program termination anyway.
If you're in the process itself then yes you should as you might not know where the server is and the server could be out of proc. If you're in a DLL it becomes more complicated.
In a DLL you should UNLESS you receive a DLL_PROCESS_DETACH notification, in which case you should do absolutely nothing and just let the application close. This is because this notification is called during process teardown. As such it is too late to clean up at that point. The kernel may have already reclaimed the blocks you call release on.
Remember as a DLL writer there is nothing you can do if the process exits ungracefully, you can only do what you can within reason to clean up after yourself in a graceful exit.
One easy solution is to use smart COM Pointers everywhere, the ATL and WRL have implementations that work nicely and make it so you don't have to worry about it for the most part. Even if these are stored statically their destructors will be called before process teardown or DLL unload, thus releasing safely at a time when it is safe to do so.
So the short answer is If you can e.g. you should always call release if it is safe to do so. However there are times when it is not and you should most definitely NOT do anything.
Depending on the implementation of the underlying object, there may or may not be a penalty. The object may have state that persists beyond process shutdown. A persistent lock in a local database is the easiest example that comes to mind.
With that in mind, I say it's better to call Release just in case.
in-process COM object will die with the process
out-of-process reference will be released on timeout
poorly designed servers and clients might remain in bad state holding pointers to objects (typically proxies), that are not available any longer, being unable to see they are dead. being unable to get rid of them
it is always a good idea to release the pointers gracefully
If you don't release COM pointers properly, and COM activity included marshaling, you are very likely to have exceptions in CoUninitialze which are both annoying and/or can end up showing process crash message to the user.

Why does calling WSASocket from DllMain lead to a hang?

I need to destroy some objects when my DLL is unloaded. This object contains a thread that sometimes calls the WSASocket function (for reconnecting a connection). So, I call the destructor from DllMain in response to DLL_PROCESS_DETACH, but that causes my application to hang. Specifically, the call to WSASocket locks up.
I know that some functions cannot be called from DllMain, especially functions that call LoadLibrary and FreeLibrary. But why does the WSASocket function have this same problem?
It's because you shouldn't use DllMain for that cause. Many system procs will cause a deadlock being called from DllMain. Declare an additional export proc especially for deinitialization of your dll and call it right before FreeLibrary.
Also, I recommend you to read "Best Dll Practices" by MSFT. There are a lot of reasons to stay away from DllMain.

How can I handle exit() calls in 3rd party library code?

I'm working on a C++ application which uses a library written in C by another team. The writers of the library like to call exit() when errors happen, which ends the program immediately without calling the destructors of objects on the stack in the C++ application. The application sets up some system resources which don't automatically get reclaimed by the operating system after the process ends (shared memory regions, interprocess mutexes, etc), so this is a problem.
I have complete source code for both the app and the library, but the library is very well-established and has no unit tests, so changing it would be a big deal. Is there a way to "hook" the calls to exit() so I can implement graceful shutdown for my app?
One possibility I'm considering is making one big class which is the application - meaning all cleanup would happen either in its destructor or in the destructor of one of its members - then allocating one of these big objects on the heap in main(), setting a global pointer to point to it, and using atexit() to register a handler which simply deletes the object via the global pointer. Is that likely to work?
Is there a known good way to approach this problem?
In the very worst case, you can always write your own implementation of exit and link it rather than the system's own implementation. You can handle the errors there, and optionally call _exit(2) yourself.
Since you have the library source, it's even easier - just add a -Dexit=myExit flag when building it, and then provide an implementation of myExit.
install exit handler with atexit and implement the desired behavior
If you want to make the C library more usable from C++, you could perhaps run it in a separate process. Then make sure (with an exit handler or otherwise) that when it exits, your main application process notices and throws an exception to unwind its own stack. Perhaps in some cases it could handle the error in a non-fatal way.
Of course, moving the library use into another process might not be easy or particularly efficient. You'll have some work to do to wrap the interface, and to copy inputs and outputs via the IPC mechanism of your choice.
As a workaround to use the library from your main process, though, I think the one you describe should work. The risk is that you can't identify and isolate everything that needs cleaning up, or that someone in future modifies your application (or another component you use) on the assumption that the stack will get unwound normally.
You could modify the library source to call a runtime- or compile-time-configurable function instead of calling exit(). Then compile the library with exception-handling and implement the function in C++ to throw an exception. The trouble with that is that the library itself probably leaks resources on error, so you'd have to use that exception only to unwind the stack (and maybe do some error reporting). Don't catch it and continue even if the error could be non-fatal as far as your app is concerned.
If the call exit and not assert or abort, there are a few points to get control again:
When calling exit, the destructors for objects with static lifetime (essentially: globals and objects declared with static) are still executed. This means you could set up a (few) global "resource manager" object(s) and release the resources in their destructor(s).
As you already found, you can register hooks with atexit. This is not limited to one. You can register more.
If all else fails, because you have the source of the library, you can play some macro tricks to effectively replace the calls to exit with a function of your own that could, for example, throw an exception.

Global variable destructors not called, where to start?

I'm faced with the problem that my applications global variable destructors are not called. This seems to occur only if my application successfully connects to an oracle database (using OCI).
I put some breakpoints in the CRT and it seems that DllMain (or __DllMainCRTStartup) is not called with DLL_PROCESS_DETACH, thus no atexit() is called which explains why my destructors are not called.
I have no idea why this happens.
I realize that this is probably not enough information to be able to indicate the cause, but my question is: What would be a good start to look for the cause of this problem?
This is a list of things I already tried:
search the net for solutions
attached the debugger and enable native exceptions to see there was no hidden crash, sometimes I get an exception in the .Net framework, but the app seems to continue.
try to reproduce in a small application, no success
The most common situation I encounter where this occurs is a program crash. In certain circumstances crashes can happen silently from an end user perspective. I would attach a debugger to the program, set it to break on all native exceptions and run the scenario.
It's possible that someone is calling TerminateProcess, which unlike ExitProcess does not notify DLLs of shutdown.
This might be helpful:
What happens to global variables declared in a DLL?
Are your globals declared inside a dll, or in your application's memory space?
Calling theexit API often means that the application exits without calling destructors. I an not sure that VC does in this case.
Also try avoid using global objects. This is because you have little control over when and in what order the constructors and destructors are called. Rather convert the objects into pointers and initialise and destroy the pointers using the appropriate DllMain hooks. Since DllMain is an OS construct and not a language construct, it should prove more reliable in the case of normal exits.