#.net #c #timeout #global-variables #destructor
#.net #c #тайм-аут #глобальные переменные #деструктор
Вопрос:
В моем приложении C смешанного режима я замечаю следующие странные эффекты:
- Если я запускаю исполняемый файл вне Visual Studio, все неуправляемые глобальные переменные правильно уничтожаются.
- Если я запускаю исполняемый файл вне Visual Studio, а затем подключаю отладчик, все неуправляемые глобальные переменные правильно уничтожаются.
- При Запуске исполняемого файла внутри отладчика Visual Studio не все неуправляемые глобальные переменные, похоже, уничтожены.
Я прочитал это.У Net есть 2-секундный тайм-аут для очистки. Означает ли это полное уничтожение неуправляемой глобальной переменной? Или это для каждого деструктора?
Я совершенно уверен, что причиной является этот 2-секундный тайм-аут, потому что, когда я устанавливаю точку останова в начале метода doexit, отладчик останавливается на этом, когда приложение завершается. Но если я установлю точку останова ближе к концу функции doexit, эта точка останова никогда не будет достигнута.
Есть ли способ изменить этот 2-секундный тайм-аут из приложения? Проблема в том, что если не все глобальные переменные уничтожены, моя система обнаружения утечек памяти сообщит о большом количестве утечек памяти.
Редактировать:
Это пример программы, показывающий проблему.
Поскольку я хотел создать приложение смешанного режима, я написал отдельный main (скомпилированный изначально) и отдельную функцию ‘add’ (скомпилированный управляемый). Это основная:
#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 resu<
}
Они компилируются и связываются с помощью этих команд (с использованием 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, поэтому, если вы хотите протестировать это, вам не нужно копировать / вставлять или перепечатывать все снова.
РЕДАКТИРОВАТЬ: Немного изменил заголовок, чтобы теперь было более понятно, что у нас есть фактическая причина проблемы.
Комментарии:
1. Это интересный вопрос. Я думаю, люди захотят подключиться, если бы в вопросе была минимальная рабочая демонстрация этого 🙂
2. Хорошо, пример приложения теперь подключен к Сети.
3. Жаль, что я могу ответить только на 1 этот вопрос. Теперь это отличный вопрос!
Ответ №1:
Хм, подтверждаю проблему. Мне нужно подумать / прочитать больше об этом. На самом деле это начинает выглядеть как ошибка.
Обратите внимание, что я ни разу не запускал ничего из этого с отладкой, потому что моя установка 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
Проверка: подтверждена.
Ответ №2:
@sehe: Ваша собственная сборка не работает в смешанном режиме! Вот почему он уничтожается должным образом.
Если вы хотите создать приложение смешанного режима, вам необходимо добавить параметр /clr paremeter. Более того, невозможно объединить /clr с /EHsc, вы должны использовать /EHa
cl /c /clr /EHa /Od /Zi main.cpp
Однако я сталкиваюсь с той же проблемой, что и автор … у кого-нибудь есть решение?