Форум: "Система";
Текущий архив: 2002.12.30;
Скачать: [xml.tar.bz2];
ВнизEStackOverflow Найти похожие ветки
← →
Дуся (2002-10-23 13:35) [0]Господа!.. Хочется рыдать уже, но все равно не поможет...
Программа вдруг ни с того ни с сего выдает EStackOverflow внутри процедуры, выполняющейся в отдельном thread. Ладно если бы просто вываливала exception, но затем она просто тихо закрывает приложение. Хотя блокtry..except
отрабатывает - в логе об этом есть запись.
Процедура самая обычная, обходит список и что-то с каждым элементом делает или не делает в зависимости от статуса. Длина списка порядка 300 элементов. Вызывается за день кучу раз - примерно каждые 2 секунды.
Такой ошибки не встречала раньше никогда.
Вопроса два: с чего бы это, и можно ли как-то это так отлавливать
чтобы она все не роняла!..
Помогите!..
Приложение онлайновое, жутко важное, топор близится.. :(
← →
Opuhshii (2002-10-23 13:53) [1]Рекурсия у Вас,
"просто тихо закрывает приложение" - правильно,. почитайте Рихтера поймете почему,.. это очень правильно... ;)
← →
Дуся (2002-10-23 13:57) [2]Рекурсии йок.
В хелпе написано "либо рекурсия, либо очень большие локальные переменные" (extremely large local variables) - это как так - очень большие?!..
и почему валится-то не на каждом проходе, а от балды ?..
← →
Игорь Шевченко (2002-10-23 14:04) [3]Код в студию. Телепатов здесь нету
← →
Дуся (2002-10-23 14:12) [4]
procedure TInstrOperator.CheckDataBase;
Var
i : integer;
LCount : integer;
begin
try
if InsideList = nil then exit;
LCount := InsideList.Count - 1;
StatusForm.FIProgress.Max:=LCount+1;
StatusForm.AllFI.caption:= IntToStr(LCount+1);
if NoNewFI and NoNewQueue then
exit;
WriteToLogFile("TInstrOperator.CheckDataBase. Lcount = "+IntToStr(LCount));
for i := 0 to LCount do
begin
WorkInstr := InsideList.Items[i];
if WorkInstr <> nil then
begin
if (WorkInstr.Board < 0){ or (WorkInstr.Board > 4) }then
begin
if WorkInstr.Board <> 11 then continue;
end;
if WriteInitToBase then
if not WorkInstr.InitOnDataBase then WorkInstr.InitDataBase;
if WorkInstr.InitOnDataBase then
if not WorkInstr.OnDataBase then WorkInstr.ToDataBase;
WorkInstr.SequenceToDataBase;
StatusForm.FIProgress.Position := i;
StatusForm.I1.Caption := IntToStr (i+1);
end;
end;
StatusForm.FIProgress.Position := StatusForm.FIProgress.Max;
StatusForm.FIProgress.Position := 0;
StatusForm.i1.Caption := "";
except
on E:Exception do
WriteToLogFile("TInstrOperator.CheckDataBase " + E.ClassName+":"+E.Message);
end;
end;
← →
Дуся (2002-10-23 14:14) [5]Вот... Если кому понятно что-то вообще...
← →
Opuhshii (2002-10-23 14:19) [6]лажа скорее всего не здесь,...
← →
Дуся (2002-10-23 14:25) [7]а где?..
Внутри одного из вызываемых методов?..
но тогда там бы и валилось - там тоже проверок наставлено сверх меры...
← →
Opuhshii (2002-10-23 14:32) [8]Скорее всего внутри одного из вызываемых методов скорее всего вызывается TInstrOperator.CheckDataBase; ,..
← →
Дуся (2002-10-23 14:35) [9]Нет, не вызывается.
Рекурсии нет.
← →
Opuhshii (2002-10-23 14:42) [10]я склонен полагать что рекурсия есть, хотя возможно(навряд ли) передача переменных(очень больших) через стек,... вороться указанием var const в параметрах......
← →
Дуся (2002-10-23 14:46) [11]Какие параметры?!... Это все методы класса!..
Может это что-то на уровне железа?
← →
Opuhshii (2002-10-23 14:48) [12]2Дуся © (23.10.02 14:46)
у метода класса не может быть параметров передаваемых через стек?
"Может это что-то на уровне железа?" - неверю!
← →
Дуся (2002-10-23 14:58) [13]Где вы в запостеном коде видели параметры?..
Нету их, чесслово.
А вот с железом предположение имеет вероятность отличную от нуля...
← →
Digitman (2002-10-23 16:44) [14]
> А вот с железом предположение имеет вероятность отличную
> от нуля...
Ерунда полная.
Ты вообще трассировать пыталась сей код ?
← →
Дуся (2002-10-23 16:55) [15]А то.
Только я же говорю - валится иногда, раз в сутки, безсистемно. У меня такого смоделировать не получилось ни разу.
Как такое может быть?..
← →
Digitman (2002-10-23 17:02) [16]приведи код Execute()
← →
Дуся (2002-10-23 17:13) [17]Да там вообще очень глубоко копать....
Вызывается в цикле некий метод, в котором в результате вызывается этот метод этого объекта. Кроме него еще до фига всего прочего... Однако. После падения последняя запись в логе -
TInstrOperator.CheckDataBase EStackOverflow:Stack overflow
К сожалению, подробное логирование включила только вчера, с тех пор упало всего раз. Может в другой раз упадет в другой процедуре - и тогда мои подозрения насчет железа станут осязаемее.. Или нет?
← →
Digitman (2002-10-23 17:46) [18]
> мои подозрения насчет железа станут осязаемее
даже не думай.
никакого железа.
только - программа виновата.
попробуй включить в лог инф-цию о состоянии стека ИМЕННО на момент входа в каждую из подозрительных процедур/ф-ций, т.е. в тех точках, где вероятность локального исключения практически отсутствует
момент начала в логе подозрительно стабильного уменьшения значения указателя стека (в совокупности с инф-цией о текущих в этот момент процедурах/ф-циях) вполне может дать уже что-то конкретное
фиксируй ид-р тек.код.потока процесса для сопоставления со стеком, ибо каждый код.поток процесса имеет свой собственный стек
состояние указателя стека и ID тек.код.потока читай так :
var
sp: DWord; // лок.переменная для фиксации указателя стека для тек.метода
tid: DWord; // лок.переменная для фиксации id код.потока, в котором выполняется тек.метод
...
begin
tid := GetCurrentThreadId; //
asm
mov [sp], esp
end;
// здесь - запись в лог значений sp и tid
...
end;
← →
Игорь Шевченко (2002-10-23 18:03) [19]В JCL (www.delphi-jedi.org) есть трассировщик стека. Unit JCLDebug.pas
← →
Дуся (2002-10-24 09:34) [20]Блин... Со стеком напрямую я-то никогда не работала.. На что там обращать внимание?..
← →
Digitman (2002-10-24 09:59) [21]попросту (без лишних премудростей) :
стек - структура памяти типа LIFO, автоматически "ведомая" процессором
фигурирует понятие "указатель на вершину стека" :
- "растет" стек - уменьшается указатель
- "уменьшается" стек - увеличивается указатель
при вызове п/программы стек "растет" на величину, равную размеру ссылки на адрес возврата + полный размер параметров (если имеются) + (иногда) размер результата
при возврате из п/программы стек "уменьшается" на ту же величину, на какую он "вырос" в ходе вызова п/программы
в теле п/программы стек тоже может "дышать", но к моменту возврата из тела, как правило, д.б. таким же как и в момент входа в тело
тем самым достигается т.н. "баланс" стека
переполнение стека есть нарушение его баланса, в рез-те которого стек "вырос" до крит.размера
если п/программа бесконечно вызывает саму себя (см.все о бесконечной рекурсии), возникает как раз ситуация с переполнением стека, ибо стек - не "резиновый" и имеет строго определенный размер
о размере стека можно судить по указателю на его вершину
как прочитать состояние указателя вершины стека - пример приведен
← →
Дуся (2002-10-24 17:15) [22]Теперь с ассемблером проблемы :(
Забыла напрочь.
А компилятор ругается на mov [sp], esp : Invalid register combination.
← →
Anatoly Podgoretsky (2002-10-24 17:20) [23]Привелигированный регистр, только в кольце 0
Кроме того sp это 16 битный, а esp 32 битный, что и является недопустимой комбинацией.
← →
Дуся (2002-10-24 17:28) [24]Как я поняла, тут надо куда-нибудь сунуть значение из регистра esp. Осталось понять, как в код ассемблера вставить адрес переменной ...
← →
Digitman (2002-10-24 17:36) [25]ох, ну я ж - к примеру) неудачный пример с именем переменной оказался ... ид-р "SP" в контексте asm-блока компилятор считает зарезервированным именем регистра, отсюда и проблема)...
ну обзови ты ее хоть StackPointer :
var
StackPointer: DWord;
..
mov [StackPointer], esp
← →
Дуся (2002-10-24 17:42) [26]Все. Понятно. Квадратные скобочки ни к чему.
ЗАРАБОТАЛО!..
Все, наставила диагностики, будем ждать облома.
← →
VMcL (2002-10-25 20:13) [27]Возможно поможет следующий приём:
<pre>
procedure TInstrOperator.CheckDataBase;
const
Already: Boolean = False;
// ...
begin
if Already then Exit;
Already := True;
try
// Собственно тело процедуры
finally
Already := False;
end;
end;
</pre>
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2002.12.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.015 c