Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
335 views
in Technique[技术] by (71.8m points)

python - 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-----
MIIFmTCCBIGgAwIBAgITQwAAAGqQd2QfUVAHwQABAAAAajANBgkqhkiG9w0BAQsF
ADBGMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFjAUBgoJkiaJk/IsZAEZFgZhdmFt
YXIxFTATBgNVBAMTDGF2YW1hci1EQy1DQTAeFw0yMDEyMjkxMjAyNDhaFw0yMjEy
MjkxMjAyNDhaMHYxCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcT
BlN5ZG5leTERMA8GA1UEChMIRGVsbCBFTUMxEDAOBgNVBAsTB1N1cHBvcnQxIzAh
BgNVBAMTGm5lbzEtc3lWwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBjH2ubfVxCC42LVURTZUog/vJZ
ctAEBDUW3VaeRCMWD3dvB0loc0llGaXQVafh0Q2cW8Uy0qMexPcUUwp8OjbtwcBo
3TkEApBABgX/JC9P+BXCK3NiYze1SAjsgcdeZaS0t3HLlgwc8vZSotXco+mwZM9S
TtrU1RqU4kkqhR5+wjPT8ffLFyZNBCdDKUOF3wxsr/0uUpfm9Bnt3DahoN4dwHvI
Ovi1DSV6ob84VXKT3ehMqt27ZW5dtLQdpzINADHDHlitTAUAO+CdO3LltqobQbf8
iK8fmnmSWHVF8vA3mmIfANLILZ6XKASgo2D2RU0jPjbkWi3nPY+2aRPGS1wJ
-----END CERTIFICATE-----
', '')

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)
/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
')

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...