Mantis - Squeak Packages
Viewing Issue Advanced Details
3929 FFI major always 06-28-06 19:41 04-08-10 14:32
nicolas cellier  
andreas  
normal  
resolved 3.9  
fixed  
none    
none  
0003929: [BUG][FFI] strange behavior on unix vm/plugin: seventh call lead to unconsistent results
The test case provided in attached files will return false from the seventh call on, when it should always return true.

try
    DLANGE2Library testDLANGE2.

Behaviour is very strange.
It's like the image is getting corrupted.
When executing step by step in Debugger, of course the bug does not show up...
place libdlange2.so in local directory, launch squeak, load DLANGE2Library.st, save the image.

Then execute
    DLANGE2Library testDLANGE2 inspect.

You should get an array with 10 true. But starting at 7, all elements are false.
This bug did not show on a windows XP platform.
 DLANGE2Library.st [^] (1,549 bytes) 06-28-06 19:42
 libdlange2.so [^] (1,719 bytes) 06-28-06 19:42
 dlange2.c [^] (324 bytes) 06-28-06 19:43

Notes
(0005412)
nicolas cellier   
06-28-06 19:47   
You can compile the library with:
    gcc -c dlange2.c; ld -shared -o libdlange2.so dlange2.o

SUBROUTINE DLANGE is a FORTRAN routine from LAPACK library to compute a matrix norm. I use it for SUnit TestCase checks on my Smallapack port to Squeak (Smalltalk interface to LAPACK).

It as been translated by f2c, then changed to simply return 0.0.

By now, Smallapack port to Squeak is blocked by this bug.
(0005418)
andreas   
06-28-06 21:40   
You need to do some of your own debugging first. Start out with:
- Telling us what OS, hardware (CPU), architecture you are running on
- Check whether later versions of the VM also have this problem or if it's specific to your version
- Check what the *actual* result of the call is (e.g., whether it compares equal to 0.0 is a completely useless bit of information here)
- Change the return value from 0.0 to something else (say 42.0) since the bit pattern for 0.0 is equal to zero is equal to NULL etc. Put differently there is no guarantee that your call *ever* returns the correct result
- Asking Ian whether there are any known problems with FFI support
(0005422)
nicolas cellier   
06-28-06 22:29   
Thanks Andreas

MY SYSTEM (A MANDRAKE 9 LINUX)
- uname -a is:
Linux wifi2 2.4.29 0000004 mer f� 23 01:09:47 CET 2005 i686 unknown unknown GNU/Linux

