B
Ben Voigt [C++ MVP]
Aek said:On Jun 26, 10:55 am, Aek <[email protected]> wrote:On Jun 26, 8:36 am, "Ben Voigt [C++ MVP]" <[email protected]> wrote:You are linking both with /MDd, right?Yeah they are both /MDd
We came to a resolution on this issue. We found that once the
offending C++ DLL that used managed extensions was removed from the
main application, then the problem went away.
Luckily the managed dll didnt do that much, and was mostly prototype
code for a legacy task, so removing it was the best option. We have
other managed dlls that we continue to use, but there was something
specific about how this one was built or used that caused the problem.We still have not found the root cause of the issue. There is likely
someway that we are building/configuring or using this managed C++ dll
that is causing it to automatically cleanup native types registered
with atexit in a different assembly.Why the dll calls the CRT cleanup code and the fact that the main
executable does it again is odd, considering that there are a number
of checks in place around that automatic cleanup code to avoid this
problem.I will spend a few hours today trying to create a small reproducible
case and if the root cause is not clear, perhaps I can post it here
for examination.Thanks for all your help.
Regards,
Josh Stewart
For anyone that is interested in have a look at a small example of the
problem.. I have created a small reproducible example.
The offending DLL has had all of its managed code removed, so I do not
think it is the managed extensions C++ that was causing the problems
with that DLL.
The issue seems to be related to mixing a /clr built executable + dll
with a native C++ (no clr) library.
You can breakpoint in the destructor of the meyer singleton in the
native C++ lib to see it destroy twice.
Here is the example
solution:http://aek.bur.st/work/Example_AtExit_Issue.zip
If anyone has an idea about what the issue here is, please let me
know
Cheers,
Josh Stewart
Someone at work found the solution..
In the managed DLL project, remove /NOENTRY from Linker -> Command
Line -> Additional Options
Note that this is the same as setting "No Entry Point" to "yes" in
Linker -> Advanced.
Seems that the /NOENTRY was left in after converting from 2003 to 2005
project and should not be used in this case.
Still not sure why this affects the local statics in the native
library though.
The CRT entry-point sets up the various arrays and linked lists that handle
destruction of statics and globals for the module. If it wasn't called,
those lists wouldn't be set up correctly, and apparently the ones from the
main application were used instead. So all the statics were cleaned up,
instead of just the ones for the local module. Or something like that.