Bug #18833 [Com]: exec() : After throusands calls, causes "Unable to fork" error

From: Date: Mon, 22 Nov 2021 22:57:27 +0000
Subject: Bug #18833 [Com]: exec() : After throusands calls, causes "Unable to fork" error
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-237927@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=18833&edit=1

 ID:                 18833
 Comment by:         ciprian dot dimofte dot 1982 at gmail dot com
 Reported by:        antoine dot bajolet at tdf dot fr
 Summary:            exec() : After throusands calls, causes "Unable to
                     fork" error
 Status:             No Feedback
 Type:               Bug
 Package:            *General Issues
 Operating System:   GNU/Linux 2.4.9 RH 7.1
 PHP Version:        4.2.1
 Block user comment: N
 Private report:     N

 New Comment:

This saved my life. And it's sooo elegant ! :)

function user_proc_exec ($command,& $result,& $status)
	{
	$process = proc_open(
			$command,
			array(
			0 => array("pipe", "r"), //STDIN
			1 => array("pipe", "w"), //STDOUT
			2 => array("pipe","w")), //STDERR
			$pipes
			);
	$result = stream_get_contents($pipes[1]);
	$error = stream_get_contents($pipes[2]);
	fclose($pipes[1]);
	fclose($pipes[2]);
	$status= proc_close($process);
	$result = explode("\n",trim($result));
    return($error);
	}


Previous Comments:
------------------------------------------------------------------------
[2010-02-19 00:26:07] simeonl at dbc dot co dot nz

OK, sorry, further testing revealed that klaus' fix hadn't worked for me after all, and
the problem *doesn't* seem to be in exec.  I can't be certain that we even have the same
problem.

I was able to track it down though by using a function like this:

// Before using this method, you need to run "apt-get install lsof" on your server.
public static function countOpenFiles()
{
  return count(explode("\n", trim(shell_exec("lsof -p '" . posix_getpid() .
"'" ))));
}

Logging the output at key points helped me track down the handle "leak", which turned out
to be PDO (using persistent connections fixed it).

------------------------------------------------------------------------
[2010-02-18 02:09:12] simeonl at dbc dot co dot nz

I got the same problem with a CLI script running repeated exec commands.  

PHP 5.2.11-0.dotdeb.1 with Suhosin-Patch 0.9.7 (cli) (built: Sep 19 2009 23:21:37)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
    with Suhosin v0.9.29, Copyright (c) 2007, by SektionEins GmbH

(Debian - Lenny)

Adopting the suggested "user_proc_exec" workaround has fixed the problem, which does
suggest the exec might not be closing it's pipes properly.

------------------------------------------------------------------------
[2009-12-19 12:39:56] klaus dot wendel at lednew dot de

I've forgotten: Please aslo add a

$result = explode("\n",trim($result));

function user_proc_exec ($command,& $result,& $status)
	{
	$process = proc_open(
			$command,
			array(
			0 => array("pipe", "r"), //STDIN
			1 => array("pipe", "w"), //STDOUT
			2 => array("pipe","w")), //STDERR
			$pipes
			);
	$result = stream_get_contents($pipes[1]);
	$error = stream_get_contents($pipes[2]);
	fclose($pipes[1]);
	fclose($pipes[2]);
	$status= proc_close($process);
	$result = explode("\n",trim($result));
    return($error);
	}

------------------------------------------------------------------------
[2009-12-19 12:26:49] klaus dot wendel at lednew dot de

[Ubuntu karmic 9.10; php-cli 5.2.10]

> The per-user process number limit is set in 
> /etc/security/limits.conf.
> In my case, it was enough to raise it and reboot.

In my case, this wasn't the answer, unfortunately. Or fortunately, because I was forced to find
a workaround, which could help others, too.

In my code I replaced exec by following function:

function user_proc_exec ($command,& $result,& $status)
	{
	$process = proc_open(
			$command,
			array(
			0 => array("pipe", "r"), //STDIN
			1 => array("pipe", "w"), //STDOUT
			2 => array("pipe","w")), //STDERR
			$pipes
			);
	$result = stream_get_contents($pipes[1]);
	$error = stream_get_contents($pipes[2]);
	fclose($pipes[1]);
	fclose($pipes[2]);
	$status= proc_close($process);
    return($error);
    }

Everything is working fine now.

------------------------------------------------------------------------
[2009-05-04 14:42:05] scherbakov_koksa at mail dot ru

It seems I've finally figured out the reason (after a huge amount of googling UNIX forums).

The PHP fork() error is accompanied by the following entries in Apache error_log:

[Mon May 04 20:55:59 2009] [alert] (11)Resource temporarily unavailable: setuid: unable to change to
uid: 48
[Mon May 04 20:55:59 2009] [alert] Child 10053 returned a Fatal error... Apache is exiting!

The system configuration doesn't allow Apache to execute more than N child processes
simultaneously. Apache runs out of this limit and can't start any more processes. Hence is the
error.

The per-user process number limit is set in /etc/security/limits.conf. In my case, it was enough to
raise it and reboot.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=18833


--
Edit this bug report at https://bugs.php.net/bug.php?id=18833&edit=1


Thread (14 messages)

« previous php.bugs (#237927) next »