Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
14-1118254778
digger
2005-06-08 22:19
2005.07.11
Обрезали UTP кабель :-(


1-1118494263
Pasha L
2005-06-11 16:51
2005.07.11
FILETIME


6-1112869182
_Alexander_
2005-04-07 14:19
2005.07.11
Сообщение через сокет передается не полностью


14-1118038510
vidiv
2005-06-06 10:15
2005.07.11
*.cdw


1-1118919896
Priest
2005-06-16 15:04
2005.07.11
Как определить по какому столбцу кликнули в cxGridDBTableVi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский