问题
We use SQLite library in our product and suddenly after recompilation with different compiler version (Visual C++) it started crashing on customer computers.
The crash is
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
and the code causing the crash is the following (part of sqlite3MutexInit):
0710ead0 b804811407 mov eax, 0x07148104
0710ead5 b97c861407 mov ecx, 0x0714867c
0710eada 0f44c8 cmove ecx, eax
0710eadd f30f7e410c movq xmm0, mmword ptr [ecx+0Ch]
The corresponding C code:
if( sqlite3GlobalConfig.bCoreMutex ){
pFrom = sqlite3DefaultMutex();
}else{
pFrom = sqlite3NoopMutex();
}
memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
It is not particularly important, but in our case sqlite3GlobalConfig.bCoreMutex is set to 1.
The problem is that in this particular case the memory at address 07148688 is readable and the instruction is supposed to read it, not write it.
We have memory dumps from two machines and in both cases it happened on Athlon XP processors (Family/Model/Stepping: 6/10/0, 6/8/1).
Recompilation with several Visual C++ versions (2012, 2013 and 2013 Update 1) yeilds slightly different code (movq vs movdqu instruction at the faulting address), but the crash happens consistently.
Could it be caused by processor or compiler bug we are hitting?
回答1:
The older AMD Athlon (and Pentium III) processors apparently do not support this form of movq which was introduced with SSE2 instructions. I quote Anders Carlsson in a GCC discussion:
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.
That Intel reference documentation is no longer available; another reference for the movq instruction is at http://x86.renejeschke.de/html/file_module_x86_id_201.html. I don't have an AMD Athlon XP to test this against, though.
Turning off SSE2 optimizations should resolve the problem. SSE2 instruction set is the default in VS2012 and later, and the /arch compiler flag controls which instruction set to use; see http://msdn.microsoft.com/en-us/library/7t5yh4fd%28v=vs.110%29.aspx.
来源:https://stackoverflow.com/questions/21256792/write-access-violation-on-read-instruction