|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-05-14 15:09 UTC] dbarrett at vistaprint dot com
Description: ------------ This is an intermittent but fatal problem. I cannot reproduce it on demand, but it occurs regularly on our MediaWiki 1.12.0 site running on Apache 2.2.8. When invoking a non-interactive Microsoft Windows command via exec() or shell_exec(), sometimes the resulting process will hang. Once this occurs, most or all subsequent exec() calls (within the same Apache instance) will hang as well. Eventually the wiki becomes unusable. The only way to kill these processes is to restart Apache. Other traditional "kill" techniques fail. This is not the same as Bug #30794, which was about interactive commands like Notepad. I'm speaking of diverse shell commands like perl.exe, gnuplot.exe, latex.exe, and others. All of them process text input, if that matters. If the process is "foo" and you run exec("foo"), you wind up with several hung processes: foo.exe cmd.exe*32 This may be a race condition. I ran the "handle" utility (from sysinternals) on the hung processes. It seemed to indicate that the processes were waiting on c:\Apache2\logs\error.log. Then handle itself (handle64.exe) hung! Because this is an intermittent problem, I am looking for advice on how to debug it and report more detailed information to you. Please don't append the generic "install the latest snapshot and let us know if the problem is still there" message to this ticket, because I can't install an experimental PHP release on a production server, and the problem happens ONLY on our production server (probably because of the load), not on any of our development or test servers. Expected result: ---------------- exec() and shell_exec() should never hang. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Nov 06 23:00:02 2025 UTC |
I am also experiencing this problem. I have been able to recreate it with system() as well as proc_open(). With proc_open() it doesn't seem to matter if I set bypass_shell or not, just determines whether I have a dangling cmd.exe process or not... cmd.exe seems to stop at Wait:UserReq, but that probably doesn't mean much. I am able to reproduce it with XAMPP 1.6.6a (PHP 5.2.5) on Windows XP or Windows Server 2003 (32-bit). I don't have much to add in terms of documentation as I don't get anything in the httpd logs, but using the following code snippet: protected function runSAS($filename) { $this->log("Requested to run SAS file: " . $filename, LOG_DEBUG); $toRun = "\"" . SAS . "\""; $toRun .= " -sysin '" . $filename . "'"; $toRun .= " -CONFIG '" . SASV9CFG . "'"; $toRun .= " -PRINT '" . TEMP_DIR . "/" . basename($filename) . ".lst'"; $toRun .= " -LOG '" . TEMP_DIR . "/" . basename($filename) . ".log'"; $toRun .= " -NOSPLASH"; $this->log("SAS command to run: " . $toRun, LOG_DEBUG); $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a file to write to ); $res = proc_open($toRun, $descriptorspec, $pipes, null, null, array(/*"bypass_shell" => true*/)); if (is_resource($res)) { //fwrite($pipes[0], "exit\n"); //fflush($pipes[0]); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); $return_value = proc_close($res); $this->log("Return value from SAS: " . $return_value, LOG_DEBUG); } } When it does seem to complete, I'll get this in my log: 2008-06-26 20:23:55 Debug: Return value from SAS: 1 Nothing should come out on the pipes at all and when I set it up to read those and it completes, there is no data read. However, in a hang case, PHP blocks reading STDOUT instead of on proc_close never getting any data... even if I set the stream to be non-blocking on the pipe explicitely after proc_open.If that's any help, I'm using a COM object as a workaround for this bug, and while it makes this bug appear less frequently, it still happens, randomly, from time to time. Here's what i did as a workaround using the exec() function call: $WshShell = new COM("WScript.Shell"); $OutputFile = "C:\\Temp\\output.txt"; $Command = "cmd /C MyApp.exe > $OutputFile"; $WshShell->Run( $Command, 0, true ); file_get_contents( $OutputFile ) ); unlink( $OutputFile );I've seen this happen in other languages too. This happens when the pipe between the parent and child fills up, and cmd.exe ends up blocking and creates a race condition. (Windows script host languages trip up on this quickly) in popen_ex() ( in tsrm_win32.c) the pipe is creates with a 2k buffer: if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) { this should probably be significantly larger. I'd certainly go with at least 16k or 32k. (hey, it's only memory :D) as well, the elimination of the unrequired cmd.exe as the immediate child process would eliminate the possibility that *it's* buffer gets overwhelmed too. (which solves bug #43327, and I've passed a patch to Pierre for that.)