Форум: "Основная";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
Вниз
Процедуры вылетают без ошибок Найти похожие ветки
← →
Krolm © (2008-11-05 06:52) [0]В достаточно крупном приложении произвольно вылетают процедуры. То есть доходит до какой-то строчки, потом в подпрограмме при построковой отладке брейк прыгает на строчку end; и выходит из всех подпрограмм на самый высокий уровень. Никаках сообщений об ошибках. Если есть try finally блоки - finally обрабатывается нормально.
Типичные процедуры, после которых вылетает:s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
sl.add(s); (sl:TstringList);
При этом если такие "проблемные" процедуры заменить на другие попроще, например MessageBox(0,@s[1],"",0); Все отрабатывается без проблем.
Сначала помогло увеличение размера стека + директива компилятора inline. Поток стал отрабатывать без проблем. Но такая же ерунда возникла в основной программе, в процедуре сохранения StringGrid в файл. Не могу найти причину. Что может быть?
ОС Vista, CodeGear™ RAD Studio 2007 Version 11.0.2902.10471
← →
Сергей М. © (2008-11-05 10:58) [1]try
s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
except
on e:exception do
Messagebox(0, PChar(e.classname + " " + e.Message), "", mb_ok or mb_setforeground); // <- что дословно написано в тексте сообщения ?
end;
← →
KSergey © (2008-11-05 12:25) [2]Это наблюдается только в отладчике?
StringList точно создан до использования?
Приложение однопоточное или многопоточное?
← →
Anatoly Podgoretsky © (2008-11-05 13:04) [3]> Поток стал отрабатывать без проблем.
← →
Anatoly Podgoretsky © (2008-11-05 13:05) [4]> Поток стал отрабатывать без проблем.
← →
KSergey © (2008-11-05 13:29) [5]> Anatoly Podgoretsky © (05.11.08 13:04) [3]
> > Поток стал отрабатывать без проблем.
Я это читал, от того и последнйи вопрос.
Но может чел. имел ввиду что-то другое? Но если тама еще и многопоточность....
← →
Anatoly Podgoretsky © (2008-11-05 16:01) [6]> KSergey (05.11.2008 13:29:05) [5]
В которой наверно и происходит ошибка и поток слетает, вместе с приложением. Особенно если гдето есть except end;
← →
Leonid Troyanovsky © (2008-11-05 16:05) [7]
> Krolm © (05.11.08 06:52)
> В достаточно крупном приложении произвольно вылетают процедуры.
IsMultiThread = True?
--
Regards, LVT.
← →
Loginov Dmitry © (2008-11-05 23:03) [8]> То есть доходит до какой-то строчки, потом в подпрограмме
> при построковой отладке брейк прыгает на строчку end; и
> выходит из всех подпрограмм на самый высокий уровень. Никаках
> сообщений об ошибках. Если есть try finally блоки - finally
> обрабатывается нормально.
Это все в доп. потоке? Тогда какие сообщения об ошибках ожидаются? Поток грохается просто, вот и все. Тут необходимо перехватывать исключение, как в [1].
← →
Германн © (2008-11-06 02:25) [9]Ох уж эти доппотоки! :(
Чур меня!
← →
Krolm © (2008-11-06 08:31) [10]По вопросам: 2 потока. 1 - интерфейс. 2 - работа с сетью.
try
s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
except
on e:exception do
Messagebox(0, PChar(e.classname + " " + e.Message), "", mb_ok or mb_setforeground); // <- что дословно написано в тексте сообщения ?
end;
Никаких исключительных ситуаций не возникает. Но я все таки нашел причину.
При создании формы на событии OnShow висело выравнивание ширины колонок. И был там код наподобие следующиего:
for i:= main.Colcount to main.ColCount+5 do
main.Colwidths[i]:=-1;
main.Colcount была представлена в виде константы, и при изменении структуры таблицы (столбцов стало меньше) я не отловил что происходит бред и вообще обращение к тем объектам, которых не существует.
У меня остается вопрос, почему софт не сыпался на этом этапе. А сыпался потом, когда уже работал даже не со StringGrid ом.
← →
Krolm © (2008-11-06 08:33) [11]Надо было включить RangeCheck короче, и было бы все намного проще. Хотя почему никакой ошибки ReadofAddress не возникало, для меня до сих пор загадка. Компилятор получается сглупил?
← →
Сергей М. © (2008-11-06 08:42) [12]
> Krolm © (06.11.08 08:31) [10]
> Никаких исключительных ситуаций не возникает
Значит в утверждении
> Типичные процедуры, после которых вылетает:
> s:=StringReplace(s,#13#10,#9,[rfReplaceAll]);
> sl.add(s); (sl:TstringList);
>
> При этом если такие "проблемные" процедуры заменить на другие
> попроще, например MessageBox(0,@s[1],"",0); Все отрабатывается
> без проблем.
>
нет ни слова истины
← →
Anatoly Podgoretsky © (2008-11-06 08:50) [13]> Krolm (06.11.2008 8:31:10) [10]
Потому, что ты начинающий и до тебя пока не доходит необходимость настройки компилятора на предмет проверки выхода за границы (Range checking).
← →
Anatoly Podgoretsky © (2008-11-06 08:51) [14]> Krolm (06.11.2008 8:33:11) [11]
Не кати бочку на компилятор, сглупил ты, компилятор честно выполнил твои пожелания.
← →
KSergey © (2008-11-06 10:21) [15]Память не выделяется побайтно, да и не может компилятор встраивать код проверки каждого байтика: допустимо его (байтика) использование программистом или нет. Это слишком накладно и затратно было бы в плане ресурсов и производительности.
А потому обращение к произвольному участку памяти не всегда недопустимо: возможно эта память находится в блоке, который вообще-то данному приложению доступен с точки зрения ОС, однако память эта заполнена мусором. Ну либо вообще шарахаемся по собственному стеку: тогда получается операции с памятью приложению разрешены, однако понятно, что ничего доброго из этого не получится. Обработка исключений - она тоже ведь вовсе не "неубиваемая".
(впрочем, переходи на .NET - тама подобные засады решены в ядре + компиляторе, причем неотключаемо, если только не пытаться "обмануть" компилятор специально).
← →
Krolm © (2008-11-06 10:54) [16]Все хватит флейм разводить. Что там компилятор должен или не должен.
2KSergey дело не в проверках каждого байта. Мне раньше казалось, что обращение к несуществующему объекту обязательно должно провоцировать ошибку. Разве не так? А если уж за пределами памяти своего приложения- тогда вообще ОС должна ругаться что приложение недопустимую операцию осуществляет. Тут видимо ситуация именно со стеком была, с учетом того, что увеличение его размера позволило нормально отрабатывать потоку.
Анатолий, каждый программист допускает ошибки. Называть это глупостью нехорошо. В противном случае все программисты заранее глупы. Мы люди, а не машины. Ради интереса опять написал свою ошибку в код и прогнал программу со включенным RangeCheck ом. Никакой ругани.
Нехорошо поступил разработчик компонента TSortGrid, который сделал так:
procedure InvalidOp(const id: string);
begin
// raise EInvalidGridOperation.Create(id);
end;
procedure TMyCustomGrid.SetColWidths(Index: Longint; Value: Integer);
begin
if FColWidths = nil then
UpdateExtents(FColWidths, ColCount, DefaultColWidth);
if Index >= ColCount then InvalidOp(SIndexOutOfRange);
if Value <> PIntArray(FColWidths)^[Index + 1] then
begin
ResizeCol(Index, PIntArray(FColWidths)^[Index + 1], Value);
PIntArray(FColWidths)^[Index + 1] := Value;
ColWidthsChanged;
end;
end;
Хороший подход к созданию безглючных компонентов)) Мне страшно раскоментировать эту строчку)
← →
Anatoly Podgoretsky © (2008-11-06 11:07) [17]В том то и дело, что тебе только кажется.
← →
Krolm © (2008-11-06 12:43) [18]Казалось) Все приходит с опытом. Анатолий, Вы как специалист может расскажете о том, в каки случаях Access Violation не возникает? Какие-нибудь примеры? Мне например будет интересно изучить этот вопрос.
← →
Сергей М. © (2008-11-06 13:05) [19]
> Мне страшно раскоментировать эту строчку
В D7 (build 8.1) и в Grids и в QGrids строчка, на которой ты сделал акцент, не закомментирована ..
← →
Krolm © (2008-11-06 14:13) [20]Я написал что это не StringGrid а SortGrid. Компонент взят с торри. Написать самому такое - уйдут недели. Вот пожинаю плоды своей лени.
← →
Сергей М. © (2008-11-06 14:19) [21]Тогда смело раскомментируй
← →
Krolm © (2008-11-06 14:47) [22]Уже. Сижу мучаюсь( Повыкидывал из него много лишнего)) Ну для меня не нужного типа настроек шрифтов для каждой ячейки.
← →
Сергей М. © (2008-11-06 14:56) [23]
> Написать самому такое - уйдут недели
А чем собссно StringGrid не угодил ?
← →
Krolm © (2008-11-06 15:20) [24]Нет сортировки, нет фильтрации. Это самое важное. Сортировку еще могу реализовать. Но как фильтрацию сделать - даже и не знаю.
← →
Сергей М. © (2008-11-06 15:26) [25]
> Krolm © (06.11.08 15:20) [24]
А откуда вообще у тебя берутся данные, визуализируемые гридом ?
← →
Anatoly Podgoretsky © (2008-11-06 15:27) [26]> Krolm (06.11.2008 12:43:18) [18]
Ни какой мистики.
В тех случая когда не происходить нарушения, то есть память еще принадлежит твоему приложению, и она еще не порушена, а показывает на еще не существующий кусок или уже занятый другим экземпляром.
Подобный вопрос часто задают - как узнать разрушен компонент или нет. Обсуждения обычно длинные.
← →
Anatoly Podgoretsky © (2008-11-06 15:28) [27]> Krolm (06.11.2008 14:13:20) [20]
По делу пожинаешь. В моих программ единственный посторонний компонент - это TntUnicode - по острой необходимости.
← →
Vlad Oshin © (2008-11-06 15:35) [28]
> как фильтрацию сделать
есть идея второй grid поверх первого держать, второй слой как-бы.
И показывать его и в нем то, что удовлетворяет фильтру из первого
← →
KSergey © (2008-11-06 16:11) [29]> Vlad Oshin © (06.11.08 15:35) [28]
> есть идея второй grid поверх первого держать, второй слой как-бы.
ТОгда навероне будет правильнее все ж отдельный контейнер сделать, а не использовать грид не по делу :)
← →
MsGuns © (2008-11-07 15:00) [30]>Krolm © (06.11.08 15:20) [24]
>Нет сортировки, нет фильтрации. Это самое важное. Сортировку еще могу реализовать. Но как >фильтрацию сделать - даже и не знаю.
Все делается элементарно, если использовать сетку только для отображения, а сами данные хранить в структурах (классах, рекордах,БД) списками. Списки можно и сортировать и фильтровать, а в сетку "передавать" только список отображаемых. Грид куда быстрее перерисует новый список, чем, например, будет менять местами строки, например, при сортировке.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.007 c