Не все собственные глобальные переменные уничтожаются в смешанном режиме .Net приложения из-за 2-секундного тайм-аута - PullRequest
4 голосов
/ 17 мая 2011

В моем приложении C ++ в смешанном режиме я замечаю следующие странные эффекты:

  • Если я запускаю исполняемый файл вне Visual Studio, все неуправляемые глобальные переменные корректно уничтожаются.
  • Если я запускаю исполняемый файл вне Visual Studio, а затем присоединяю отладчик, все неуправляемые глобальные переменные корректно уничтожаются.
  • Когда я запускаю исполняемый файл в отладчике Visual Studio, не все неуправляемые глобальные переменные кажутся разрушенными.

Я прочитал, что .Net имеет 2-секундный таймаут для очистки. Это для всего неуправляемого уничтожения глобальной переменной? Или это на деструктор?

Я совершенно уверен, что причиной этого 2-секундного таймаута является то, что, когда я устанавливаю точку останова в начале метода doexit, отладчик останавливается там, когда приложение завершается. Но если я установлю точку останова в конце функции doexit, эта точка останова никогда не будет достигнута.

Есть ли способ изменить этот 2-секундный тайм-аут из приложения? Проблема в том, что если не все глобальные переменные будут уничтожены, моя система обнаружения утечек памяти сообщит о большом количестве утечек памяти.

EDIT:

Это пример программы, показывающей проблему.

Поскольку я хотел создать приложение в смешанном режиме, я написал отдельную основную (скомпилированную изначально) и отдельную функцию добавления (скомпилированную управляемую). Это главное:

#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;
}

А это файл add.cpp:

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

Они скомпилированы и связаны с помощью этих команд (используя VS2010 и .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

Это вывод, если приложение запущено:

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

Таким образом, уничтожение глобальных переменных прекращается после первой.

Если я уменьшу время сна с 1000 мс до 500 мс, глобальные переменные x5, x4 и x3 будут уничтожены, но затем также остановятся.

Я загрузил файлы в http://www.mediafire.com/?gil2hm2d3cw1zmz,, поэтому, если вы хотите проверить это, вам не нужно копировать / вставлять или перепечатывать все заново.

РЕДАКТИРОВАТЬ: Немного изменил заголовок, чтобы теперь стало понятнее, когда у нас есть реальная причина проблемы.

Ответы [ 2 ]

1 голос
/ 18 мая 2011

Хм, подтверждающий проблему. Мне нужно подумать / прочитать больше об этом. На самом деле это начинает выглядеть как ошибка.


Примечание я ни разу не запустил что-либо из этого с отладкой, потому что моя установка VS каким-то образом не работает. Слава за создание командной строки!

Для справки, вот мой начальный запуск (без перекомпиляции, только ваш двоичный файл) на Win7-64, .NET 4.0, двух ядрах процессора и 1 ГБ ОЗУ):

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

Компиляция снова локально ничего не изменила. Я дважды проверил, что это действительно артефакт смешанного режима:

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

Проверка: подтверждена.

0 голосов
/ 16 мая 2012

@ sehe: Ваша собственная сборка не в смешанном режиме! Вот почему он разрушает должным образом.

Если вы хотите создать приложение в смешанном режиме, вам нужно добавить / clr paremeter. Более того, невозможно объединить / clr с / EHsc, вы должны использовать / EHa

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

Однако я сталкиваюсь с той же проблемой, что и автор ... у кого-нибудь есть решение?

...