As GCPW is currently experiencing problems while unloading the credential provider dll we have researched and found what we believe is a bug on the crashpad library.
Currently we are instantiating the crashpad through function GetCrashpadClient()
which basically dynamically creates by using new a CrashpadClient object and return a reference to this.
static crashpad::CrashpadClient* const client = new crashpad::CrashpadClient();
return *client;
The problem is that that object is never deleted, and so the destructor is never called, and although that maybe not harmful for certain applications it is problematic for DLLs like ours, because CrashPadClient registers
HandleHeapCorruption function as an exception handler using
PVOID handler = AddVectoredExceptionHandler(true, HandleHeapCorruption);
vectored_handler_.reset(handler);
and also stores the handler to be deregistered upon destruction by using the
void ScopedVectoredExceptionRegistrationCloseTraits::Free(PVOID handle) {
PCHECK(::RemoveVectoredExceptionHandler(handle));
}
but since the object is stored as a raw pointer then nobody owns it and it is never destroyed.
all this means that if you use CrashpadClient inside a dynamically loaded dll, and then you unload the library the HandleHeapCorruption function it is going to be still on the exception handlers queue although the function itself is not going to be mapped on the process memory, and then if some exception happens the program aborts.
I believe (and tested) this can be fixed with this little change that uses static function allocation of an object instead of using a pointer
crashpad::CrashpadClient& GetCrashpadClient() {
static crashpad::CrashpadClient client;
return client;
}
I am happy to hear comments, since this problem is blocking us to releasing new updates of GCPW.
Thanks in advance
Ricardo