简体   繁体   English

全局变量的析构函数中ctrl-c上的AV

[英]AV on ctrl-c in destructor of global variable

Consider following snippet: 考虑以下代码段:

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

When I press ctrl-c I get an AV with following callstack: 当我按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

Can anyone help me understand what is going on? 谁能帮助我了解发生了什么事? Looks like MSVCP locale gets uninitalized before global variable destructor which relies on locale? 看起来MSVCP语言环境在依赖于语言环境的全局变量析构函数之前未初始化吗? What is the proper way to get around this? 解决此问题的正确方法是什么?

From my understanding of the way the runtime works is that the global variable A is created at initialization time of the runtime, before main() is called. 根据我对运行时工作方式的理解,是在调用main()之前,在运行时初始化时创建全局变量A。 It is therefore tied to the locale of the underlying OS rather than the local of the application in this instance. 因此,在这种情况下,它绑定到基础OS的语言环境,而不是应用程序的本地语言。 The locale of the application is therefore disposed before the global is destructed. 因此,应在销毁全局变量之前处理应用程序的语言环境。 As someone pointed out, if you want the destructor to use the locale of the application, then the best way is to use a handler for ctrl-c. 正如有人指出的那样,如果您希望析构函数使用应用程序的语言环境,那么最好的方法是对ctrl-c使用处理程序。 However, if this object was constructed inside of main, then it becomes a true runtime construction and wouldn't suffer this issue. 但是,如果此对象是在main内部构造的,则它将成为真正的运行时构造,并且不会遇到此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM