Error message from php executing c script - php

I spent hours trying to debug a php script which runs a c simulation using exec(). After throwing stderr print messages in everywhere, I finally found that the underlying issue was printing a directory path to a char array that was too small using sprintf().
I'm guessing it was a segmentation fault, but I never actually saw the shell error message saying 'segmentation fault'. When I changed the allocation size, everything worked.
I had been redirecting stderr output to a log file, and that log file got all of the messages from fprintf(stderr,"..."); but it didn't get any shell error messages.
The command is this
exec("$cmd 2>> $logFile & $PROCFILE 1 $ipaddr $! 2>> $logFile", $output, $rv);
$cmd runs a c simulation, and $PROCFILE runs a second c program that takes three arguments (the 1, $ipaddr, and $!). Before I fixed the allocation size problem, the php script would just stop execution of the $cmd simulation and continue on the next line (i.e. after the exec() statement). The next line in the php file is
if(rv!=0){handle error}
but that also didn't catch the problem.
I kept thinking I was running into a permissions error. How can one get exec() to show the shell errors? Or was this a result of running the two programs simultaneously with '&'?

When a program dies, the "Segmentation fault" message comes from the shell, not from the program. Redirection only applies to the program's output, not the shell's. The message should get put into the $output variable. If $rv is 0 and there's nothing in $output, I suspect you're wrong about what happened. I suggest you verify this by writing a simple test program that just does:
kill(0, SIGSEGV);
BTW, why aren't you using snprintf(), so you can't get a buffer overflow in the first place?

Related

Write the PHP command line log to a file like in Python

In Python, we can add the command line log to a file instead of the console using this command:
python script.py >> mylogfile.txt
How can I do it using PHP? I've tried
php script.php >> mylogfile.txt
but it doesn't work.
I use Windows 10.
I finally found the answer. It's based on the article PHP on the Command Line – Part 1 Article
I first used php script.php > mylog.txt which returns some of the log text to the console, so I thought it's not writing to the log, but it does. I wanted php script.php > mylog.txt 2>&1 which will add any log to the file.
The article says it doesn't work in Windows, but I use Windows 10 and it works.
The error messages are mixed with the normal output as before. But by
piping the output from the script, I can split the errors from the
normal output:
php outwitherrors.php 2> errors.log
This time, you’ll only see these messages:
Opening file foobar.log Job finished
But, if you look into the directory in which you ran the script, a new file called errors.log will have been created, containing the error
message. The number 2 is the command line handle used to identify
standard error. Note that 1 is handle for standard output, while 0 is the handle for standard error. Using the > symbol from the command line, you can direct output to a particular location.
Although this may not seem very exciting, it’s a very handy tool for
system administration. A simple application, running some script from
cron, would be the following:
php outwitherrors.php >> transaction.log 2>> errors.log
Using ‘>>‘, I tell the terminal to append new messages to the existing
log (rather than overwrite it). The normal operational messages are
now logged to file transaction.log, which I might peruse once a month, just to check that everything’s OK. Meanwhile, any errors that need a quicker response end up in file errors.log, which some other cron job might email me on a daily basis (or more frequently) as required.
There’s one difference between the Unix and Windows command lines,
when it comes to piping output, of which you should be aware. On Unix,
you can merge the standard output and standard error streams to a single destination,
for example:
php outwitherrors.php > everything.log 2>&1
It reroutes standard error to standard output, meaning that both get
written to log file everything.log.

Running console program in PHP

I wrote a simple PHP code to execute a console program:
<?php
$cmd = escapeshellcmd('progName.exe arg1 arg2 arg3');
exec($cmd);
?>
If I run the command on the console directly on the server, it works. However, when I run the PHP on the browser, it doesn't work. The process progName.exe is running (checked using Task Manager on the server), but it never finishes. This program is supposed to compute some parameters from the arguments and write the result to a binary file, and also produce a .WAV file. Here is the error message I get on the browser:
Error Summary
HTTP Error 500.0 - Internal Server Error
C:\php\php-cgi.exe - The FastCGI process exceeded configured activity timeout
Detailed Error Information
Module FastCgiModule
Notification ExecuteRequestHandler
Handler PHP
Error Code 0x80070102
Then I wrote a simple console program that write a sentence to a text file (writeTxt.exe hello.txt). Using the same PHP script, I ran it on the browser and it works.
I already tried to increase the timeout on the server, but still have the same error.
What could cause this problem?
When you execute a program in PHP using the exec function (e.g. exec('dir')), PHP waits until it is ended or you sent it to the background and PHP comes back directly (see documentation, especially the comments).
According to your posted PHP sources ($cmd = escapeshellcmd('progName.exe arg1 arg2 arg3');) the program is not sent to background by PHP - so what stays is that progName.exe...
...sends itself or a fork to the background (unlikely, but look into the sources of progName.exe)
...is waiting for input (<-- this is my favorite)
I missed something ;-)
As I said I bet it is the second option. Hope that helped a bit.

Processing Gem Data

