php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #20783 Segfault on 'maximum execution time'
Submitted: 2002-12-03 04:45 UTC Modified: 2002-12-09 15:24 UTC
From: msopacua@php.net Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 4.4CVS2002-12-03 OS: BSD/OS 4.2/FreeBSD-STABLE 4.7
Private report: No CVE-ID: None
 [2002-12-03 04:45 UTC] msopacua@php.net
This is RC1 - will test later with RC2, using CLI, but same error message is in the weblogs.

The script basically splits a 65Meg logfile into parts for each day. It uses a growing buffer, to make just 1 fwrite operation (essentially make sure that every line is in the right file). Max executiontime is set to 900 in the script. When it reaches that, it segfaults.
bt full, below:
(gdb) bt full
#0  0x48225b6d in kill () from /shlib/libc.so.2
No symbol table info available.
#1  0x814df13 in _emalloc (size=129, 
    __zend_filename=0x8193ef4 "/home/mdev/_src/php-4.3.0RC1/main/spprintf.c", __zend_lineno=143, 
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/mdev/_src/php-4.3.0RC1/Zend/zend_alloc.c:162
        p = (zend_mem_header *) 0x0
        real_size = 136
        cache_index = 17
#2  0x814e225 in _erealloc (ptr=0x0, size=129, allow_failure=0, 
    __zend_filename=0x8193ef4 "/home/mdev/_src/php-4.3.0RC1/main/spprintf.c", __zend_lineno=143, 
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/mdev/_src/php-4.3.0RC1/Zend/zend_alloc.c:271
        p = (zend_mem_header *) 0x81bad38
        orig = (zend_mem_header *) 0x8210a4f
        real_size = 135585392
        cache_index = 86
#3  0x812e3f2 in xbuf_resize (xbuf=0x804566c, add=0) at /home/mdev/_src/php-4.3.0RC1/main/spprintf.c:143
        buf = 0x80622e0 "?%ܳ\e\bh8\a"
        size = 128
        offset = 0
#4  0x812e478 in xbuf_init (xbuf=0x804566c, max_len=0) at /home/mdev/_src/php-4.3.0RC1/main/spprintf.c:160
No locals.
#5  0x812f4f0 in vspprintf (pbuf=0x80456cc, max_len=0, 
    format=0x81a86a6 "Maximum execution time of %d second%s exceeded", ap=0x8045750 "\204\003")
    at /home/mdev/_src/php-4.3.0RC1/main/spprintf.c:614
        xbuf = {buf = 0x0, size = 0, max_len = 0, 
  buf_end = 0x815d158 "U\211?\203?(\213U\b\017?B\b\203?\001t\035\203?\001\177\t\205?t`?H\001", 
  nextb = 0x56 <Address 0x56 out of bounds>}
        cc = 136354480
#6  0x812b6a1 in php_error_cb (type=1, error_filename=0x82078a4 "/chroot/webdocs/log/apct/php/split.php", 
    error_lineno=67, format=0x81a86a6 "Maximum execution time of %d second%s exceeded", 
    args=0x8045750 "\204\003") at /home/mdev/_src/php-4.3.0RC1/main/main.c:544
        buffer = 0x2 <Address 0x2 out of bounds>
        buffer_len = 1210886440
        display = 134502596
#7  0x815f963 in zend_error (type=1, format=0x81a86a6 "Maximum execution time of %d second%s exceeded")
    at /home/mdev/_src/php-4.3.0RC1/Zend/zend.c:711
        args = 0x8045750 "\204\003"
        params = (zval ***) 0x8209ca4
        retval = (zval *) 0x814e047
        z_error_type = (zval *) 0x8045780
        z_error_message = (zval *) 0x82085a4
        z_error_filename = (zval *) 0x804572c
        z_error_lineno = (zval *) 0x1
        z_context = (zval *) 0x0
        error_filename = 0x82078a4 "/chroot/webdocs/log/apct/php/split.php"
        error_lineno = 67
        orig_user_error_handler = (zval *) 0xffffffff
#8  0x8156bdb in zend_timeout (dummy=27) at /home/mdev/_src/php-4.3.0RC1/Zend/zend_execute_API.c:722
No locals.
#9  <signal handler called>
No symbol table info available.
#10 0x482b560f in memcpy () from /shlib/libc.so.2
No symbol table info available.
#11 0x482affce in realloc () from /shlib/libc.so.2
No symbol table info available.
#12 0x814e2ba in _erealloc (ptr=0x87b3024, size=32186413, allow_failure=0, 
    __zend_filename=0x81a8ae4 "/home/mdev/_src/php-4.3.0RC1/Zend/zend_operators.c", __zend_lineno=1040, 
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/mdev/_src/php-4.3.0RC1/Zend/zend_alloc.c:293
        p = (zend_mem_header *) 0x87b3000
        orig = (zend_mem_header *) 0x87b3000
        real_size = 32186416
        cache_index = 4023302