MY SQUEAK VM
(IT IS THE REGULAR STABLE RELEASE FROM squeak.org)
- squeak -version is:
3.7-7 #1 Sat Mar 19 13:12:20 PST 2005 gcc 3.3.5
Squeak3.7 of '4 September 2004' [latest update: #5989]
Linux squeak.hpl.hp.com 2.4.27-1-386 #1 Fri Sep 3 06:24:46 UTC 2004 i686 GNU/Linux
default plugin location: /usr/local/lib/squeak/3.7-7/*.so

THE RESULT ANSWERED BY THE FFI CALL
- if i write the test as:
   | val |
   val = self dlange...etc...
   val = 0.0
what i obtain is false, but val is perfectly equal to zero (evaluating val=0.0 or val isZero in the debugger will answer true).
So yes, the correct value is returned, and that is what i call strange behavior

I'am going to inquire newer VM and FFI plugin and ask Ian...
(0005658)
andreas   
07-09-06 06:53   
Is there any news on this issue? Anything that can be done before 3.9 goes gold?
(0012919)
nicolas cellier   
01-11-09 01:43   
I tried and debug via gdb, put a break point at ffiCallAddressOf+49

(gdb) disas ffiCallAddressOf
0x08090a08 <ffiCallAddressOf+0>: push %ebp
0x08090a09 <ffiCallAddressOf+1>: mov %esp,%ebp
0x08090a0b <ffiCallAddressOf+3>: mov 0x10(%ebp),%ecx
0x08090a0e <ffiCallAddressOf+6>: test %ecx,%ecx
0x08090a10 <ffiCallAddressOf+8>: je 0x8090a25 <ffiCallAddressOf+29>
0x08090a12 <ffiCallAddressOf+10>: sub %ecx,%esp
0x08090a14 <ffiCallAddressOf+12>: sub $0x4,%ecx
0x08090a17 <ffiCallAddressOf+15>: mov 0xc(%ebp),%edx
0x08090a1a <ffiCallAddressOf+18>: mov (%edx,%ecx,1),%eax
0x08090a1d <ffiCallAddressOf+21>: mov %eax,(%esp,%ecx,1)
0x08090a20 <ffiCallAddressOf+24>: sub $0x4,%ecx
0x08090a23 <ffiCallAddressOf+27>: jae 0x8090a1a <ffiCallAddressOf+18>
0x08090a25 <ffiCallAddressOf+29>: call *0x8(%ebp)
0x08090a28 <ffiCallAddressOf+32>: mov %eax,0x812a760
0x08090a2d <ffiCallAddressOf+37>: mov %edx,0x812a764
0x08090a33 <ffiCallAddressOf+43>: fstl 0x8129f40
0x08090a39 <ffiCallAddressOf+49>: mov %ebp,%esp
0x08090a3b <ffiCallAddressOf+51>: pop %ebp
0x08090a3c <ffiCallAddressOf+52>: ret
0x08090a3d <ffiCallAddressOf+53>: nop
0x08090a3e <ffiCallAddressOf+54>: nop
0x08090a3f <ffiCallAddressOf+55>: nop
End of assembler dump.

It seems like the floating point register stack overflows...
Though ffiFloatReturnValue is always 0.0, I further get a NaN at 7th call to primitiveFloatEqualtoArg, maybe because this one needs two fp registers for comparands and fp stack only has one slot left...
Here is the process:

(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb)
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x3ff889731d0000000000
  R6: Empty 0x00000000000000000000
=>R5: Zero 0x00000000000000000000 +0
  R4: Empty 0x00000000000000000000
  R3: Empty 0x40008cabcfae00000000
  R2: Empty 0x00000000000000000000
  R1: Empty 0xc002989e10f340000000
  R0: Empty 0x00000000000000000000

Status Word: 0x6861 IE PE SF C3
                       TOP: 5
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf7ff
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x3ff889731d0000000000
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
=>R4: Zero 0x00000000000000000000 +0
  R3: Empty 0x00000000000000000000
  R2: Empty 0x00000000000000000000
  R1: Empty 0xc002989e10f340000000
  R0: Empty 0x00000000000000000000

Status Word: 0x6061 IE PE SF C3
                       TOP: 4
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf5ff
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x3ff889731d0000000000
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
  R4: Zero 0x00000000000000000000 +0
=>R3: Zero 0x00000000000000000000 +0
  R2: Empty 0x00000000000000000000
  R1: Empty 0xc002989e10f340000000
  R0: Empty 0x00000000000000000000

Status Word: 0x5861 IE PE SF C3
                       TOP: 3
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf57f
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x3ff889731d0000000000
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
  R4: Zero 0x00000000000000000000 +0
  R3: Zero 0x00000000000000000000 +0
=>R2: Zero 0x00000000000000000000 +0
  R1: Empty 0x00000000000000000000
  R0: Empty 0x00000000000000000000

Status Word: 0x5061 IE PE SF C3
                       TOP: 2
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf55f
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x3ff889731d0000000000
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
  R4: Zero 0x00000000000000000000 +0
  R3: Zero 0x00000000000000000000 +0
  R2: Zero 0x00000000000000000000 +0
=>R1: Zero 0x00000000000000000000 +0
  R0: Empty 0x00000000000000000000

Status Word: 0x4861 IE PE SF C3
                       TOP: 1
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf557
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
  R7: Empty 0x00000000000000000000
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
  R4: Zero 0x00000000000000000000 +0
  R3: Zero 0x00000000000000000000 +0
  R2: Zero 0x00000000000000000000 +0
  R1: Zero 0x00000000000000000000 +0
=>R0: Zero 0x00000000000000000000 +0

Status Word: 0x4061 IE PE SF C3
                       TOP: 0
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0xf555
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb) info float
=>R7: Zero 0x00000000000000000000 +0
  R6: Empty 0x00000000000000000000
  R5: Zero 0x00000000000000000000 +0
  R4: Zero 0x00000000000000000000 +0
  R3: Zero 0x00000000000000000000 +0
  R2: Zero 0x00000000000000000000 +0
  R1: Zero 0x00000000000000000000 +0
  R0: Zero 0x00000000000000000000 +0

Status Word: 0x7861 IE PE SF C3
                       TOP: 7
Control Word: 0x127f IM DM ZM OM UM PM
                       PC: Double Precision (53-bits)
                       RC: Round to nearest
Tag Word: 0x7555
Instruction Pointer: 0x00:0x00000000
Operand Pointer: 0x00:0x00000000
Opcode: 0x0000
(gdb) x /1lf 0x8129f40
0x8129f40 <ffiFloatReturnValue>: 0
(gdb) cont
Continuing.

Breakpoint 9, ffiCallAddressOf ()
    at /windata/Smalltalk/Squeak/Squeak-3.10-1/platforms/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S:51
51 fstl ffiFloatReturnValue
(gdb)


Calling convention mismatch ?
Or lack of a pop (fstlp 0x8129f40) in ffiCallAddressOf ?

I declared to be cdecl:
    <cdecl: double 'dlange_'( char * long * long * double * long * double * long )>
    ^self externalCallFailed

Was it all right ?
Can someone confirm what I say ?
I don't want to dig more and become an expert of IA-32 !
(0012920)
nicolas cellier   
01-11-09 20:36   
Changing line 51 of x86-sysv-asm.S solved this problem:

    fstpl ffiFloatReturnValue

I do not know other implications. Please check.
(0012922)
nicolas cellier   
01-15-09 07:25   
Eliot Miranda suggested that a fninit be placed in FFI preamble (of course, before starting to stack arguments), and maybe in other relevant places in the VM.

See http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-January/133575.html [^]
(0013627)
nicolas cellier   
04-06-10 20:34   
Fixed in unix VM 3.11-3