Search code examples
pythonubuntusubprocesspyinstallersuse

Weird behavior of subprocess with Pyinstaller compiled on ubuntu and run on SuSe 12 SP4


I am noticing some weird behavior of subprocess compiled using pyinstaller on Ubuntu 16 which works fine on ubuntu 16 but fails on SuSe12 SP4. Was wondering if someone can shed some light and tell me what trivial info Am i missing?

Basically, I have a simple script :

import os, sys, subprocess
def get_all_outputs(cmd):
    proc = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            shell=True,
                            universal_newlines=True)
    std_out, std_err = proc.communicate()
    return proc.returncode, std_out, std_err
cmd = raw_input('CMD:')
print get_all_outputs(cmd)

This works fine as normal python file or pyinstaller file on Ubuntu 16...

root@ubuntu16:~/cert/dist# ./retcode
CMD:openssl x509 -in /root/cert_new/mycert.cer


(0, '-----BEGIN CERTIFICATE-----\nMIIFmTCCBIGgAwIBAgITQwAAAGqQd2QfUVAHwQABAAAAajANBgkqhkiG9w0BAQsF\nADBGMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFjAUBgoJkiaJk/IsZAEZFgZhdmFt\nYXIxFTATBgNVBAMTDGF2YW1hci1EQy1DQTAeFw0yMDEyMjkxMjAyNDhaFw0yMjEy\nMjkxMjAyNDhaMHYxCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcT\nBlN5ZG5leTERMA8GA1UEChMIRGVsbCBFTUMxEDAOBgNVBAsTB1N1cHBvcnQxIzAh\nBgNVBAMTGm5lbzEtc3lWwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBjH2ubfVxCC42LVURTZUog/vJZ\nctAEBDUW3VaeRCMWD3dvB0loc0llGaXQVafh0Q2cW8Uy0qMexPcUUwp8OjbtwcBo\n3TkEApBABgX/JC9P+BXCK3NiYze1SAjsgcdeZaS0t3HLlgwc8vZSotXco+mwZM9S\nTtrU1RqU4kkqhR5+wjPT8ffLFyZNBCdDKUOF3wxsr/0uUpfm9Bnt3DahoN4dwHvI\nOvi1DSV6ob84VXKT3ehMqt27ZW5dtLQdpzINADHDHlitTAUAO+CdO3LltqobQbf8\niK8fmnmSWHVF8vA3mmIfANLILZ6XKASgo2D2RU0jPjbkWi3nPY+2aRPGS1wJ\n-----END CERTIFICATE-----\n', '')

But when I scp the compiled file to SuSe12SP4, I never get the output and instead it keeps throwing error code 127 along with a funny message like below:

neo_suse12sp4:~/pp # ./retcode
CMD:/usr/local/ssl/bin/openssl x509 -in /root/pp/mycert.cer

(127, '', '/bin/sh: /tmp/_MEIOqKDWs/libreadline.so.6: no version information available (required by /bin/sh)\n/usr/local/ssl/bin/openssl: relocation error: /usr/local/ssl/bin/openssl: symbol i2d_DHxparams, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference\n')

I even tried using full path to openssl and the certificate and it simply never works.

neo_suse12sp4:~/pp # which openssl
/usr/local/ssl/bin/openssl

I would really appreciate if someone can please assist me here. I'll be really thankful to you. Google and existing articles on SO seems to be no match to this problem.


Solution

  • Alright, seems like I found my way out by my self. This looks like the openssl executable found on SuSe 12 SP4 system is incompatible with the libcrypto.so library that was collected from Ubuntu 16 build system (and is now overriding the system one in the frozen application and its subprocesses).

    We need to modify the LD_LIBRARY_PATH for our subprocess to make the system's libraries take precedence over the bundled ones.

    Million thanks to @Rok Mandeljc (rokm) on github for assisting me with this. Posting it here in case someone else bang their head will get around this problem easily.

    Solution:

    ###Add the following code to your existing code 
    env = dict(os.environ)  # make a copy of the environment
    lp_key = 'LD_LIBRARY_PATH'  # for GNU/Linux and *BSD.
    lp_orig = env.get(lp_key + '_ORIG')
    if lp_orig is not None:
        env[lp_key] = lp_orig  # restore the original, unmodified value
    else:
        # This happens when LD_LIBRARY_PATH was not set.
        # Remove the env var as a last resort:
        env.pop(lp_key, None)
    

    Next, add the env variable to subprocess Popen command

    def run_command(cmd): #returns the output of a program
        proc = subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True, universal_newlines=True, env=env)
        std_out, std_err = proc.communicate()
        return std_out
    

    More Info : https://pyinstaller.readthedocs.io/en/stable/runtime-information.html?ld-library-path-libpath-considerations#ld-library-path-libpath-considerations