Crash using callback

Victor Stinner <[email protected]> Thu, 5 Oct 2006 16:03:02 +0200
Newsgroups gmane.comp.python.ctypes.devel
Organization INL
Message-ID <[email protected]>
Hi,

I wrote a Python binding for libnetfilter_conntrack using ctypes. Ctypes 
library is really great! It's so easy to write the binding and then to use 
it!

But during tests, I was victim of a crash. After long analys, I understood 
that the problem comes from callback. Here is a little example of the crash:
--- C code ---

typedef int (*callback_t) (int *arg);
callback_t global_callback = NULL;
void set_callback(callback_t callback)
{
  global_callback = callback;
}

void read_table()
{
    int i;
    static int arg = 10;
    if (!global_callback) return;
    for (i=0; i<10; i++)
    {
        if (global_callback(&arg) != 0) return;
    }
}

--- Python code ---
lib = cdll.LoadLibrary("libbug_callback.so")

def mine(number_ptr):
    return 0

callback_t = CFUNCTYPE(c_int, POINTER(c_int))
for subloop in xrange(10000):
    lib.set_callback( callback_t(mine) ) # <~~~ here it is
    lib.read_table()
---

Full example is attached to this email (crash_ctypes.tar.bz2).

Or another version of Python code to better understand the bug:
===
# using same function and callback type
for subloop in xrange(10000):
    mycallback = callback_t(mine)
    lib.set_callback(mycallback)
    del mycallback # <~~~ without this, it doesn't crash
    lib.read_table()
===

On my mind, the problem is about object destruction and referrence counting. 
It's not really a problem of ctypes, more a problem of object lifetime.

« lib.set_callback( callback_t(mine) ) » create a temporary object of type 
callback_t which is used during the call of lib.set_callback. But after this 
call, the object is destroyed. The problem is that the C library stores a 
pointer to this (destroyed) object. And so it will quickly crash...

Question: would it be possible to change object lifetime, tell that the 
function keep a referrence of the object, or something like that? Or should I 
keep a copy of "mycallback = callback_t(mine)" somewhere?

Bye,
Victor Stinner
http://www.inl.fr/

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
Ctypes-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-devel
crash_ctypes.tar.bz2 (application/x-tbz, 728 B) - not displayed