Hello, I have a problem with a program that links with sqlite3 and executes an SQL statement. The program is executed under Qemu, with an 32-bit x86 emulated machine, and Qemu is running on a 64-bit x86 host. Originally, the program worked fine, when it was compiled with a toolchain composed out of gcc 4.9.2, glibc 2.21, binutils 2.24. Now I am rebuilding the system with a toolchain composed out of gcc 7.3, glibc 2.27, binutils 2.30. In this case, the program receives a SIGFPE (Arithmetic Error) in Sqlite code. Analysis of the coredump reveals that the error occurs on an 'fldl' instruction (Floating-point Load Long) and that the exact cause of the error is an underflow. The problem does not appear when Qemu is started without KVM support. In this case, floating point handling is covered by Qemu itself. The problem does occur when passing '-enable-kvm' which causes the host machine to execute most instructions. However, it is unclear to me why gcc is emitting an 'fldl' instruction here (which wasn't present with the old toolchain) and why it is causing an underflow. The part of the code being executed is not handling a floating-point value. There is a print of a real a bit further down, which is conditional on a flag indicating that the union indeed holds a real value. Could this 'fldl' instruction be part of that code, moved upwards? In that case, who is at fault here? Because the loading of the real should only happen when we know that it is indeed a real, and not an integer. I tried reproducing the problem with a simple program from the Sqlite 'Getting started' guide, running the same SQL query, and linking to the exact same binary copy of the sqlite shared library file, but this worked fine. The source code in question is: SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ int fg = pMem->flags; const int nByte = 32; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !(fg&MEM_ZerAny help is much appreciated.uio) ); assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( fg&(MEM_Int|MEM_Real) ); assert( (pMem->flags&MEM_RowSet)==0 ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ pMem->enc = 0; return SQLITE_NOMEM_BKPT; } /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 ** string representation of the value. Then, if the required encoding ** is UTF-16le or UTF-16be do a translation. ** ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ if( fg & MEM_Int ){ sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); }else{ assert( fg & MEM_Real ); sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); } pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); sqlite3VdbeChangeEncoding(pMem, enc); return SQLITE_OK; } The disassembly with the new toolchain (gcc 7.3.0) is below. I marked with leading # signs the part of the disassembly I do not understand and where the problem occurs. When the problem occurs, the value pointed to in %esi is '3'. 0001c1cb <sqlite3VdbeMemStringify>: SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ 1c1cb: 55 push %ebp 1c1cc: 89 e5 mov %esp,%ebp 1c1ce: 57 push %edi 1c1cf: 56 push %esi 1c1d0: 53 push %ebx 1c1d1: 83 ec 2c sub $0x2c,%esp 1c1d4: e8 fc ff ff ff call 1c1d5 <sqlite3VdbeMemStringify+0xa> 1c1d9: 81 c3 02 00 00 00 add $0x2,%ebx 1c1df: 89 c6 mov %eax,%esi 1c1e1: 89 55 d8 mov %edx,-0x28(%ebp) 1c1e4: 89 4d d4 mov %ecx,-0x2c(%ebp) int fg = pMem->flags; 1c1e7: 8b 40 08 mov 0x8(%eax),%eax 1c1ea: 66 89 45 de mov %ax,-0x22(%ebp) if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ 1c1ee: ba 20 00 00 00 mov $0x20,%edx 1c1f3: 89 f0 mov %esi,%eax 1c1f5: e8 5d bb ff ff call 17d57 <sqlite3VdbeMemClearAndResize> 1c1fa: 85 c0 test %eax,%eax 1c1fc: 74 0b je 1c209 <sqlite3VdbeMemStringify+0x3e> pMem->enc = 0; 1c1fe: c6 46 0a 00 movb $0x0,0xa(%esi) return SQLITE_NOMEM_BKPT; 1c202: bf 07 00 00 00 mov $0x7,%edi 1c207: eb 72 jmp 1c27b <sqlite3VdbeMemStringify+0xb0> --> exit # 1c209: 89 c7 mov %eax,%edi # 1c20b: dd 06 fldl (%esi) # 1c20d: dd 5d e0 fstpl -0x20(%ebp) # 1c210: 8b 46 10 mov 0x10(%esi),%eax if( fg & MEM_Int ){ 1c213: f6 45 de 04 testb $0x4,-0x22(%ebp) 1c217: 74 11 je 1c22a <sqlite3VdbeMemStringify+0x5f> sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); 1c219: 83 ec 0c sub $0xc,%esp 1c21c: ff 75 e4 pushl -0x1c(%ebp) 1c21f: ff 75 e0 pushl -0x20(%ebp) 1c222: 8d 93 00 00 00 00 lea 0x0(%ebx),%edx 1c228: eb 0f jmp 1c239 <sqlite3VdbeMemStringify+0x6e> sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); 1c22a: 83 ec 0c sub $0xc,%esp 1c22d: ff 75 e4 pushl -0x1c(%ebp) 1c230: ff 75 e0 pushl -0x20(%ebp) 1c233: 8d 93 00 00 00 00 lea 0x0(%ebx),%edx 1c239: 52 push %edx 1c23a: 50 push %eax 1c23b: 6a 20 push $0x20 1c23d: e8 fc ff ff ff call 1c23e <sqlite3VdbeMemStringify+0x73> 1c242: 83 c4 20 add $0x20,%esp 1c245: 0f b6 55 d8 movzbl -0x28(%ebp),%edx pMem->n = sqlite3Strlen30(pMem->z); 1c249: 8b 46 10 mov 0x10(%esi),%eax 1c24c: e8 a8 9d fe ff call 5ff9 <sqlite3Strlen30> 1c251: 89 46 0c mov %eax,0xc(%esi) pMem->enc = SQLITE_UTF8; 1c254: c6 46 0a 01 movb $0x1,0xa(%esi) pMem->flags |= MEM_Str|MEM_Term; 1c258: 8b 46 08 mov 0x8(%esi),%eax 1c25b: 89 c1 mov %eax,%ecx 1c25d: 83 e1 f3 and $0xfffffff3,%ecx 1c260: 66 81 c9 02 02 or $0x202,%cx 1c265: 66 0d 02 02 or $0x202,%ax 1c269: 80 7d d4 00 cmpb $0x0,-0x2c(%ebp) 1c26d: 0f 45 c1 cmovne %ecx,%eax 1c270: 66 89 46 08 mov %ax,0x8(%esi) sqlite3VdbeChangeEncoding(pMem, enc); 1c274: 89 f0 mov %esi,%eax 1c276: e8 5f d0 ff ff call 192da <sqlite3VdbeChangeEncoding> } 1c27b: 89 f8 mov %edi,%eax 1c27d: 8d 65 f4 lea -0xc(%ebp),%esp 1c280: 5b pop %ebx 1c281: 5e pop %esi 1c282: 5f pop %edi 1c283: 5d pop %ebp 1c284: c3 ret while the disassembly with the old toolchain is: 0001cdff <sqlite3VdbeMemStringify>: 1cdff: 55 push %ebp 1ce00: 89 e5 mov %esp,%ebp 1ce02: 57 push %edi 1ce03: 56 push %esi 1ce04: 53 push %ebx 1ce05: 83 ec 1c sub $0x1c,%esp 1ce08: e8 fc ff ff ff call 1ce09 <sqlite3VdbeMemStringify+0xa> 1ce0d: 81 c3 02 00 00 00 add $0x2,%ebx 1ce13: 89 c7 mov %eax,%edi 1ce15: 89 55 e0 mov %edx,-0x20(%ebp) 1ce18: 8b 45 08 mov 0x8(%ebp),%eax 1ce1b: 89 45 dc mov %eax,-0x24(%ebp) 1ce1e: 8b 47 08 mov 0x8(%edi),%eax 1ce21: 66 89 45 e6 mov %ax,-0x1a(%ebp) 1ce25: ba 20 00 00 00 mov $0x20,%edx 1ce2a: 89 f8 mov %edi,%eax 1ce2c: e8 be b8 ff ff call 186ef <sqlite3VdbeMemClearAndResize> 1ce31: 89 c6 mov %eax,%esi 1ce33: 85 c0 test %eax,%eax 1ce35: 74 0b je 1ce42 <sqlite3VdbeMemStringify+0x43> 1ce37: c6 47 0a 00 movb $0x0,0xa(%edi) 1ce3b: be 07 00 00 00 mov $0x7,%esi 1ce40: eb 60 jmp 1cea2 <sqlite3VdbeMemStringify+0xa3> 1ce42: f6 45 e6 04 testb $0x4,-0x1a(%ebp) (+0x43) 1ce46: 74 10 je 1ce58 <sqlite3VdbeMemStringify+0x59> 1ce48: 83 ec 0c sub $0xc,%esp 1ce4b: ff 77 04 pushl 0x4(%edi) 1ce4e: ff 37 pushl (%edi) 1ce50: 8d 83 00 00 00 00 lea 0x0(%ebx),%eax 1ce56: eb 0e jmp 1ce66 <sqlite3VdbeMemStringify+0x67> 1ce58: 83 ec 0c sub $0xc,%esp 1ce5b: ff 77 04 pushl 0x4(%edi) 1ce5e: ff 37 pushl (%edi) 1ce60: 8d 83 00 00 00 00 lea 0x0(%ebx),%eax 1ce66: 50 push %eax 1ce67: ff 77 10 pushl 0x10(%edi) 1ce6a: 6a 20 push $0x20 1ce6c: e8 fc ff ff ff call 1ce6d <sqlite3VdbeMemStringify+0x6e> 1ce71: 83 c4 20 add $0x20,%esp 1ce74: 8b 47 10 mov 0x10(%edi),%eax 1ce77: e8 e3 a2 fe ff call 715f <sqlite3Strlen30> 1ce7c: 89 47 0c mov %eax,0xc(%edi) 1ce7f: c6 47 0a 01 movb $0x1,0xa(%edi) 1ce83: 8b 47 08 mov 0x8(%edi),%eax 1ce86: 80 7d dc 00 cmpb $0x0,-0x24(%ebp) 1ce8a: 74 03 je 1ce8f <sqlite3VdbeMemStringify+0x90> 1ce8c: 83 e0 f3 and $0xfffffff3,%eax 1ce8f: 66 0d 02 02 or $0x202,%ax 1ce93: 66 89 47 08 mov %ax,0x8(%edi) 1ce97: 0f b6 55 e0 movzbl -0x20(%ebp),%edx 1ce9b: 89 f8 mov %edi,%eax 1ce9d: e8 eb ce ff ff call 19d8d <sqlite3VdbeChangeEncoding> 1cea2: 89 f0 mov %esi,%eax + 0xa3 1cea4: 8d 65 f4 lea -0xc(%ebp),%esp 1cea7: 5b pop %ebx 1cea8: 5e pop %esi 1cea9: 5f pop %edi 1ceaa: 5d pop %ebp 1ceab: c3 ret The backtrace from the coredump analysis is: (gdb) bt #0 0xb7513e3d in sqlite3VdbeMemStringify (pMem=0xb6b1a900, enc=<optimized out>, bForce=<optimized out>) at sqlite3.c:70739 #1 0xb7513f36 in valueToText (pVal=0xb6b1a900, enc=enc@entry=0x1) at sqlite3.c:71501 #2 0xb751405e in sqlite3ValueText (pVal=pVal@entry=0xb6b1a900, enc=enc@entry=0x1) at sqlite3.c:71534 #3 0xb7514074 in sqlite3_value_text (pVal=0xb6b1a900) at sqlite3.c:77123 #4 0xb75143dd in sqlite3_column_text (pStmt=0xb6b1a978, i=0x1) at sqlite3.c:77989 #5 0xb754a6a0 in sqlite3_exec (db=0xb6b02f78, zSql=<optimized out>, xCallback=0xb7558033 <sqlite3InitCallback>, pArg=0xb6c74c28, pzErrMsg=0x0) at sqlite3.c:112209 #6 0xb754697d in sqlite3VdbeExec (p=p@entry=0xb6b23508) at sqlite3.c:84727 #7 0xb7549bd4 in sqlite3Step (p=0xb6b23508) at sqlite3.c:77535 #8 sqlite3_step (pStmt=0xb6b23508) at sqlite3.c:12062 #9 0xb754a606 in sqlite3_exec (db=0xb6b02f78, zSql=<optimized out>, zSql@entry=0xb6b23200 "CREATE TABLE InterfaceTable(gem_port_obj_index_list varchar ,obj_index unsigned int ,ont_and_slot unsigned smallint ,pbit_tc_mapping unsigned int ,port unsigned tinyint ,sub_itf_obj_index_list varchar ,uni unsigned tinyint ,CONSTRAINT KEY_InterfaceTable PRIMARY KEY (obj_index))", xCallback=xCallback@entry=0x0, pArg=pArg@entry=0x0, pzErrMsg=pzErrMsg@entry=0xb6c74e6c) at sqlite3.c:112187 [...] #17 0xb76275eb in start_thread (arg=0xb6c75b40) at pthread_create.c:463 #18 0xb6fb6e96 in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:108 Any help is much appreciated. Best regards, Thomas