Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизПодайте идею как искать причину stack overflow Найти похожие ветки
← →
Alias © (2005-06-16 12:53) [0]Имеется приложение моего производства. Пользователи жалуются, что время от времени появляется сообщение "stack overflow" после чего приложение падает. Найти закономерность при котором ситуация появляется они не могут. Я тоже. Подозреваю, что это как-то связано с динамическим созданием/удалением форм. Форм много, около сотни.
Размышляю как эту ситуацию вылавливать. Подумал вначале, что хорошо бы все события открытия и закрытия формочек писать в файлик и туда же писать события исключений. Но это требует серьезной перестройки всего приложения т.к. все формы наследуются от TForm. Да и стоит ли овчинка выделки?
Что скажет уважаемый All?
← →
BiN © (2005-06-16 12:58) [1]Навскидку: некорректная рекурсия
← →
Ega23 © (2005-06-16 12:58) [2]Где-то память не освобождаешь. Где - тебе виднее.
← →
-=XP=- © (2005-06-16 12:59) [3]Напишите в файле проекта {$MAXSTACKSIZE 100000000}.
Если ошибка будет повторяться, то, скорее всего, где-то происходит (рекурсивное) зацикливание.
Если ошибка пропадет, значит, где-то в производится попытка выделить большой участок памяти в стеке. Найдите это место и, если есть возможность - оптимизируйте алгоритм. Или, если так и должно быть - оставьте все как есть. Подправьте, правда, значение MaxStackSize.
← →
jack128 © (2005-06-16 13:34) [4]Ega23 © (16.06.05 12:58) [2]
Где-то память не освобождаешь. Где - тебе виднее.
тут стек не причем.
Скорее всего либо действительно бесконечная/очень глубокая рекурсия, либо по наобъявлял статических массивов нехилой размерности аля array[0..50 * 1024 - 1] of TLargeRecord во всяких разных процедурах..
← →
Alias © (2005-06-16 13:52) [5]Больших массивов нету, это точно.
Остается вариант - рекурсивное зацикливание (других не прозвучало).
Я вот что думаю. Любая форма удаляясь удаляет всех своих потомков (тех, у кого она в Parent). Это ведь рекурсия. А если есть две формы, которые ссылаются друг на друга?.. Интересно такое может быть? Искать ошибку где-то в строках, где присутствует .Parent:=...? или .Create(self) ?
← →
jack128 © (2005-06-16 13:57) [6]Alias © (16.06.05 13:52) [5]
А если есть две формы, которые ссылаются друг на друга?..
нет, такого быть не может. Не может быть такого, что A.Parent := B и при этом B.Parent := A. в VCL подобных глюков нету, разве что ты сам ручками подобный функционал реализовал и где то ошибся..
← →
evvcom © (2005-06-16 14:14) [7]
> Любая форма удаляясь удаляет всех своих потомков (тех, у
> кого она в Parent).
Форма удаляет тех, у кого она Owner, а не Parent.
А классическая рекурсия (вызов из функции/процедуры/метода себя же) в программе присутствует где-нибудь?
← →
Alias © (2005-06-16 14:14) [8]2jack128 Нет, я подобного не делал. Это обычное бизнес приложение. Там нет хитроумного функционала. Нет и моих рекурсивных функций. Формочек много это да. Многие из них вызывают друг друга. Но это не должно быть причиной.
т.е. реализовать в VCL бесконечную рекурсию невозможно?
Какие еще идеи?
Есть еще работа с БД. Много всяких DataSet-ов. Тут ничего не может быть?
← →
Oleg2 (2005-06-16 14:20) [9]А не создаёш ли ты объект в цикле (к примеру TBitmap), а
потом не удаляеш?
← →
Fay © (2005-06-16 14:22) [10]2 Alias © (16.06.05 14:14) [8]
>> Но это не должно быть причиной.
Совершенно верно - не должно. Но МОЖЕТ.
← →
Digitman © (2005-06-16 14:23) [11]
> т.е. реализовать в VCL бесконечную рекурсию невозможно?
очень даже возможно.
например в обработчике некоего события некоего контрола ты вызываешь некий метод, исполнение которого в свою очередь приводит к возбуждению того же события
← →
-=XP=- © (2005-06-16 14:24) [12]Много всяких DataSet-ов. Тут ничего не может быть?
Проверьте:procedure DoSomething;
begin
DataSet.First;
while not DataSet.Eof do
begin
<...>
DoSomething; // Безусловный вызов - ошибка
<...>
if <Условие> then // Проверьте условие - может быть зацикливание
DoSomething;
<...>
DataSet.Next; // Обязательно, а то зависнет
end;
end;
← →
Юрий Зотов © (2005-06-16 14:32) [13]> Alias © (16.06.05 14:14) [8]
> Там нет хитроумного функционала. Нет и моих рекурсивных
> функций.
Для создания рекурсии вовсе не требуется хитроумного функционала. Достаточно написать обработчик события (или сообщения), код которого прямо или опосредованно возбуждает то же самое событие (или посылает то же самое сообщение). Вот простой (специально утрированный) пример - обработчик события OnChange компонента TEdit:
procedure TForm1.Edit1Change(Sender: TObject);
begin
Edit1.Text := "1" + Edit1.Text
end;
← →
jack128 © (2005-06-16 14:50) [14]evvcom © (16.06.05 14:14) [7]
Форма удаляет тех, у кого она Owner, а не Parent.
любой WinControl удаляет все свои контролы, в том числе и форма
← →
evvcom © (2005-06-16 15:05) [15]
> jack128 © (16.06.05 14:50) [14]
Я знаю...
← →
lookin © (2005-06-21 18:24) [16][13] Юрий Зотов © (16.06.05 14:32)
Насчет этого примера я подумал вот что. Как я понимаю, stack overflow в этом случае происходит из-за "переполнения" строки, которая является массивом. Так вот не надо ли думать, что возникающий в данном примере stack overflow есть результат непродуманной реализации TEdit? Ведь как я понимаю, всегда можно реализовать проверку на выход за пределы массива при попытке добавить в оный новый символ?
← →
Anatoly Podgoretsky © (2005-06-21 18:45) [17]lookin © (21.06.05 18:24) [16]
Неверно понимаешь, строка занимает всего 4 байта на стеке. А переполнение происходит из-за бесконечного рекурсивного выхова обработчика.
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.052 c