#1253 python builtin and inheritance

open
nobody
python (259)
5
2012-12-21
2012-06-26
No

Hello all,

I think I have found a problem with swig 2.0.7 (using Python 2.7 on ubuntu 12.04 x86_64).
I manage to have a very short example that show what is going wrong.

The problem occurs while I was playing with directors and the -builtin swig option (that comes with an interesting performance increase, thank you so much for that :)). In the first place I thought I was doing something wrong with directors but the problem seems not be related to them.

I have a simple C++ class that I want to subclass and overload some methods (directors activated or not):

#sample.h--------------------------------------------------
#ifndef SAMPLE_H
#define SAMPLE_H

class Sample
{
public:
Sample();
virtual ~Sample();
virtual int echo(int);
};

#endif

#sample.cpp--------------------------------------------------
#include "sample.h"

Sample::Sample() {}
Sample::~Sample() {}
int Sample::echo(int number) {return number;}

#sample.i--------------------------------------------------
//%module (directors="1") sample
%module sample
%{
#define SWIG_FILE_WITH_INIT
#include "sample.h"
%}

//%feature("director") Sample;

class Sample
{
public:
Sample();
virtual ~Sample();
virtual int echo(int);
};

#Makefile--------------------------------------------------
all: wrapper
g++ -O2 -fPIC -c sample.cpp
g++ -O2 -fPIC -c sample_wrap.cxx -I/usr/include/python2.7
g++ -shared sample.o sample_wrap.o -o _sample.so

wrapper:
swig -c++ -python -builtin sample.i

#test.py--------------------------------------------------
#!/usr/bin/env python

from sample import Sample

class MySample(Sample):
def echo(self, i):
return 2 * i

while 1:
s = MySample()
del s

When executing this, here is the error message I get:

*** glibc detected *** python: double free or corruption (out)

Using valgrind I detect that the problem come from:

==606== Invalid free() / delete / delete[] / realloc()
==606== at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==606== by 0x7438B71: _wrap_delete_Sample_closure (sample_wrap.cxx:3793)
==606== by 0x444D77: ??? (in /usr/bin/python2.7)
==606== by 0x526A22: PyDict_DelItem (in /usr/bin/python2.7)
==606== by 0x42D65A: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==606== by 0x4317F1: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==606== by 0x54B170: PyRun_FileExFlags (in /usr/bin/python2.7)
==606== by 0x54B7D7: PyRun_SimpleFileExFlags (in /usr/bin/python2.7)
==606== by 0x54C5D5: Py_Main (in /usr/bin/python2.7)
==606== by 0x5FAC76C: (below main) (libc-start.c:226)
==606== Address 0x67e3010 is 82,608 bytes inside a block of size 262,144 alloc'd
==606== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==606== by 0x531FF7: PyObject_Malloc (in /usr/bin/python2.7)
==606== by 0x4FF3DC: _PyObject_GC_Malloc (in /usr/bin/python2.7)
==606== by 0x556308: PyType_GenericAlloc (in /usr/bin/python2.7)
==606== by 0x557D1A: ??? (in /usr/bin/python2.7)
==606== by 0x4C71C7: ??? (in /usr/bin/python2.7)
==606== by 0x4C7C75: PyObject_Call (in /usr/bin/python2.7)
==606== by 0x42AA49: PyEval_EvalFrameEx (in /usr/bin/python2.7)
==606== by 0x4317F1: PyEval_EvalCodeEx (in /usr/bin/python2.7)
==606== by 0x54A077: PyImport_ExecCodeModuleEx (in /usr/bin/python2.7)
==606== by 0x50D090: ??? (in /usr/bin/python2.7)
==606== by 0x50DA8A: ??? (in /usr/bin/python2.7)

In the wrapper code, the line 3793 is using a macro:

SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_Sample)

If I remove the -builtin option then my test script runs OK (well it loops indefinetly but that's what I expect).

Do I missed something from builtin specificities or is this a swig bug ?

Thanks for your support

Discussion