#13 0x815c026 in concat_function (result=0x82083a4, op1=0x82083a4, op2=0x8209864)
    at /home/mdev/_src/php-4.3.0RC1/Zend/zend_operators.c:1040
        res_len = 32186412
        op1_copy = {value = {lval = 136381232, dval = 1.6390645495445642e-269, str = {
      val = 0x8210330 "?\203 \b?\003!\b?\001!\b", len = 136401268}, ht = 0x8210330, obj = {ce = 0x8210330, 
      properties = 0x8215174}}, type = 208 '?', is_ref = 101 'e', refcount = 2052}
        op2_copy = {value = {lval = 134505192, dval = 1.8680208399949844e-312, str = {
      val = 0x80462e8 "?b\004\bd\230 \b\b", len = 88}, ht = 0x80462e8, obj = {ce = 0x80462e8, 
      properties = 0x58}}, type = 96 '`', is_ref = 0 '\000', refcount = 0}
        use_copy1 = 0
        use_copy2 = 0
#14 0x816e786 in execute (op_array=0x82077a4) at /home/mdev/_src/php-4.3.0RC1/Zend/zend_execute.c:1169
        var_ptr = (zval **) 0x8210330
        execute_data = {opline = 0x8215198, function_state = {function_symbol_table = 0x82109a4, 
    function = 0x82077a4, reserved = {0x10001, 0x0, 0x8207824, 0x80465d0}}, fbc = 0x0, ce = 0x0, object = {
    ptr = 0x0}, Ts = 0x8045948, original_in_execution = 0 '\000', op_array = 0x82077a4, 
  prev_execute_data = 0x0}
#15 0x815fecb in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/mdev/_src/php-4.3.0RC1/Zend/zend.c:840
        files = 0x804663c ""
        i = 1
        file_handle = (zend_file_handle *) 0x8047b74
        orig_op_array = (zend_op_array *) 0x0
        local_retval = (zval *) 0x0
#16 0x812d6f7 in php_execute_script (primary_file=0x8047b74) at /home/mdev/_src/php-4.3.0RC1/main/main.c:1560
        orig_bailout = {{jb_eip = 135750363, jb_ebx = 134512624, jb_esp = 134511300, jb_ebp = 134511504, 
    jb_esi = 1209737216, jb_edi = 134619872, jb_mask = 0, jb_pad = {0, 0, 0}}}
        orig_bailout_set = 1 '\001'
        prepend_file_p = (zend_file_handle *) 0x0
        append_file_p = (zend_file_handle *) 0x0
        prepend_file = {type = 6 '\006', filename = 0x8047ff0 "?{\004\b\003", opened_path = 0x0, handle = {
    fd = 0, fp = 0x0}, free_filename = 0 '\000'}
        append_file = {type = 1 '\001', filename = 0x0, 
  opened_path = 0x10007 <Address 0x10007 out of bounds>, handle = {fd = 3, fp = 0x3}, 
  free_filename = 144 '\220'}
        old_cwd = 0x8046648 ""
        old_primary_file_path = 0x8047fbb "./split.php"
        retval = 0
#17 0x8176aa0 in main (argc=3, argv=0x8047be4) at /home/mdev/_src/php-4.3.0RC1/sapi/cli/php_cli.c:711
        orig_bailout = {{jb_eip = 0, jb_ebx = 0, jb_esp = 0, jb_ebp = 0, jb_esi = 0, jb_edi = 0, jb_mask = 0, 
    jb_pad = {0, 0, 0}}}
        orig_bailout_set = 0 '\000'
        exit_status = 0
        c = 10
        file_handle = {type = 2 '\002', filename = 0x8047658 "/chroot/webdocs/log/apct/php/split.php", 
  opened_path = 0x0, handle = {fd = 1210928260, fp = 0x482d4c84}, free_filename = 0 '\000'}
        behavior = 1
        no_headers = 1
        orig_optind = 1
        orig_optarg = 0x0
        arg_free = 0x8047fbb "./split.php"
        arg_excp = (char **) 0x8047bec
        script_file = 0x8047fbb "./split.php"
        global_vars = {head = 0x0, tail = 0x0, size = 4, count = 0, dtor = 0, persistent = 0 '\000', 
  traverse_ptr = 0x481ad8c8}
        interactive = 0
        module_started = 1
        exec_direct = 0x0
        param_error = 0x0
#18 0x806276e in __start ()

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-12-03 09:47 UTC] msopacua@php.net
Researched this some more, same for RC2.
Reproducable script:
#!/home/mdev/_src/php-4.3.0RC2/sapi/cli/php -q
<?php
set_time_limit(2);
echo "Running php ", PHP_VERSION, "\n";
echo "Running script with memory limit:", ini_get('memory_limit'), "\n";
$i=0;
define('LONG_STRING', str_repeat('x', 4096) . "\n");
$buffer ='';
// yes this is intended.
while($i > -1)
{
        if(++$i % 10000 == 0)
                print "Still running: $i\n";
        if(isset($argv[1]) && $argv[1] == 'buffer')
                $buffer.=LONG_STRING;
}
?>

