Read Access Violation

We use the SQLite library in our product and suddenly after recompiling with a different version of the compiler (Visual C ++), it started to crash on client computers.

Crash

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 failure code is as follows (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] 

Corresponding C code:

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

This 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 07148688 is readable and the instruction should read it, not write it.

We have memory dumps from two computers, and in both cases this happened on Athlon XP processors (Family / Model / Stepping: 6/10/0, 6/8/1).

Recompiling with several versions of Visual C ++ (2012, 2013 and 2013 Update 1) Yeilds is slightly different from the code (the movq vs movdqu command on the failure address), but the failure occurs sequentially.

Could this be caused by a processor or compiler error that we click?

+2
source share
1 answer

Older AMD Athlon processors (and Pentium III) do not seem to support this form of movq, which was introduced with SSE2 instructions. I quote Anders Carlson in the GCC Discussion :

Looking at Intel help 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 last two instructions are not supported on AMD and Pentium III, you will need another way to move data between xmm registers and memory.

This Intel reference documentation is no longer available; another link for the movq command is at http://x86.renejeschke.de/html/file_module_x86_id_201.html . However, I do not have AMD Athlon XP to test this.

Disabling SSE2 optimization should solve the problem. The SSE2 instruction set is the default in VS2012 and later, and the / arch compiler flag controls which command should be used; see http://msdn.microsoft.com/en-us/library/7t5yh4fd%28v=vs.110%29.aspx .

+3
source

All Articles