Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.23;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.027 c
1-1105606105
Leon1
2005-01-13 11:48
2005.01.23
Alignment


1-1104920197
AliceCat
2005-01-05 13:16
2005.01.23
Приведение типов: char -> double


1-1105223958
WhiteGuy
2005-01-09 01:39
2005.01.23
Move It!


3-1103542973
IBChaynik
2004-12-20 14:42
2005.01.23
BLOB поле


1-1105428274
Eyfel
2005-01-11 10:24
2005.01.23
пакеты в deplhi 2005