Output:
# ./test_while.php buffer
Running php 4.3.0RC2
Running script with memory limit:
FATAL:  emalloc():  Unable to allocate 129 bytes
Segmentation fault (core dumped)

Omit the argument 'buffer' and the script finishes cleanly, after outputting some lines and reaching max_execution_time.

The memory limit reference I put in, because:
php -i | grep ini | sed -e "s|.*=> \(.*\)$|\1|" | xargs grep '^memory_limit' && php -r 'echo "Limit is: ", ini_get("memory_limit"), "\n";'

Outputs:
memory_limit = 16M      ; Maximum amount of memory a script may consume (8MB)
Limit is: 

This script doesn't come above 16M, the original script does however, which is probably another bug..
 [2002-12-03 09:55 UTC] derick@php.net
Script works fine for me on Linux...
 [2002-12-03 10:25 UTC] msopacua@php.net
For completeness:
CFLAGS='-O0' \
./configure \
        --prefix=/phpct \
        --with-apache=../apache_1.3.27 \
        --enable-cli \
        --disable-cgi \
        --enable-debug \
        --enable-magic-quotes \
        --disable-short-tags \
        --with-zlib \
        --with-zlib-dir=/usr \
        --enable-calendar \
        --enable-ftp \
        --with-mhash=/weblib/local \
        --enable-shmop \
        --enable-sysvmsg \
        --enable-sysvsem \
        --enable-sysvshm

Derick:
It may be frame #6: buffer = 0x2. This is typical for BSD's - if you do something like:
char **buffer;

buffer[0] = (char *)malloc(1024);

Linux doesn't seem to mind as I see it in linux oriented packages, but BSD's do as buffer[0] hasn't been allocated.

And:
$ ./test_while.php buffer
Running php 4.4.0-dev on FreeBSD
Running script with memory limit:
php in malloc(): warning: recursive call
FATAL:  emalloc():  Unable to allocate 129 bytes
Segmentation fault (core dumped)


 [2002-12-03 10:43 UTC] msopacua@php.net
And here we go:
(gdb) frame 5
#5  0x814e842 in vspprintf (pbuf=0xbfbfddf8, max_len=1024, 
    format=0x81ce420 "Maximum execution time of %d second%s exceeded", ap=0xbfbfde6c "\002")
    at /home/mdev/cvs/php4/main/spprintf.c:614
614             if (!xbuf_init(&xbuf, max_len)) {
(gdb) info local
xbuf = {buf = 0x0, size = 0, max_len = 1024, buf_end = 0x2839f67d "fflush", nextb = 0x2839f67d "fflush"}
cc = 673076424
(gdb) frame 4
#4  0x814dd30 in xbuf_init (xbuf=0xbfbfdd98, max_len=1024) at /home/mdev/cvs/php4/main/spprintf.c:160
160             xbuf_resize(xbuf, 0); /* NOT max_len */
(gdb) info local
No locals.
(gdb) print *xbuf
$5 = {buf = 0x0, size = 0, max_len = 1024, buf_end = 0x2839f67d "fflush", nextb = 0x2839f67d "fflush"}
(gdb) frame 4
#4  0x814dd30 in xbuf_init (xbuf=0xbfbfdd98, max_len=1024) at /home/mdev/cvs/php4/main/spprintf.c:160
160             xbuf_resize(xbuf, 0); /* NOT max_len */
(gdb) print *xbuf
$6 = {buf = 0x0, size = 0, max_len = 1024, buf_end = 0x2839f67d "fflush", nextb = 0x2839f67d "fflush"}
(gdb) frame 3
#3  0x814dcab in xbuf_resize (xbuf=0xbfbfdd98, add=0) at /home/mdev/cvs/php4/main/spprintf.c:143
143             buf = erealloc(xbuf->buf, size+1); /* alloc space for NUL */
(gdb) print size
$7 = 128

That's the 129 bytes.
Notice that buf_end and nextb are equal.

Additionally, in main/main.c:
    char *buffer;
    int buffer_len, display;
    TSRMLS_FETCH();

    buffer_len = vspprintf(&buffer, PG(log_errors_max_len), format, args);

Which yields:
gdb) frame 6
#6  0x814ab05 in php_error_cb (type=1, error_filename=0x825c424 "/home/mdev/cvs/php4/test_while.php", 
    error_lineno=14, format=0x81ce420 "Maximum execution time of %d second%s exceeded", 
    args=0xbfbfde6c "\002") at /home/mdev/cvs/php4/main/main.c:533
533             buffer_len = vspprintf(&buffer, PG(log_errors_max_len), format, args);
(gdb) print buffer
$8 = 0x66e90a5 <Error reading address 0x66e90a5: Bad address>
 [2002-12-09 12:39 UTC] iliaa@php.net
The debug build with intentionally die with a Segv when emalloc cannot allocate memory.
 [2002-12-09 15:24 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The crash occures because Zend will die with SEGV when emalloc cannot allocate more memory when --enable-debug is on. In this situation the account had a hard memory limit, which PHP exceeded, when it could not allocate more memory it crashed.
Not a PHP bug.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 14:01:28 2024 UTC