![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
EStackOverflow [D5, NT4, Win2k]
Дуся © (2002-10-23 13:35:00)Господа!.. Хочется рыдать уже, но все равно не поможет...
Программа вдруг ни с того ни с сего выдает EStackOverflowвнутри процедуры, выполняющейся в отдельном thread. Ладно если бы просто вываливала exception, но затем она просто тихо закрывает приложение. Хотя блокtry..exceptотрабатывает - в логе об этом есть запись.
Процедура самая обычная, обходит список и что-то с каждым элементом делает или не делает в зависимости от статуса. Длина списка порядка 300 элементов. Вызывается за день кучу раз - примерно каждые 2 секунды.
Такой ошибки не встречала раньше никогда.
Вопроса два: с чего бы это, и можно ли как-то это так отлавливать
чтобы она все не роняла!..
Помогите!..
Приложение онлайновое, жутко важное, топор близится.. :(
VMcL (2002-10-25 20:13:00) [1]Возможно поможет следующий приём:
<pre>
procedure TInstrOperator.CheckDataBase;
const
Already: Boolean = False;
// ...
begin
if Already then Exit;
Already := True;
try
// Собственно тело процедуры
finally
Already := False;
end;
end;
</pre>
Дуся (2002-10-24 17:42:00) [2]Все. Понятно. Квадратные скобочки ни к чему.
ЗАРАБОТАЛО!..
Все, наставила диагностики, будем ждать облома.
Digitman (2002-10-24 17:36:00) [3]ох, ну я ж - к примеру) неудачный пример с именем переменной оказался ... ид-р "SP" в контексте asm-блока компилятор считает зарезервированным именем регистра, отсюда и проблема)...
ну обзови ты ее хоть StackPointer :
var
StackPointer: DWord;
..
mov [StackPointer], esp
Дуся (2002-10-24 17:28:00) [4]Как я поняла, тут надо куда-нибудь сунуть значение из регистра esp. Осталось понять, как в код ассемблера вставить адрес переменной ...
Anatoly Podgoretsky (2002-10-24 17:20:00) [5]Привелигированный регистр, только в кольце 0
Кроме того sp это 16 битный, а esp 32 битный, что и является недопустимой комбинацией.
Дуся (2002-10-24 17:15:00) [6]Теперь с ассемблером проблемы :(
Забыла напрочь.
А компилятор ругается на mov [sp], esp : Invalid register combination.
Digitman (2002-10-24 09:59:00) [7]попросту (без лишних премудростей) :
стек - структура памяти типа LIFO, автоматически "ведомая" процессором
фигурирует понятие "указатель на вершину стека" :
- "растет" стек - уменьшается указатель
- "уменьшается" стек - увеличивается указатель
при вызове п/программы стек "растет" на величину, равную размеру ссылки на адрес возврата + полный размер параметров (если имеются) + (иногда) размер результата
при возврате из п/программы стек "уменьшается" на ту же величину, на какую он "вырос" в ходе вызова п/программы
в теле п/программы стек тоже может "дышать", но к моменту возврата из тела, как правило, д.б. таким же как и в момент входа в тело
тем самым достигается т.н. "баланс" стека
переполнение стека есть нарушение его баланса, в рез-те которого стек "вырос" до крит.размера
если п/программа бесконечно вызывает саму себя (см.все о бесконечной рекурсии), возникает как раз ситуация с переполнением стека, ибо стек - не "резиновый" и имеет строго определенный размер
о размере стека можно судить по указателю на его вершину
как прочитать состояние указателя вершины стека - пример приведен
Дуся (2002-10-24 09:34:00) [8]Блин... Со стеком напрямую я-то никогда не работала.. На что там обращать внимание?..
Игорь Шевченко (2002-10-23 18:03:00) [9]В JCL (www.delphi-jedi.org) есть трассировщик стека. Unit JCLDebug.pas
Digitman (2002-10-23 17:46:00) [10]
> мои подозрения насчет железа станут осязаемее
даже не думай.
никакого железа.
только - программа виновата.
попробуй включить в лог инф-цию о состоянии стека ИМЕННО на момент входа в каждую из подозрительных процедур/ф-ций, т.е. в тех точках, где вероятность локального исключения практически отсутствует
момент начала в логе подозрительно стабильного уменьшения значения указателя стека (в совокупности с инф-цией о текущих в этот момент процедурах/ф-циях) вполне может дать уже что-то конкретное
фиксируй ид-р тек.код.потока процесса для сопоставления со стеком, ибо каждый код.поток процесса имеет свой собственный стек
состояние указателя стека и ID тек.код.потока читай так :
var
sp: DWord; // лок.переменная для фиксации указателя стека для тек.метода
tid: DWord; // лок.переменная для фиксации id код.потока, в котором выполняется тек.метод
...
begin
tid := GetCurrentThreadId; //
asm
mov [sp], esp
end;
// здесь - запись в лог значений sp и tid
...
end;
Дуся (2002-10-23 17:13:00) [11]Да там вообще очень глубоко копать....
Вызывается в цикле некий метод, в котором в результате вызывается этот метод этого объекта. Кроме него еще до фига всего прочего... Однако. После падения последняя запись в логе -
TInstrOperator.CheckDataBase EStackOverflow:Stack overflow
К сожалению, подробное логирование включила только вчера, с тех пор упало всего раз. Может в другой раз упадет в другой процедуре - и тогда мои подозрения насчет железа станут осязаемее.. Или нет?
Digitman (2002-10-23 17:02:00) [12]приведи код Execute()
Дуся (2002-10-23 16:55:00) [13]А то.
Только я же говорю - валится иногда, раз в сутки, безсистемно. У меня такого смоделировать не получилось ни разу.
Как такое может быть?..
Digitman (2002-10-23 16:44:00) [14]
> А вот с железом предположение имеет вероятность отличную
> от нуля...
Ерунда полная.
Ты вообще трассировать пыталась сей код ?
Дуся (2002-10-23 14:58:00) [15]Где вы в запостеном коде видели параметры?..
Нету их, чесслово.
А вот с железом предположение имеет вероятность отличную от нуля...
Opuhshii (2002-10-23 14:48:00) [16]2Дуся © (23.10.02 14:46)
у метода класса не может быть параметров передаваемых через стек?
"Может это что-то на уровне железа?" - неверю!
Дуся (2002-10-23 14:46:00) [17]Какие параметры?!... Это все методы класса!..
Может это что-то на уровне железа?
Opuhshii (2002-10-23 14:42:00) [18]я склонен полагать что рекурсия есть, хотя возможно(навряд ли) передача переменных(очень больших) через стек,... вороться указанием var const в параметрах......
Дуся (2002-10-23 14:35:00) [19]Нет, не вызывается.
Рекурсии нет.
Opuhshii (2002-10-23 14:32:00) [20]Скорее всего внутри одного из вызываемых методов скорее всего вызывается TInstrOperator.CheckDataBase; ,..