Рассмотрим следующий фрагмент кода:AV на Ctrl-C в деструкторе глобальной переменной
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <Windows.h>
using namespace std;
class A
{
public:
~A()
{
cout << "I am about to die" << endl;
}
};
A a;
int _tmain(int argc, _TCHAR* argv[])
{
while (true)
{
cout << "Waiting for ctrlc" << endl;
Sleep(1000);
}
}
При нажатии Ctrl-C Я получаю AV с следующим стеком вызовов:
0:001> kn
# Child-SP RetAddr Call Site
00 000000c0`dcdbf420 000007fe`9244fab9 MSVCP120D!std::locale::locale+0x2e [f:\dd\vctools\crt\crtw32\stdhpp\xlocale @ 324]
01 000000c0`dcdbf450 000007fe`92454e25 MSVCP120D!std::ios_base::getloc+0x29 [f:\dd\vctools\crt\crtw32\stdhpp\xiosbase @ 424]
*** WARNING: Unable to verify checksum for JustPlayC.exe
02 000000c0`dcdbf490 000007f7`524c33c0 MSVCP120D!std::basic_ios<char,std::char_traits<char> >::widen+0x25 [f:\dd\vctools\crt\crtw32\stdhpp\ios @ 127]
03 000000c0`dcdbf4f0 000007fe`9246570e JustPlayC!std::endl<char,std::char_traits<char> >+0x40 [c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream @ 999]
04 000000c0`dcdbf520 000007f7`524c2cb1 MSVCP120D!std::basic_ostream<char,std::char_traits<char> >::operator<<+0x2e [f:\dd\vctools\crt\crtw32\stdhpp\ostream @ 201]
05 000000c0`dcdbf550 000007f7`524cefb1 JustPlayC!A::~A+0x41
06 000000c0`dcdbf580 000007fd`edd558c3 JustPlayC!`dynamic atexit destructor for 'a''+0x21
07 000000c0`dcdbf5b0 000007fd`edd551b3 MSVCR120D!doexit+0x133 [f:\dd\vctools\crt\crtw32\startup\crt0dat.c @ 628]
08 000000c0`dcdbf620 000007fd`edd55aeb MSVCR120D!_cexit+0x13 [f:\dd\vctools\crt\crtw32\startup\crt0dat.c @ 449]
09 000000c0`dcdbf650 000007fd`edd559c1 MSVCR120D!__CRTDLL_INIT+0x10b [f:\dd\vctools\crt\crtw32\dllstuff\crtlib.c @ 325]
0a 000000c0`dcdbf6a0 000007fe`d916ecef MSVCR120D!_CRTDLL_INIT+0x31 [f:\dd\vctools\crt\crtw32\dllstuff\crtlib.c @ 215]
0b 000000c0`dcdbf6d0 000007fe`d9180f6c ntdll!LdrpCallInitRoutine+0x3f
0c 000000c0`dcdbf720 000007fe`d9180e0c ntdll!LdrShutdownProcess+0x142
0d 000000c0`dcdbf830 000007fe`d612870f ntdll!RtlExitUserProcess+0xac
0e 000000c0`dcdbf870 000007fe`d61286e7 KERNELBASE!DefaultHandler+0xf
0f 000000c0`dcdbf8a0 000007fe`d8841842 KERNELBASE!CtrlRoutine+0x9b
10 000000c0`dcdbf990 000007fe`d9174f45 KERNEL32!BaseThreadInitThunk+0x1a [d:\win8_gdr\base\win32\client\thread.c @ 65]
11 000000c0`dcdbf9c0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
Может кто-нибудь помочь мне понять, что происходит? Похоже, что локаль MSVCP получает uninitalized перед глобальным деструктором переменной, который полагается на локаль? Каков правильный способ обойти это?
Почему вы не устанавливаете обработчик сигнала и не закрываете программу правильно? –
Ну, конечно, есть много альтернатив. Но я хотел бы понять порядок неинициализации, который привел к AV. – Klark
Порядок инициализации и уничтожения глобальных переменных не указан. – songyuanyao