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

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

Сенсация! Код initialization может не выполнятся! [D7, Win2k, WinXP]


Страницы:   1 2 3 4 5 6

MikProg ©   (2006-07-11 21:37:00) 

Написана прога. С целью сериализации в секции initialization семи унитов регистрируется описанные в них классы через registerclass. Фенька в следующем: у меня программа работает, у клиента нет. Вставленные в секцию инициализации отладочные строки для записи в файл пишут лог в порядке инициализации модулей. В логе запуска на моей машине (XP и Win2k) отметился каждый из 7 модулей. В логе запуска того же экзешника у клиента (Win2k) отметились тольк 3 из 7 модулей !!! Это полный трындец! Я понимаю что могу грубо регистрировать классы где нибудь в одном месте, но это есть покушение на устои! Кто нибудь может объяснить?


atruhin   (2006-07-13 08:59:00) [41]

> [49] sniknik ©   (12.07.06 14:40)
> > отсюда резонный вопрос - какая разница, указывать const
> или не указывать ?
> для контроля "себя любимого". хотя честно не знал, что оптимизатор
> стал таким умным

Помимо вышеперечисленного большая разница во времени выполнения. При передаче БЕЗ const и var для подсчета ссылок создается неявный:
try
 
finaly
 dec(refcount);
end;
для теста можно измерить скорость выполнения(с const и без const):
function FirstByteLess (S1, S2 : string) : boolean;
begin
 result := S1[1] < S2[1];
end;


Сергей М.   (2006-07-13 08:50:00) [42]


> MikProg ©   (13.07.06 08:38) [70]


см.[13]

> ищу причины приводящие к указанному эффекту


Я как раз и привел одну из таких причин.


MikProg   (2006-07-13 08:38:00) [43]


> Причем здесь "монолитный экзешник" ?

Давать советы не читая вопрос - моветон. Вы не находите?


Сергей М.   (2006-07-13 08:18:00) [44]


> MikProg ©   (12.07.06 20:30) [65]
> Пример для монолитного экзешника?


Причем здесь "монолитный экзешник" ?
У него своя RTL, обращаясь к ней ты регистрируешь класс в соответствующей RTTI. А где-то далее по ходу работы приложения ты, к примеру,  пытаешься проверить, не зарегистрирован ли этот класс в другоммодуле (в bpl или dll), который будучи собранным с инымзначением опции линкера Build With Run-Time Packages пользует другойэкз-р RTL и RTTI соответственно. Совершенно очевидно, что в такой ситуации GetClass вернет nil.


Суслик   (2006-07-12 23:35:00) [45]

ты все же попробуй, что я говорил. если будет ошибка, надо будет дальше разбираться :)


MikProg   (2006-07-12 20:45:00) [46]


> Семество блоков try... уже должно быть на уровне рефлексов

т.е. подразумевается, что дельфа может еще и маскировать ошибки?

а как же вот это

procedure       _StartExe(InitTable: PackageInfo; Module: PLibModule);
begin
 RaiseExceptionProc := @RaiseException;
 RTLUnwindProc := @RTLUnwind;
{$ENDIF}
 InitContext.InitTable := InitTable;
 InitContext.InitCount := 0;
 InitContext.Module := Module;
 MainInstance := Module.Instance;
{$IFNDEF PC_MAPPED_EXCEPTIONS}
 SetExceptionHandler;
{$ENDIF}
 IsLibrary := False;
 InitUnits;
end;

и

procedure       SetExceptionHandler;
asm
 XOR     EDX,EDX                 { using [EDX] saves some space over [0] }
 LEA     EAX,[EBP-12]
 MOV     ECX,FS:[EDX]            { ECX := head of chain                  }
 MOV     FS:[EDX],EAX            { head of chain := @exRegRec            }

 MOV     [EAX].TExcFrame.next,ECX
{$IFDEF PIC}
 LEA     EDX, [EBX]._ExceptionHandler
 MOV     [EAX].TExcFrame.desc, EDX
{$ELSE}
 MOV     [EAX].TExcFrame.desc,offset _ExceptionHandler
{$ENDIF}
 MOV     [EAX].TExcFrame.hEBP,EBP
{$IFDEF PIC}
 MOV     [EBX].InitContext.ExcFrame,EAX
{$ELSE}
 MOV     InitContext.ExcFrame,EAX
{$ENDIF}
end;

Т.е. try except уже есть вокруг всей программы. Просто обрабатка делегирована АПИ ОС

ну и далее

procedure InitUnits;
var
 Count, I: Integer;
 Table: PUnitEntryTable;
 P: Pointer;