I have a question regarding running a shell command via PHP. My goal is to successfully run compass compile [project] via PHP. I have tried the following:
echo system('compass compile [project]', $s); // prints [31m[0m
echo $s; // prints 1
echo passthru('compass compile [project]', $p); // prints [31m[0m
echo $p; // prints 1
echo shell_exec('compass compile [project]'); // prints [31m[0m
echo exec('compass compile [project]', $e, $ee);
print_r($e); // Array ( [0] => [31m[0m )
echo $ee; // prints 1
I even tried running a shell command to an executable file that contained compass compile test and I still got the same results as the trials above.
My questions
What does [31m[0m mean? Does this represent binary data? Do these represent bash colors as search engines suggest?
As far as I know, the output should be the following:
For kicks, I tried to execute via system(/usr/local/bin/compass compile [project]); and I got the same result. I double checked my path so I know I can execute these commands as expected. Here is the output from echo $PATH:
/usr/lib/lightdm/lightdm:
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:/bin:
/usr/games:
/usr/local/games:
/var/lib/gems/1.9.1/bin
Is there a way to compile compass projects using PHP?
I've seen a similar error before.
Typically it is due to the things being output in the bash startup scripts. For example, I had an echo in one of my bash startups that jacked up a lot of scripts till I realized what was causing the problem.
Or, perhaps the user (www-data ?) doesn't actually have a home dir and appropriate startup scripts in place?
You can try this to get a non interactive shell:
exec("/bin/bash -c \"compass compile [project]\"", $e, $ee);
print_r($e);
echo $ee;
If you still have issues, try redirecting the output to a tmp file, an checking it:
exec("/bin/bash -c \"compass compile [project] > /tmp/compass.compile.output\"", $e, $ee);
print_r($e);
echo $ee;
See also: What's the difference between .bashrc, .bash_profile, and .environment?
The issue was fixed by using sass --compass and redirecting the stderr to stdout via echo shell_exec("sass --compass [project] 2>&1");
It was a pretty long and arduous process figuring this out since it's been awhile since I've dabbled in command line programs. Remember that error streams and output streams might be on different outputs. The easiest way to test this is to shovel the output into a file via:
# do this once with a good file and once with a file that will give errors
sass --poll style.scss > output.txt
If output.txt is empty then the error output is on the stderr stream such as the case above. We can correct this by redirecting the stderr to the srdout. For example:
sass --poll > output.txt 2>&1
#shows results
cat output.txt
I created a simple PHP script that redirects the output from one textarea to the other. The code can be found here.
First guess would be a permissions issue. Odds are the user account running PHP (unless you're running this from the command line, I'm guessing that this is the user that the httpd apache daemon is running under) doesn't have the permissions to do what you're asking. The errors are extremely unhelpful, however.
From what I can tell, it looks like an attempt to have the error show up in red on the command line. My guess is that there are hidden (or somehow never printed out) characters in-between the codes. Check out some of your apache and/or PHP error logs to see if anything helpful is showing up there that never made it into the PHP variable. Or, for kicks, try copy and pasting the output with the bash colors into a basic text editor and first delete each character from the beginning one by one... see if anything magically appears. If that doesn't work, try the same in reverse, backspacing from the end. Either way, there's an error occurring, so important that it must show in bold red letters to you, it's just not getting to you.
If it does in fact turn out to be a permissions issue, and it's one you can't remedy through permissions wrangling, you could create an intermediary file that your Apache user has permissions to write to, and your cron user has permissions to read from. Instead of running the code directly from PHP, put it in the file, then run a cron on a frequent basis looking for anything in that file, CHECKING IT FOR VALIDITY, and then running it through the compiler and removing it from the file.
It'd be ugly, but sometimes pretty things don't work.
You guessed it right it is colors but the way it is defined is not right. For more information regarding using colors in console please refer to this document. Also, for compiling SCSS via compass you can use shell_exec command in linux. For more information regarding shell_exec please refer to this document. Let us know how it goes.

PHP on Windows using system function - Why errors not in the correct place

I am using the PHP system function on windows as follows:
system("mysql --user=root --password=xxxx --host=127.0.0.1 --verbose <create.sql > out.txt 2>&1", $retVal);
But the error messages apppear at the top of the file. Is it possible to get the error messages to appear after the appropriate line of SQL that has the error.
The problem is that stdout is buffered and stderr is not meaning that the errors will always show first in this case. You are going to need to wrap your system call in a script and sort it afterwards if you wish to retain some sort of order. There is some explanation available over here.

PHP not executing python script correctly

I'm executing a python script from a php page like so: exec("python ./test.py");
This script runs fine if I don't open a serial port in it. If I do, however, (and this is the whole point of calling the python script in the first place), the script doesn't execute properly.
If I call a simple python script that prints a statement -
print "This works!"
Then I get the desired output in my php page.
But, if I open a serial port, I no longer get the output of "This works!", and the serial data is not getting sent to the receiving device -
import serial
ser = serial.Serial("/dev/ttyACM0",9600)
print "This works!"
Both scripts run fine from the command line.
Is this a php limitation? I have tried other methods of execution such as popen and system, but they didn't work for me either.
Perhaps you aren't getting complete error reporting from your Python execution. Try adding raise Exception('Boo!') as the first line of you Python program to find out if you are or not. If you don't get the exception and a traceback, then your program is probably failing on the serial.Serial line, but you aren't hearing about it.

Categories