Pārlūkot izejas kodu

HPCC-10333 Embedded Python may encounter undefined symbols

Due to bugs in the way that Python is build for some distros, it is necessary
to ensure that the libpython library is loaded with RTLD_GLOBAL set.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 gadi atpakaļ
vecāks
revīzija
5c8d69a280
1 mainītis faili ar 31 papildinājumiem un 0 dzēšanām
  1. 31 0
      plugins/pyembed/pyembed.cpp

+ 31 - 0
plugins/pyembed/pyembed.cpp

@@ -236,6 +236,7 @@ static class Python27GlobalState
 public:
     Python27GlobalState()
     {
+        pythonLibrary = (HINSTANCE) 0;
 #ifndef _WIN32
         // If Py_Initialize is called when stdin is set to a directory, it calls exit()
         // We don't want that to happen - just disable Python support in such situations
@@ -246,6 +247,33 @@ public:
             return;
         }
 #endif
+#ifndef _WIN32
+        // We need to ensure all symbols in the python2.6 so are loaded - due to bugs in some distro's python installations
+        FILE *diskfp = fopen("/proc/self/maps", "r");
+        if (diskfp)
+        {
+            char ln[_MAX_PATH];
+            while (fgets(ln, sizeof(ln), diskfp))
+            {
+                if (strstr(ln, "libpython2"))
+                {
+                    const char *fullName = strchr(ln, '/');
+                    if (fullName)
+                    {
+                        char * lf = (char *) strchr(fullName, '\n');
+                        if (lf)
+                        {
+                            *lf = 0;
+                            pythonLibrary = dlopen((char *)fullName, RTLD_NOW|RTLD_GLOBAL);
+//                            DBGLOG("dlopen %s returns %"I64F"x", fullName, (__uint64) pythonLibrary);
+                            break;
+                        }
+                    }
+                }
+            }
+            fclose(diskfp);
+        }
+#endif
         // Initialize the Python Interpreter
         Py_Initialize();
         PyEval_InitThreads();
@@ -263,6 +291,8 @@ public:
             // Finish the Python Interpreter
             Py_Finalize();
         }
+        if (pythonLibrary)
+            FreeSharedObject(pythonLibrary);
     }
     bool isInitialized()
     {
@@ -271,6 +301,7 @@ public:
 protected:
     PyThreadState *tstate;
     bool initialized;
+    HINSTANCE pythonLibrary;
 } globalState;
 
 // Each call to a Python function will use a new Python27EmbedFunctionContext object