begin
 if InitContext.InitTable = nil then
   exit;
 Count := InitContext.InitTable^.UnitCount;
 I := 0;
 Table := InitContext.InitTable^.UnitInfo;
{$IFDEF LINUX}
 Inc(Cardinal(Table), InitContext.Module^.GOT);
{$ENDIF}
 try
   while I < Count do
   begin
     P := Table^[I].Init;
     Inc(I);
     InitContext.InitCount := I;
     if Assigned(P) then
     begin
{$IFDEF LINUX}
       CallProc(P, InitContext.Module^.GOT);
{$ENDIF}
{$IFDEF MSWINDOWS}
       TProc(P)();
{$ENDIF}
     end;
   end;
 except
   FinalizeUnits;
   raise;
 end;
end;

на этом все! Далее идет код initialization унитов


MikProg   (2006-07-12 20:35:00) [47]


> Тут такой момент - проблема не у отвечающих, проблема у
> тебя.

Как это вы заметили. Если бы эта была проблема отвечающих они бы давали советы если не как устранить, то как локализовать проблему. А пока они (сорри народ ничего персонального) блещут эрудицией и не более.


MikProg   (2006-07-12 20:30:00) [48]


> Каждая RTTI создается при инициализации каждой RTL.

Пример для монолитногоэкзешника?


Мефисто   (2006-07-12 19:04:00) [49]


> MikProg ©   (12.07.06 10:00) [13]


Присоеденяюсь к пердыдущим коллегам.

Семество блоков try... уже должно быть на уровне рефлексов


Игорь Шевченко   (2006-07-12 15:30:00) [50]

MikProg ©   (12.07.06 14:44) [51]

Тут такой момент - проблема не у отвечающих, проблема у тебя.


Сергей М.   (2006-07-12 15:15:00) [51]


> MikProg ©   (12.07.06 14:55) [57]
>
>
> > вникнуть в RTTI.
>
> Ну-ну. Подскажите как в монолитном экзешнике создать две
> копии RTTI.


Нунукай в другом месте.

Каждая RTTI создается при инициализации каждой RTL.


StriderMan   (2006-07-12 15:05:00) [52]


> каждый раз при записи в лог такие строковые вычисления??
> ? жуть...

даже дважды....


> procedure LogRecord(s: string);
> var
>  f: Text;
>  oems: array [0..4096] of Char;
> begin
>    Assign(f,LogFileName);
>    if not FileExists(LogFileName) then
>      Rewrite(f)
>    else
>      Append(f);
>    Writeln(f,DateTimeToStr(now),' : ',s);
>    Close(f);
> end;


.. а Close надо бы в finally засунуть...


MikProg   (2006-07-12 15:04:00) [53]


> ЗЫ: Result:= ParamStr(0) + '.log';

вы оптимизирете отладочный код? В любом случае - спасибо, я попробую, но вряд ли это поможет. :)


StriderMan   (2006-07-12 15:01:00) [54]


> Блин.
> function LogFileName: string;
> var
>  s, s1: string;
> begin
>  s:=ParamStr(0);
>  s1:=ExtractFileExt(s);
>  Result:=copy(s,1,length(s)-length(s1))+'.log';
> end;


каждый раз при записи в лог такие строковые вычисления??? жуть...

ЗЫ: Result:= ParamStr(0) + '.log';


MikProg   (2006-07-12 14:57:00) [55]


> С какого перепугу незарегистрированность

Почитай свои посты до полного понимания.


MikProg   (2006-07-12 14:55:00) [56]


> вникнуть в RTTI.

Ну-ну. Подскажите как в монолитном экзешнике создать две копии RTTI.


Сергей М.   (2006-07-12 14:54:00) [57]


> MikProg ©   (12.07.06 14:51) [54]


Ты с дуба упал ?)

С какого перепугу незарегистрированность некоего дельфийского класса вызовет "небезизвестный диалог "Приложение будет закрыто." ?)


MikProg   (2006-07-12 14:52:00) [58]


> что же у тебя в LogFileName?

Блин.
function LogFileName: string;
var
 s, s1: string;
begin
 s:=ParamStr(0);
 s1:=ExtractFileExt(s);
 Result:=copy(s,1,length(s)-length(s1))+'.log';
end;


MikProg   (2006-07-12 14:51:00) [59]


> ЗЫ: Только что испытал
>

Напоминаю. Приложение не вызывает ошибок! А буде она произойдет вы об этом узнаете в любом случае или от обработчика в RTL дельфы или от винды (небезизвестный диалог "Приложение будет закрыто.")


sniknik   (2006-07-12 14:50:00) [60]

> В ожидании ...
не хочеш пока развеять сомнения и ответить, что же у тебя в LogFileName? привести код его определения, и сказать где это происходить.


Страницы:   1 2 3 4 5 6

Наверх

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