Зависание при ошибке. Плохая ревизия 3476

Уже исправленные репорты или принятые предложения
Закрыто
Yiivgeny
Сообщения: 80
Зарегистрирован: 2010.11.24, 10:39

Зависание при ошибке. Плохая ревизия 3476

Сообщение Yiivgeny »

Здравствуйте.

Суть:
При условии, что zlib.output_compression=On (аналогичных директив управляющих буферизацией из конфига достаточно много), при возникновении любой ошибки Yii 1.1.9-dev неизменно зависает, что приводит в конечном итоге к вылету по тайм-ауту и печали в дальнейших поисках собственных ошибок.

Почему:
После изменения 3476 файл /base/CErrorHandler.php выглядит так (101-102)

Код: Выделить всё

while (ob_get_level())
    @ob_end_clean(); 
Если убрать значок собаки, становится видна проблема. А именно:
Notice: ob_end_clean() [ref.outcontrol]: failed to delete buffer zlib output compression in /framework/base/CErrorHandler.php on line 101
Нельзя сбросить буфер функцией ob_end_clean, если буферизация включена определенным образом (в данном случае из конфига). Соответственно ob_get_level() никогда не принимает нулевое значение, что означает бесконечный цикл.

Мое решение основывается на том, что если буфер не сбросился успешно в первый раз, то и вторая попытка ему не поможет.

Примерно так (заменить 101 строку):

Код: Выделить всё

for ($level=ob_get_level();$level>0;--$level) 
После релиза это может стать большой неожиданностью для некоторых разработчиков. Считаю достаточно важной проблемой, чтобы пофиксить как можно скорее.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Зависание при ошибке. Плохая ревизия 3476

Сообщение samdark »

Хм. А более верного решения нет? Неужели при использовании gzip буфер вообще не чистится никакими средствами?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Зависание при ошибке. Плохая ревизия 3476

Сообщение samdark »

Ага, понял проблему. PHP оборачивает всё в ещё один буфер, который потом gzip-ит при этом ob_get_level будет больше не единичку изначально. Его закрыть нельзя самостоятельно и получается бесконечный цикл. Хм…
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Зависание при ошибке. Плохая ревизия 3476

Сообщение samdark »

http://code.google.com/p/yii/source/detail?r=3485 Решение не идеальное (хочется всё-так убрать @), но работает. Спасибо.
Закрыто