php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #854 include() problem
Submitted: 1998-10-16 15:08 UTC Modified: 1998-10-17 07:09 UTC
From: matt at debris dot com Assigned:
Status: Closed Package: Reproducible Crash
PHP Version: 3.0.5 OS: BSDI 3.0
Private report: No CVE-ID: None
 [1998-10-16 15:08 UTC] matt at debris dot com
When an included module is called multiple times, its
variable space can become corrupt. Perhaps include()
was never intended to be used in this fashion, but it
crashes in any case.

Here's a fresh backtrace:
Program terminated with signal 11, Segmentation fault.
#0  pval_destructor (pvalue=0x0) at variables.c:76
76              if (pvalue->type == IS_STRING) {
(gdb) bt
#0  pval_destructor (pvalue=0x0) at variables.c:76
#1  0x2480e in tc_destroy (tc=0xd2a604) at token_cache.c:314
#2  0x2484e in tcm_destroy (tcm=0xa870c) at token_cache.c:328
#3  0x1dc66 in php3_request_shutdown (dummy=0x0) at main.c:728
#4  0x1fc35 in main (argc=3, argv=0xefbfdac0) at main.c:1790

Here's a script that crashes PHP:
#!/usr/local/bin/php3 -q
<?
    for ($i = 0; $i < 1550; $i++) {
        include ("crasher.html");
    }
?>

crasher.html:
<?
$text = "***************************************************************"; 
$text .= "***************************************************************\n";
$text .= "***************************************************************\n";
$text .= "***************************************************************\n";
 ## etc... put in about a dozen or 20 of these lines...
 ## just build a long string, one way or another.
?>

When I move the contents of crasher.html into the
loop, replacing the include() call, the script works
fine. Something is different about the way PHP treats
the variable space of included code.

Adding unset($text) to the end of the included module does not help.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [1998-10-17 07:09 UTC] zeev
Ok, at last, I'm at your help :)

I've reproduced the problem on your box.  I also fixed it.
Basically, at a certain point, the script runs out of memory,
or actually, it can't find a sufficiently big memory block.

Since PHP doesn't handle out of memory errors (we never got
around to it) - the script crashed.

Using include() within a loop is *VERY* bad practice, since
it 'leaks' memory.  That is, memory is allocated separately
for each include file, and is NEVER freed until the end of
the script execution.  In your case, you should really consider
one of the following alternatives:

1.  Define a function that does what the include file does,
and call that function instead of repeatedly including
the include file.

2.  Use require() instead.  require() only parses the include
file once, and allcoates memory for it once.

As far as proper coding is concerned, (1) is much much better.

I'll make sure we handle out of memory errors nicely in
3.0.6, but that won't solve your problem - since all I'm
planning to do is exit(), instead of the current situation
which may crash under some circumstances.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 09:01:27 2024 UTC