rschupp / PAR-Packer

(perl) Generate stand-alone executables, perl scripts and PAR files https://metacpan.org/pod/PAR::Packer
Other
48 stars 13 forks source link

The executable binary file doesn't work for website #40

Closed cweiming closed 3 years ago

cweiming commented 3 years ago

I have built a website on nginx and ran a execute the binary file made by par::packer (perl script). However, it didn't work.

The binary file can work as well on terminal but not web service.

No a log file generated make me hard to solve the problem.

Any suggestion is appreciated

Thanks!

rschupp commented 3 years ago

What OS did you try this on?

cweiming commented 3 years ago

Hi Rschupp

I ran Larave 5.8 (Nginx, PHP 7.4) on ubuntu 20.04 and let a controller to exec the binary, e.g., shell_exec("binaryApp"). I have tried many ways, but it turned out that the controller wasn't able to recognize the binary and displayed "null".

rschupp commented 3 years ago

I ran Larave 5.8 (Nginx, PHP 7.4) on ubuntu 20.04 and let a controller to exec the binary, e.g., shell_exec("binaryApp"). I have tried many ways, but it turned out that the controller wasn't able to recognize the binary and displayed "null".

I don't understand any of this except that you're running on Linux. An executable generated by pp is nothing special so I don't know what you mean with "controller wasn't able to recognize the binary".

Try running strace -f ... on the process that's supposed to do the shell_exec("binaryApp") to see what's happening.

cweiming commented 3 years ago

I am sorry for explaining the issue unclear.

The controller in Laravel is a script that controls any of whatever you want, e.g., runing an executable generated by pp. The controller can find the executable but can't execute it. However, running .pl (or other executable not made by pp) works as well.

I have googled a lot but nothing found.

Still thanks for your comments.

rschupp commented 3 years ago

I have googled a lot but nothing found.

Googling won't help. strace the process, this will show you the system calls surrounding the execution of the shell_exec function (just search the output of strace for the path or name of the "binaryApp"). Either it gets to execve("binaryApp", ...), then you can follow that process and maybe see why it fails, or it does not execute it, but then you should see some probing that might explain why.

cweiming commented 3 years ago

Hi rschupp,

I solved it with shell_exec("perl -MPAR=/path/to/binaryApp /path/to/binaryApp").

Thanks for your help.

rschupp commented 3 years ago

I solved it with shell_exec("perl -MPAR=/path/to/binaryApp /path/to/binaryApp").

Very strange - that implies that /path/to/binaryApp is a Perl script, not an executable. What is the actual pp command you used to generate binaryApp?

cweiming commented 3 years ago

For example,

pp -o /path/to/binaryApp /path/to/binaryApp.pl

Run the command shell_exec("perl -MPAR=/path/to/binaryApp binaryApp") on PHP website

It works as well.

rschupp commented 3 years ago

So I did some experiments.

php's shell_exec works fine with a pp generated executable:

$ cat foo.php
<?php
  $out = shell_exec("./hello");
  echo "got <$out>\n";
?>
$ pp -o hello -E 'say "hello!";'
$ php7.4 foo.php 
got <hello!
>

That makes me suspect the web server: maybe it runs php in some sandboxed environment that obstructs how pped executables work. E.g. create a user namespace and mount a tmpfs with -o noexec on /tmp in there. In such a scenario /path/to/binaryApp would fail with nothing on stdout and stderr (because it writes, then executes a custom perl executable to /tmp), but your workaround would succeed (it doesn't use this executable, only the zip that's part of the executable).

cweiming commented 3 years ago

Same as you found.

Web server seems to obstruct how pped executables work. However, I have no idea how to set up the environment of web server to let executable runs as normal.

/path/to/binaryApp as I mentioned above works fine, but it's not easy to debug when fail with nothing on stdout and stderr.

I will take time to look the environment setting of web server.

rschupp commented 3 years ago

You can set the environment variable PAR_GLOBAL_TEMP (see https://metacpan.org/pod/PAR#NOTES) to specify where "packed" executables extract stuff to (esp. the custom perl interpreter). It should be a directory on a filesystem (as seen from the sandbox) that is mounted with -o exec.

cweiming commented 3 years ago

Would you mind if you could give me an example to set PAR_GLOBAL_TEMP?

rschupp commented 3 years ago

Would you mind if you could give me an example to set PAR_GLOBAL_TEMP?

Sorry, I don't know how your web server's sandbox looks like. It must be set to a directory that is (as seen from within the sandbox):

cweiming commented 3 years ago

I didn't use any container like the docker of the web server, so I am not sure how to set it as you suggested. I was trying to change the /tmp to other places in PHP.ini but got failed (shell_exec("/path/to/executable")) with nothing on stdout and stderr.

Anyway, shell_exec("perl -MPAR=/path/to/executable /path/to/executable") still work fine.

cweiming commented 3 years ago

I didn't use any container like the docker of web server, so I am not sure how to set it of what you suggested. I was trying to change the /tmp to other place in PHP but got failed with nothing on stdout and stderr.

rschupp commented 3 years ago

If you are still interested to investigate, you cant try with current master (just adds some debug output):