visual-c++ - 读指令的写访问冲突

标签 visual-c++ optimization compiler-construction processor amd-processor

我们在产品中使用 SQLite 库,在使用不同的编译器版本 (Visual C++) 重新编译后突然开始在客户计算机上崩溃。

崩溃是

ExceptionAddress: 0710eadd (sqlite3!sqlite3_transfer_bindings+0x0004e5bd)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 07148688
Attempt to write to address 07148688

导致崩溃的代码如下(sqlite3MutexInit 的一部分):

0710ead0 b804811407      mov     eax, 0x07148104
0710ead5 b97c861407      mov     ecx, 0x0714867c
0710eada 0f44c8          cmove   ecx, eax
0710eadd f30f7e410c      movq    xmm0, mmword ptr [ecx+0Ch]

对应的C代码:

if( sqlite3GlobalConfig.bCoreMutex ){
  pFrom = sqlite3DefaultMutex();
}else{
  pFrom = sqlite3NoopMutex();
}
memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));

这并不是特别重要,但在我们的例子中 sqlite3GlobalConfig.bCoreMutex 设置为 1。

问题在于,在这种特殊情况下,地址 07148688 处的内存是可读的,并且指令应该读取它,而不是写入它。

我们有来自两台机器的内存转储,这两种情况都发生在 Athlon XP 处理器上(系列/型号/步进:6/10/0、6/8/1)。

使用多个 Visual C++ 版本(2012、2013 和 2013 Update 1)重新编译会产生略有不同的代码(错误地址处的 movq 与 movdqu 指令),但崩溃始终发生。

这可能是由我们遇到的处理器或编译器错误引起的吗?

最佳答案

较旧的 AMD Athlon(和 Pentium III)处理器显然不支持这种形式的 movq,它是通过 SSE2 指令引入的。我在 GCC discussion 中引用了安德斯·卡尔森 (Anders Carlsson) 的话。 :

Looking at the Intel reference documentation available from ftp://download.intel.com/design/Pentium4/manuals/25366614.pdf MOVQ has the following opcodes:

0F 6F /r MOVQ mm, mm/m64      Move quadword from mm/m64 to mm. 
0F 7F /r MOVQ mm/m64, mm      Move quadword from mm to mm/m64. 
F3 0F 7E MOVQ xmm1, xmm2/m64  Move quadword from xmm2/mem64 to xmm1.
66 0F D6 MOVQ xmm2/m64, xmm1  Move quadword from xmm1 to xmm2/mem64.

and since the two latter instructions are unsupported on AMD and Pentium III you would need some other way to move data between the xmm registers and memory.

英特尔引用文档不再可用; movq 指令的另一个引用位于 http://x86.renejeschke.de/html/file_module_x86_id_201.html 。不过,我没有 AMD Athlon XP 来对此进行测试。

关闭 SSE2 优化应该可以解决该问题。 SSE2指令集是VS2012及更高版本中默认的,/arch编译器标志控制使用哪个指令集;请参阅http://msdn.microsoft.com/en-us/library/7t5yh4fd%28v=vs.110%29.aspx .

关于visual-c++ - 读指令的写访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21256792/

相关文章:

mysql - 如何优化这个包含 5 个子查询的查询?

c - AVR C 编译器行为。内存管理

compiler-construction - 如何创建 Clojure Lint?

c++ - 如何计算文本文件中的字符数

c++ - 错误 LNK2019 和 LNK 1120

php - 获得上个月的第一天和最后一天的最佳方式?

c++ - 访问者或节点中的 AST 遍历?

c++ - std::out_of_range at memory location error at getline

c++ - “超出 PCH 的虚拟范围”问题 - 在 Visual Studio 2019 升级到 16.7.6 之后

database - 字典数据库大小——哪些算法和策略让它如此轻便?