Там было сравнительно небольшое переполнение стэка, которое компенсировалось тем, что коллбэк, отжирающий такое большое кол-во стэка, не выполнялся весь сразу, а в нём выполнялись лишь определённые условия и то самое переполнение стэка просто не успевало происходить. Вот тебе простой пример настоящего переполнения стэка.
PHP код:
#pragma dynamic 80
main()
{
new string[100];
format(string, sizeof(string), "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
print(string);
print("Ура, я сработал!");
}
Есть два исхода ситуации для обработки этого кода: с Jit-плагина и без Jit-плагина. Но начать я бы хотел с краткого объяснения того, как работает стэк.
А понять надо именно то, что в стэк данные записываются не обычным образом: от начала к концу (1, 2, 3, 4, 5...), а каждый новый элемент попадает в начало (...5, 4, 3, 2, 1). Проще всего стэк представить как стопку тарелок. Ты не можешь взять тарелку из середины стопки, и засунуть тарелку в середину тоже не можешь. Ты можешь работать только с вершиной стопки. Так же и в стэке. Ему просто не нужно структурировать себя иначе, ибо вся информация попадает в него непрерывным потоком и выдаётся она так же непрерывным потоком (напомню, что стэк, по сути своей, похож на оперативную память, в которую данные загрузились, обработались и тут же выгрузились).
Ну а теперь вернёмся к исходам.
- Исход №1: (сразу предупреждаю, с Jit-компиляцией я знаком поверхностно и всё, что я напишу ниже - лишь мои предположения того, почему ошибок о переполнении стэка не появляется)
Особенность Jit-плагина в том, что он не работает с скомпилированным кодом напрямую, а, фактически, компилирует его прямо на ходу. Из-за этого получается так, что все инструкции для работы серверной машины формируются прямо на месте обработки кода => и инструкции по заносу данных в стэк так же формируются на ходу => из-за этого данные, в случае переполнения, просто перезапишут друг друга и если это не приведёт к каким-то серьёзным последствиям (не перезапишется какая-то важная информация или же переполнение будет очень уж большим) - код обработается, но результатом работы будет порча данных.
В нашем случае, если выделить больше ~ 85 ячеек под стэк - оба сообщения отобразятся нормально, а пострадает лишь информация о вызываемых функциях (при обработке в стэк сначала запишется информация о массиве, после запишется информация о вызове format, а после уже информация о print. Но вспомним про стопкообразную структуру стэка и тут следует понять, что информация print просто займёт место о данных о format... Дальше, возможно, будет понятнее :) )
Если же выделить меньше 85 ячеек, "буфера" из информации о вызываемых функциям (а это имя самой функции + информация о параметрах) уже не хватит и строка из print с сообщением "Ура, я сработал!" начнёт "заезжать" на строку из массива, которую мы отобразили ранее и которая в стеке будет находится сразу за строкой "Ура, я сработал!". Следовательно, нуль-символ строки "Ура, я сработал!" будет перезаписан на один из других символов и строки будут отображены вместе, ибо ближайший нуль-символ будет только в массиве. И чем меньше вы выделите памяти под стэк, тем больше строка "Ура, я сработал!" начнёт "съедать" той информации, что была записана ранее. И в консоль начнут отображаться различные лишние символы. Так будет до тех пор, пока вы не уменьшите стэк до тех пор, когда даже для строки "Ура, я сработал!" не хватит места. Тогда даже с Jit -плагином случится ошибка, которая сообщит о переполнении стэка
- Исход №2:
Без Jit-плагина даже переполнение на 1 ячейку вызовет ошибку у сервера при обработке кода и весь последующий код (в нашем случае это строка "Ура, я сработал!"), что находился в коллбэке/функции после злополучной строки с переполнением, обработан не будет. А теперь представь, что у тебя таких переполнений несколько по всему моду и они находятся в разных коллбэках/функциях и вызываются разными условиями. И тут, когда у тебя на сервере большой онлайн и, соответственно, частота вызова разных участков кода возрастает, вероятность вызова "больного" кода так же возрастает и начинаются различные проблемы, когда у тебя то одна система начинает работать не правильно (стэк переполнился и код перестал обрабатываться => каким-то переменным не присвоились нужные значения, какие-то функции не вызвались и т.п.), то другая. И ты не можешь понять что происходит, ведь, вроде бы, код весь нормально построен и все условия срабатывают...
И это лишь пример с двумя строками. А данные, которые уже не влезут в сам стэк, могут быть совершенно любыми и последствия могут быть совершенно разными.