帧指针寄存器'ebx'由xatomic.h中的内联汇编代码修改

时间:2014-01-13 09:53:23

标签: c++ visual-studio-2012 boost assembly atomic

好吧,我停下了我遇到过的最隐蔽的错误。我会评论几乎完全相同的问题,但我没有足够的声誉.. :( 这个bug的作用是我的程序试图在程序试图从函数返回时不可执行的内存区域上执行。 “执行地址0x00000000”的访问冲突。 我跟踪了Visual Studio 2012的xatomic.h头文件(#include'atomic'C ++ 11标准头文件)中发生的错误,它在x86内联汇编中覆盖了ebx寄存器。一旦发生这种情况,线程的堆栈将被永久销毁。

我确切地知道这种情况何时发生。该错误由boost :: lockfree :: queue :: empty()函数触发,并且仅在具有优化的发布版本中触发。 empty()函数必须由编译器内联到它的调用函数中。该程序在调试模式下工作得很好,因为没有内联empty()函数。

我收到许多关于修改ebx寄存器的编译器警告:

"include\boost-1_55\boost\atomic\detail\windows.hpp(1598): warning C4731: 'BuzyStack<JobPool>::push' : frame pointer register 'ebx' modified by inline assembly code"
"include\boost-1_55\boost\atomic\detail\windows.hpp(1598): warning C4731: 'BuzyStack<JobPool>::push' : frame pointer register 'ebx' modified by inline assembly code"
"y:\work\visualstudio\vc\include\xatomic.h(2133): warning C4731: 'ThreadSubSystem::join_pool' : frame pointer register 'ebx' modified by inline assembly code"
"y:\work\visualstudio\vc\include\xatomic.h(2137): warning C4731: 'ThreadSubSystem::join_pool' : frame pointer register 'ebx' modified by inline assembly code"

BuzyStack是我管理线程池的并发“线程池堆栈”。可以同时将项目推送到BuzyStack /来自BuzyStack。

我真的需要boost :: lockfree :: queue :: empty()函数,所以如何解决这个问题呢?

我所做的是相当激进的行动。我修改了Visual Studio 2012(Update 4)xatomic.h头__asm {}部分,其中ebx寄存器被覆盖。我强制保留ebx寄存器,将其保存在__asm块的开头,进入temporal var并在__asm块结束时恢复ebx。这有效。错误消失了,但我仍然可以在我的程序中看到调用堆栈临时无效的点。当我做这个改变时,编译器警告的数量也增加了一倍。

(适用更新) 很抱歉不清楚这个问题:很简单:我该如何修复这个错误?我好像是MSVC编译器的错。

我的代码中没有任何内联asm代码。所有警告都是由boost-1.55原子和无锁库以及MSVC 2012 xatomic.h头中的代码生成的。 标准头mod只是一个临时的解决方法,我不再使用modded头,也不使用empty()函数。如果我尝试调用empty()函数,bug仍然存在并且今天会破坏我的堆栈。

0 个答案:

没有答案