public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Vincent Bernat <bernat@luffy.cx>
To: libffi-discuss@sourceware.org
Subject: Corrupted stack on Sparc with Python CFFI
Date: Sat, 21 Dec 2013 23:20:00 -0000	[thread overview]
Message-ID: <m31u15ssed.fsf@neo.luffy.cx> (raw)

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

                 reply	other threads:[~2013-12-21 23:20 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m31u15ssed.fsf@neo.luffy.cx \
    --to=bernat@luffy.cx \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).