From: Stefan B. <be...@ax...> - 2007-02-02 11:48:45
|
Hi! We have trouble with the C wrapper code in SWIG_InitializeModule that is generated for interfacing with Python with SWIG version 1.3.31. It worked fine in 1.3.29. Our case is a bit special as we do not keep the _name.so files separate, but link them directly into the binary (or in our case a plugin library) where we call the appropriate SWIG_init function after the Python interpreter was started with Py_Initialize. The interpreter is started for several tasks in a sequence. This setup works fine with the SWIG_InitializeModule code that SWIG 1.3.29 generates: SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head; static int init_run = 0; clientdata = clientdata; if (init_run) return; init_run = 1; /* Initialize the swig_module */ swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; /* Try and load any already created modules */ module_head = SWIG_GetModule(clientdata); if (module_head) { swig_module.next = module_head->next; module_head->next = &swig_module; } else { /* This is the first module loaded */ swig_module.next = &swig_module; SWIG_SetModule(clientdata, &swig_module); } ... The early exit via the static variable init_run is essential here! The later SWIG 1.3.31 generates the following code: SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; int found; clientdata = clientdata; /* check to see if the circular list has been setup, if not, set it up */ if (swig_module.next==0) { /* Initialize the swig_module */ swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; } /* Try and load any already created modules */ module_head = SWIG_GetModule(clientdata); if (!module_head) { /* This is the first module loaded for this interpreter */ /* so set the swig module into the interpreter */ SWIG_SetModule(clientdata, &swig_module); module_head = &swig_module; } else { /* the interpreter has loaded a SWIG module, but has it loaded this one? */ found=0; iter=module_head; do { if (iter==&swig_module) { found=1; break; } iter=iter->next; } while (iter!= module_head); /* if the is found in the list, then all is done and we may leave */ if (found) return; /* otherwise we must add out module into the list */ swig_module.next = module_head->next; module_head->next = &swig_module; } ... Now, with this code, we have trouble as there is no early exit anymore. The circular list is empty for each interpreter run, but the static data of the wrapper module is already initialized for the second run and so on. This leads to severe memory problems and at an arbitrary time after the first run, we get memory problems and crashes. If I add an early exit like this: if (swig_module.next==0) { /* Initialize the swig_module */ swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; } else { /* We already initialized the module, so exit now. */ return; } Then again it works. Is there any reason why this change was made between 1.3.29 and 1.3.31? Greetings, Stefan -- Dipl.-Inf. Stefan Bellon Axivion GmbH Nobelstr. 15 70569 Stuttgart Tel: +49 711 6204378-6 Fax: +49 711 6204378-9 |