Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Self в потоке


TUser ©   (2005-01-13 11:58:00) 

Вот такая проблема, даже не знаю, как описать. Есть дополнительный поток, там из 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 14:48:00) [1]


> ну и как ты себе мыслишь это - переменной перечисляемого
> типа присвоить значение типа метод объекта ?

Никак не мыслю. Там еще и другая переменная есть (procedure of object). Раньше была просто переменной, в [12] я сделал ее полем класса TMyThread. Короче, исправился.


Digitman   (2005-01-13 14:33:00) [2]


> TUser ©   (13.01.05 14:15) [15]


ну и как ты себе мыслишь это - переменной перечисляемоготипа присвоить значение типа метод объекта?

цитирую тебя :


> переменной прописать :=TMyThread.Proc1


Proc1 - это метод объекта класса TMyThread
"переменная" же , по твоим же словам, -  перечислимого типа

ну дурь же ! ... согласись ?


TUser   (2005-01-13 14:15:00) [3]

Перечисляемого (afValue1, afValue2)


Digitman   (2005-01-13 14:11:00) [4]


> переменной


переменной КАКОГГО типа ?


TUser   (2005-01-13 14:07:00) [5]

FAnyField - это поле класса TMyThread.


TUser   (2005-01-13 14:06:00) [6]

OnTerminate, конечно.

А баг действительно исправился. И как я раньше не знал, что если объявленной в модуле переменной прописать :=TMyThread.Proc1, то вызов этой Proc1 даже из другого метода TMyThread не приведет к тому, что Proc1 получит указатель на объект класса TMyThread?!


Alexander Panov   (2005-01-13 14:04:00) [7]

Что-то я не пойму.
FAnyField у тебя тип, но ты используешь именно тип, а не переменную?


Digitman   (2005-01-13 14:03:00) [8]


> А разве OnExecute


что еще за OnExecute ? не знаю я такого события


KSergey   (2005-01-13 13:58:00) [9]

Есть подозрение, что проблема совсем не тут, ибо Self = nil - это бред какой-то.
К стати, а если написать явно if Self = nil then - вот прям и сработает? А то может ты просто несколько перегрелся по поводу Alt+Ctrl+C? ;)  (без обид)
Ну либо где-то явно портится память, если это вдруг так. Если напрямую работы с памятью через указатели нет - возможно поможет Check Constraint


TUser   (2005-01-13 13:56:00) [10]


> > Ну, и понятно - AV при обращении к одному из полей этого
>
> > объекта
>
>
> налицо явное противоречие.

Когда выполняется поток - то приходим в OnTerminate. Я просто попробовал вызвать все это дело в контексте основного потока (заменил resume на execute) - получил AV :) А разве OnExecute не должен вызываться при аварийном завершении потока?


TUser   (2005-01-13 13:54:00) [11]

Прошел отладчиком, посмотрел - в какой момент 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.


Digitman   (2005-01-13 13:53:00) [12]


> поток почему-то вылетает (в смысле - терминируется). Выполняется
> OnTerminate


> Ну, и понятно - AV при обращении к одному из полей этого
> объекта


налицо явное противоречие.
либо необработанное AV, приводящее к непредсказуемым рез-там, либо возбуждение OnTerminate - штатный и корректный факт корректного же завершения выполнения кода в теле Execute

у тебя происходит возбуждение OnTerminate - о каком же AV можно вести речь ? до возбуждения OnTerminate попросту дело не дойдет, если в ходе выполнения Execute будет возбуждено и никак не обработано непредусмотренное исключение, хотя бы то же самое AV


TUser   (2005-01-13 13:45:00) [13]


> TMyThread - наследник TThread ?

Да.

> Не видно описания FAnyField. ЧТо это  - тип или переменная?

FAnyField: (afValue1, afValue2);
Да, значение ему присваиваниется. Даже один раз проверяется, какое оно - и все вроде бы нормально. Только вот во время выполнения потока почему-то оказывается, что Self = nil, т.е. ноль. Ну, и понятно - AV при обращении к одному из полей этого объекта.


Verg   (2005-01-13 13:42:00) [14]

TMyThread - наследник TThread ?


Alexander Panov   (2005-01-13 13:32:00) [15]

Не видно описания FAnyField. ЧТо это  - тип или переменная?


Alexander Panov   (2005-01-13 13:31:00) [16]

Мало что понятно из топика.
Но проверь, инициализируется ли FAnyField.


TUser   (2005-01-13 13:26:00) [17]

up


Наверх

Титульная страница Поиск, карта сайта Написать письмо