Форум: "Основная";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];
ВнизSelf в потоке Найти похожие ветки
← →
TUser © (2005-01-13 11:58) [0]Вот такая проблема, даже не знаю, как описать. Есть дополнительный поток, там из Execute"а вызываются какие-то процедуры. И вот в одной из них написано
procedure TMyThread.MyProc;
begin
if FAnyField = afValue1 then
{do somthing}
else
{do other}
end;
FAnyField описан как FAnyField: (afValue1, afValue2). На строке "if FAnyField = ..." поток почему-то вылетает (в смысле - терминируется). Выполняется OnTerminate.
Посмотрел в CPU. Там написано так
cmp byte ptr [eax+$60],$00
jz +<сколько-то>
Т.е. в eax должен быть адрес объекта, а $60 - смещение, по которому хранится значение FAnyField. Но в eax лежит ноль.
В другом месте потока, где также проверяется значение этого поля, компилятор пишет
cmp byte ptr [edi+$60],$00
причем в edi лежит какой-то нормальный адрес. Если подставить через CPU window в eax правильный адрес (в тот момент, когда там ноль), то эта строчка работает, хотя дальше, конечно, большие глюки, потому что где-то что-то я так понимаю очень глобально неправильно. Только вот не могу понять, что и где.
Пробовал написать
P:=DWord(@Self)
asm
mov eax, P; // ИМХО, это полный бред
end;
но компилятор перед сравнением подставляет в eax правильный (по его понятиям адрес), т.е. 0. Думал, может не синхронизировал я чего-нибудь, что положено было синхронизировать, но вроде бы все правильно. В чем может быть беда, подскажите, plz.
← →
TUser © (2005-01-13 13:26) [1]up
← →
Alexander Panov © (2005-01-13 13:31) [2]Мало что понятно из топика.
Но проверь, инициализируется ли FAnyField.
← →
Alexander Panov © (2005-01-13 13:32) [3]Не видно описания FAnyField. ЧТо это - тип или переменная?
← →
Verg © (2005-01-13 13:42) [4]TMyThread - наследник TThread ?
← →
TUser © (2005-01-13 13:45) [5]
> TMyThread - наследник TThread ?
Да.
> Не видно описания FAnyField. ЧТо это - тип или переменная?
FAnyField: (afValue1, afValue2);
Да, значение ему присваиваниется. Даже один раз проверяется, какое оно - и все вроде бы нормально. Только вот во время выполнения потока почему-то оказывается, что Self = nil, т.е. ноль. Ну, и понятно - AV при обращении к одному из полей этого объекта.
← →
Digitman © (2005-01-13 13:53) [6]
> поток почему-то вылетает (в смысле - терминируется). Выполняется
> OnTerminate
> Ну, и понятно - AV при обращении к одному из полей этого
> объекта
налицо явное противоречие.
либо необработанное AV, приводящее к непредсказуемым рез-там, либо возбуждение OnTerminate - штатный и корректный факт корректного же завершения выполнения кода в теле Execute
у тебя происходит возбуждение OnTerminate - о каком же AV можно вести речь ? до возбуждения OnTerminate попросту дело не дойдет, если в ходе выполнения Execute будет возбуждено и никак не обработано непредусмотренное исключение, хотя бы то же самое AV
← →
TUser © (2005-01-13 13:54) [7]Прошел отладчиком, посмотрел - в какой момент Self принимает
значение nil. Оказалось вот здесь
type
TMyThread = class(TThread)
FAnyField: (afValue1, afValue2);
...
procedure Proc1;
end;
implementation
type TStates = array of
record
... {разные поля}
OnEnter = procedure of object
end;
var States: TStates;
procedure TMyThread.Execute;
begin
...
if assigned(States[i]) then
// i = 0, такой элемент в массиве есть
States[i].OnEnter;
...
end;
procedure AddState(...);
begin
{добавляем элемент в массив States, если там еще такого нет}
end;
initialization
...
AddState (...Proc1)
...
end.
Т.е. поясню. Есть массив записей, в которых есть ссылки на некие процедуры объекта. Но, когда, я их их объекта вызываю, то у них self = nil. Наверное, так и должно быть, хотя они и описаны, как методы TMyThread.
← →
TUser © (2005-01-13 13:56) [8]
> > Ну, и понятно - AV при обращении к одному из полей этого
>
> > объекта
>
>
> налицо явное противоречие.
Когда выполняется поток - то приходим в OnTerminate. Я просто попробовал вызвать все это дело в контексте основного потока (заменил resume на execute) - получил AV :) А разве OnExecute не должен вызываться при аварийном завершении потока?
← →
KSergey © (2005-01-13 13:58) [9]Есть подозрение, что проблема совсем не тут, ибо Self = nil - это бред какой-то.
К стати, а если написать явно if Self = nil then - вот прям и сработает? А то может ты просто несколько перегрелся по поводу Alt+Ctrl+C? ;) (без обид)
Ну либо где-то явно портится память, если это вдруг так. Если напрямую работы с памятью через указатели нет - возможно поможет Check Constraint
← →
Digitman © (2005-01-13 14:03) [10]
> А разве OnExecute
что еще за OnExecute ? не знаю я такого события
← →
Alexander Panov © (2005-01-13 14:04) [11]Что-то я не пойму.
FAnyField у тебя тип, но ты используешь именно тип, а не переменную?
← →
TUser © (2005-01-13 14:06) [12]OnTerminate, конечно.
А баг действительно исправился. И как я раньше не знал, что если объявленной в модуле переменной прописать :=TMyThread.Proc1, то вызов этой Proc1 даже из другого метода TMyThread не приведет к тому, что Proc1 получит указатель на объект класса TMyThread?!
← →
TUser © (2005-01-13 14:07) [13]FAnyField - это поле класса TMyThread.
← →
Digitman © (2005-01-13 14:11) [14]
> переменной
переменной КАКОГГО типа ?
← →
TUser © (2005-01-13 14:15) [15]Перечисляемого (afValue1, afValue2)
← →
Digitman © (2005-01-13 14:33) [16]
> TUser © (13.01.05 14:15) [15]
ну и как ты себе мыслишь это - переменной перечисляемого типа присвоить значение типа метод объекта ?
цитирую тебя :
> переменной прописать :=TMyThread.Proc1
Proc1 - это метод объекта класса TMyThread
"переменная" же , по твоим же словам, - перечислимого типа
ну дурь же ! ... согласись ?
← →
TUser © (2005-01-13 14:48) [17]
> ну и как ты себе мыслишь это - переменной перечисляемого
> типа присвоить значение типа метод объекта ?
Никак не мыслю. Там еще и другая переменная есть (procedure of object). Раньше была просто переменной, в [12] я сделал ее полем класса TMyThread. Короче, исправился.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.057 c