gpt4 book ai didi

c++ - 函数本地静态函数为Windows XP生成错误代码

转载 作者:行者123 更新时间:2023-12-01 14:55:26 25 4
gpt4 key购买 nike

我最初将其发布在ReverseEngineering StackExchange上,但并不确切知道它所属的位置。我决定将它张贴在这里。

最近,Microsoft Visual Studio 2015编译器最终符合C++标准要求,以生成用于函数局部静态函数的线程安全代码。在大多数情况下,这工作正常,但在Windows XP上遇到了以下3条说明导致崩溃的情况:

mov     eax,dword ptr fs:[0000002Ch]
mov ecx,dword ptr [MyModule!_tls_index (102eea44)]
mov ecx,dword ptr [eax+ecx*4]

显然,编译器似乎通过首先插入当前线程的TLS插槽来实现线程安全。 fs:2Ch应该导致每个文档使用TLS数组。但是,在Windows XP上,似乎未设置 fs:2Ch。这为我返回了0,所以下一条指令也是如此( _tls_index也是0。)由于访问无效内存,导致第三条指令崩溃。

有人知道为什么Windows XP可能不会设置 fs:2Ch吗?函数局部静态函数在我们的所有代码中都使用,我无法想象没有其他人会遇到这种情况。

更新

我已经仔细考虑了我应用于此问题的每个标签。请不要添加或删除任何内容。

最佳答案

在C++ 11标准中,在进行任何其他初始化之前,必须将具有静态或线程存储持续时间的块作用域变量初始化为零。当控制首先通过变量的声明时,发生初始化。如果在初始化过程中引发异常,则该变量将被视为未初始化,并在下次控件通过声明时重新尝试初始化。如果控件在初始化的同时输入声明,则在初始化完成时并发执行会阻塞。如果控件在初始化期间递归地重新输入声明,则该行为是不确定的。默认情况下,从Visual Studio 2015开始的Visual Studio会实现此标准行为。可以通过设置/ Zc:threadSafeInit编译器选项来明确指定此行为。 +
静态局部变量的线程安全初始化依赖于通用C运行时库(UCRT)中实现的代码。为避免依赖UCRT,或保留Visual Studio 2015之前版本的Visual Studio的非线程安全初始化行为,请使用/ Zc:threadSafeInit-选项。如果您知道不需要线程安全,请使用此选项在静态本地声明周围生成稍微小的更快的代码。
线程安全的静态局部变量在内部已使用静态局部变量(TLS)进行内部初始化时提供了高效的执行效率。此功能的实现依赖于Windows Vista和更高版本的操作系统中的Windows操作系统支持功能。 Windows XP,Windows Server 2003和较早的操作系统不具有此支持,因此它们没有获得效率优势。这些操作系统对可以加载的TLS节的数量也有较低的限制。超过TLS部分限制可能会导致崩溃。如果这是您的代码中的问题,尤其是在必须在较旧的操作系统上运行的代码中,请使用/ Zc:threadSafeInit-禁用线程安全的初始化代码。

关于c++ - 函数本地静态函数为Windows XP生成错误代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41152935/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com