开发者

Not all native global variables are destructed in mixed-mode .Net application because of a 2-second time-out

I my mixed-mode C++ application I notice the following strange effects:

  • If I start the executable outside Visual Studio, all unmanaged global variables are correctly destructed.
  • If I start the executable outside Visual Studio, then attach the debugger, all unmanaged global variables are correctly destructed.
  • I I start the executable inside the Visual Studio debugger, not all unmanaged global variables seem to be destructed.

I read that .Net has a 2 second timeout for the cleanup. Is this for the whole of the unmanaged global variable destruction? Or is this per destructor?

I am quite sure that this 2 se开发者_StackOverflowcond timeout is the cause, because when I set a breakpoint in the beginning of the doexit method, the debugger stops there when the application is exit'ed. But if I set a breakpoint near the end of the doexit function, that breakpoint is never hit.

Is there a way to change this 2 second timeout from within the application? The problem is that if not all global variables are destructed, my memory leak detection system will report lots of memory leaks.

EDIT:

This is an example program showing the problem.

Since I wanted to make a mixed-mode application, I wrote a separate main (compiled natively) and a separate 'add' function (compiled managed). This is the main:

#include <iostream>
#include <windows.h>

extern int add(int,int);

class X
   {
   public:
      X(char *name) : m_name(name) {std::cout << "Constructing " << m_name << std::endl;}
      ~X() {Sleep(1000); std::cout << "Destructing " << m_name << std::endl;}
   private:
      char *m_name;
   };

X x1("x1");
X x2("x2");
X x3("x3");
X x4("x4");
X x5("x5");

int main()
{
std::cout << "In beginning of main" << std::endl;
int i = add(1,2);
std::cout << i << std::endl;
std::cout << "At end of main" << std::endl;
}

And this is the add.cpp file:

int add (int one, int two)
{
int result = one;
result += two;
return result;
}

They are compiled and linked using these commands (using VS2010 and .Net 4.0):

cl /c /EHsc /Od /Zi main.cpp
cl /c       /Od /Zi /clr add.cpp
link /debug /debugtype:cv main.obj add.obj mscoree.lib nochkclr.obj /nodefaultlib:libcmt.lib

This is the output if the application is run:

Constructing x1
Constructing x2
Constructing x3
Constructing x4
Constructing x5
In beginning of main
3
At end of main
Destructing x5

So the destruction of the global variables stops after the first one.

If I decrease the sleep from 1000 ms to 500 ms, global variables x5, x4 and x3 are destructed but then it also stops.

I uploaded the files to http://www.mediafire.com/?gil2hm2d3cw1zmz, so if you want to test this, you don't have to copy/paste or retype everything again.

EDIT: Slightly changed the title to make it more clear now that we have the actual cause of the problem.


Hmm confirming the problem. I'll need to think/read more about this. It is starting to look like a bug, really.


Note at no time did I run any of this with debugging, because my VS setup is somehow borked. Kudos for doing the commandline build!

For the record, here is my initial run (without recompiling, just your binary) on Win7-64, .NET 4.0, two CPU cores and 1Gb RAM):

C:\stacko>.\main.exe
Constructing x1
Constructing x2
Constructing x3
Constructing x4
Constructing x5
In beginning of main
3
At end of main
Destructing x5
Destructing x4
Destructing x3

Compiling it again locally didn't change anything. I double checked that this is indeed a mixed-mode artifact:

C:\stacko>cl /c /EHsc /Od /Zi main.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp


C:\stacko>link main.obj
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

C:\stacko>.\main.exe
Constructing x1
Constructing x2
Constructing x3
Constructing x4
Constructing x5
In beginning of main
At end of main
Destructing x5
Destructing x4
Destructing x3
Destructing x2
Destructing x1

Check: confirmed.


@sehe: Your own build is not mixed mode! That is why it is destructing properly.

If you want to build a mixed mode application you need to add /clr paremeter. Moreover it ist not possible to combine /clr with /EHsc, you have to use /EHa

cl /c /clr /EHa /Od /Zi main.cpp

However I am facing the same problem like the author...has anybody a solution?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