Fixed random segfault happening when loading new PLC in runtime, when using Xenonai.
authorEdouard Tisserant
Fri, 27 Apr 2018 16:32:53 +0200
changeset 2000 9fa2f8ede5d6
parent 1999 36a624779f9f
child 2002 15cd0000350d
child 2013 d3722aa7f66b
Fixed random segfault happening when loading new PLC in runtime, when using Xenonai.
Beremiz_service.py
runtime/xenomai.py
targets/Xenomai/__init__.py
--- a/Beremiz_service.py	Thu Apr 19 15:17:05 2018 +0200
+++ b/Beremiz_service.py	Fri Apr 27 16:32:53 2018 +0200
@@ -1,3 +1,4 @@
+
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
@@ -37,6 +38,7 @@
 import Pyro.core as pyro
 
 from runtime import PLCObject, ServicePublisher, MainWorker
+from runtime.xenomai import TryPreloadXenomai
 import util.paths as paths
 
 
@@ -133,6 +135,8 @@
 
 if __name__ == '__main__':
     __builtin__.__dict__['_'] = lambda x: x
+    # TODO: add a cmdline parameter if Trying Preloading Xenomai makes problem
+    TryPreloadXenomai()
 
 
 def Bpath(*args):
@@ -675,3 +679,4 @@
 
 pyroserver.Quit()
 sys.exit(0)
+ys.exit(0)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/xenomai.py	Fri Apr 27 16:32:53 2018 +0200
@@ -0,0 +1,16 @@
+from ctypes import CDLL, RTLD_GLOBAL, pointer, c_int, POINTER, c_char, create_string_buffer
+def TryPreloadXenomai():
+    """
+    Xenomai 3 (at least for version <= 3.0.6) do not handle properly dlclose
+    of shared objects whose dlopen did trigger xenomai_init.
+    As a workaround, this pre-loads xenomai libraries that need to be 
+    initialized and call xenomai_init once for all.
+    
+    Xenomai auto init of libs MUST be disabled (see --auto-init-solib in xeno-config)
+    """
+    try:
+        for name in ["cobalt", "modechk", "copperplate", "alchemy"]:
+            globals()[name] = CDLL("lib"+name+".so", mode=RTLD_GLOBAL)
+        cobalt.xenomai_init(pointer(c_int(0)), pointer((POINTER(c_char)*2)(create_string_buffer("prog_name"), None)))  
+    except:
+        pass
--- a/targets/Xenomai/__init__.py	Thu Apr 19 15:17:05 2018 +0200
+++ b/targets/Xenomai/__init__.py	Fri Apr 27 16:32:53 2018 +0200
@@ -37,7 +37,7 @@
         if xeno_config:
             from util.ProcessLogger import ProcessLogger
             status, result, _err_result = ProcessLogger(self.CTRInstance.logger,
-                                                        xeno_config + " --skin=native --"+flagsname,
+                                                        xeno_config + " --skin=posix --skin=alchemy --no-auto-init --"+flagsname,
                                                         no_stdout=True).spin()
             if status:
                 self.CTRInstance.logger.write_error(_("Unable to get Xenomai's %s \n") % flagsname)