LINUX.ORG.RU

Кажется я положил пых

 , , ,


0

2

Код вполне себе такой:

<?php

class a
{
    public function getNewB()
    {
        $b = new b();
        $b->a = $this;
        return $b;
    }
}
class b
{
    public $a = null;
    public $b = null;
}
class x
{
    public static $a = null;
    public static $b = null;
    public static function foo()
    {
        self::$a = new a();
        self::$b = self::$a->getNewB();
        self::bar(self::$b);
    }
    public static function bar($b)
    {
        $b->b = self::$a->getNewB();
        self::bar($b->b);
    }
}
x::foo();
Запуск:
~$ php test.php 
Segmentation fault
Т.е. не память, не время, а сразу — херак и всё.

Про окружение:

~$ php -v
PHP 5.6.22-0+deb8u1 (cli) (built: Jun 13 2016 07:55:54) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
32 бит если что.
~$ cat /etc/debian_version 
8.5
Подтверждаете? Или это платформо-версионно зависимое?

Kilte, KRoN73

★★★★★

Последнее исправление: deep-purple (всего исправлений: 2)
Ответ на: комментарий от deep-purple

Повторяю ещё раз: заканчивается не динамическая память, а стек, который ограничен ОС ( ulimit -s ). Стек, @#$%, а не динамическая память! Нет никаких проблем с выделением памяти или её адресацией, в данном случае. Понятно?

Подними размер стека на достаточно большую величину (или уменьши memory_limit) и упрёшься в лимит памяти до того, как закончится стек. И соответственно получишь

PHP Fatal error: Allowed memory size of…

который ты наблюдаешь, выставив memory_limit=1M. А при установленном xdebug

Fatal error: Maximum function nesting level…

Не знаю точно как это происходит (копать исходники php лень, да и не факт, что осилю), но рекурсия в php рано или поздно забивает стек с закономерным результатом в виде segmentation fault. К примеру python работает аналогично, но там глубина рекурсии ограничена по умолчанию и нужно изменить это ограничение, чтобы получить сегфолт.

NeOlip ★★
()
Ответ на: комментарий от NeOlip

Не знаю точно как это происходит

Там всё просто: каждому вызову функции соответствует вызов zend_execute(). Установить максимальную глубину стека вызовов достаточно тривиально: достаточно повесить свой обработчик на zend_execute_internal, при входе в обработчик увеличивать внутренний счётчик вложенности, при выходе — уменьшать. При достижении лимита — вызывать zend_error(E_ERROR, «Maximum function nesting level reached»).

sjinks ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.