This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Corrupted stack on Sparc with Python CFFI


Hi!

I have run into the following problem with Python CFFI when running on
Sparc V8. The platform is the following:

 - Linux smetana 2.6.32-5-sparc64-smp #1 SMP Mon Feb 25 02:19:08 UTC 2013 sparc64 GNU/Linux
 - libffi 3.0.13
 - python-cffi 0.8.1 (also tried with Mercurial repository)
 - 32bit userspace, latest Debian unstable

Here is a simple Python program to trigger the bug:

#+begin_src python
#!/usr/bin/python

from cffi import FFI
import cffi.verifier
cffi.verifier._FORCE_GENERIC_ENGINE = True

ffi = FFI()
ffi.cdef("""
        typedef struct { ...; } myhandle_t;
        myhandle_t foo(void);
    """)
lib = ffi.verify("""
        typedef short myhandle_t;
        myhandle_t foo(void) { return 42; }
    """, extra_compile_args=["-g", "-O0"])
print lib.foo()
#+end_src

If you are not familiar with python cffi, testing for the bug is quite
easy, download cffi from here:
 https://pypi.python.org/pypi/cffi

Run "python setup.py build_ext -i", copy the above file in the current
directory and execute it with python. You get an illegal instruction
error.

The generated code contains the following bits:

#+begin_src c
typedef short myhandle_t;
myhandle_t foo(void) { return 42; }

myhandle_t _cffi_f_foo(void)
{
  return foo();
}
#+end_src

When the illegal instruction occurs, I have this in gdb:

#+begin_example
(gdb) bt
#0  _cffi_f_foo () at __pycache__/_cffi__gc12d9a91xdd04fb9c.c:48
#1  0xf7ff401c in ?? ()
#2  0xf7ff4020 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) disassemble 0xf7ff4008,+30                                                                            
Dump of assembler code from 0xf7ff4008 to 0xf7ff4026:
   0xf7ff4008:  mov  %i7, %l7
   0xf7ff400c:  mov  %o7, %i7
   0xf7ff4010:  sethi  %hi(0xf78d0400), %g1
   0xf7ff4014:  call  %g1 + 0x228       ! 0xf78d0628 <_cffi_f_foo>
   0xf7ff4018:  nop 
   0xf7ff401c:  illtrap  0x2
   0xf7ff4020:  ret 
   0xf7ff4024:  mov  %l7, %i7
#+end_example

So, the code seems the one generated in `ffi.c`. I don't know if it is
expected that the return pointer is set on the illtrap instruction and
the next one on ret.

When executing step by step the code before the stacks become corrupt
after calling _cffi_f_foo:

#+begin_example
(gdb) bt 2
#0  0xf7ff400c in ?? ()
#1  0xf7af5b38 in ffi_call_v8 () at ../src/sparc/v8.S:89
(More stack frames follow...)
(gdb) si
0xf7ff4010 in ?? ()
(gdb) bt 2
#0  0xf7ff4010 in ?? ()
#1  0xf7af5b38 in ffi_call_v8 () at ../src/sparc/v8.S:89
(More stack frames follow...)
(gdb) si
0xf7ff4014 in ?? ()
(gdb) bt 2
#0  0xf7ff4014 in ?? ()
#1  0xf7af5b38 in ffi_call_v8 () at ../src/sparc/v8.S:89
(More stack frames follow...)
(gdb) si
0xf7ff4018 in ?? ()
(gdb) bt 2
#0  0xf7ff4018 in ?? ()
#1  0xf7ff4020 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) si
_cffi_f_foo () at __pycache__/_cffi__gc12d9a91xdd04fb9c.c:47
47      {
(gdb) bt 4
#0  _cffi_f_foo () at __pycache__/_cffi__gc12d9a91xdd04fb9c.c:47
#1  0xf7ff401c in ?? ()
#2  0xf7ff4020 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
#+end_example

I absolutely don't know how the Sparc ABI should work (and I have a hard
time even understanding what the illtrap/unimp instruction is used
for). Is there something that could explain this behaviour?

_cffi_f_foo is like this:

#+begin_src asm
Dump of assembler code for function _cffi_f_foo:
   0xf78d0628 <+0>:     save  %sp, -96, %sp
   0xf78d062c <+4>:     call  0xf78d05c0 <foo>
   0xf78d0630 <+8>:     nop 
   0xf78d0634 <+12>:    mov  %o0, %g1
=> 0xf78d0638 <+16>:    sll  %g1, 0x10, %g1
   0xf78d063c <+20>:    sra  %g1, 0x10, %g1
   0xf78d0640 <+24>:    mov  %g1, %i0
   0xf78d0644 <+28>:    rett  %i7 + 8
   0xf78d0648 <+32>:    nop 
#+end_src

After returning, I got to the illtrap instruction and get a SIGILL.
-- 
printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",
dev->name);
	2.4.0-test2 /usr/src/linux/drivers/net/tokenring/lanstreamer.c


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]