-
Постов
2 -
Зарегистрирован
-
Посещение
Активность репутации
-
UniSoft получил реакцию от Kitty в Проблемы со стилями и релиз конфигурацией XE8 &C++
ну исходники библиотек то одни...
а вот в x64 не проявляется...
да и еще этот баг там не единственный, понизив приоритет инициализатора все запускается нормально,
но падает уже при закрытии и в каком-то другом модуле.
патч fmx.lib и cw32mt.lib решают проблему...
http://rghost.net/6rNpG5LlC
но я бы не рекомендовал это использовать, высока вероятность,
что может начать конфликтовать с какими либо другими модулями.
как устроена инициализация, и о каких приоритетах идет речь,
можно посмотреть тут: функция _init_exit_proc()
C:\Program Files (x86)\Embarcadero\Studio\16.0\source\cpprtl\Source\startup\initexit.c
C:\Program Files (x86)\Embarcadero\Studio\16.0\source\cpprtl\rtlinc\_startup.h
по хорошему, нужно бы отправить баг-репорт, ведь баг то критический,
но у меня нет EDN аккаунта.
-
UniSoft получил реакцию от zairkz в Проблемы со стилями и релиз конфигурацией XE8 &C++
Проблема в инициализации модулей, точнее в последовательности их инициализации. FMX.Types.pas initialization ... // <<< тут проблема, // на момент вызова этого конструктора, инициализация модуля System.Rtti.pas // еще не выполнялась... // т.е. модуль System.Rtti.pas инициализируется после FMX.Types.pas SharedContext := TRttiContext.Create; ... System.Rtti.pas class function TRttiContext.Create: TRttiContext; begin EnsurePoolToken(@Result.FContextToken); end; constructor TPoolToken.Create; begin TMonitor.Enter(PoolLock); // вот тут то и падение, модуль еще не инициализирован и PoolLock = nil try if Pool = nil then begin Pool := TRttiPool.Create; PoolRefCount := 1; end else Inc(PoolRefCount); finally TMonitor.Exit(PoolLock); end; end; procedure EnsurePoolToken(TokenRef: PInterface); var sample: Pointer; procedure DoCreate; var tok: IInterface; begin tok := TRttiContext.FGlobalContextToken; if tok = nil then tok := TPoolToken.Create; if AtomicCmpExchange(PPointer(TokenRef)^, Pointer(tok), sample) = sample then begin // We won the race to initialize the TokenRef location, so // zero-out interface reference without decrementing reference count. PPointer(@tok)^ := nil; end; end; begin sample := PPointer(TokenRef)^; if sample <> nil then Exit; DoCreate; end; initialization ... PoolLock := TObject.Create; Есть еще один нюанс, инициализация System.Rtti.pas зачем-то выполняется два раза, к краху это не приведет, но небольшой (не накопительный) memleak будет. Проблема в библиотеках, и похоже только Win32 ЗЫ. к стилям никакого отношения не имеет... достаточно одной строчки: void __fastcall TForm1::FormCreate(TObject *Sender) { TValue::From<String>("test"); } -
UniSoft получил реакцию от Kitty в Проблемы со стилями и релиз конфигурацией XE8 &C++
Проблема в инициализации модулей, точнее в последовательности их инициализации. FMX.Types.pas initialization ... // <<< тут проблема, // на момент вызова этого конструктора, инициализация модуля System.Rtti.pas // еще не выполнялась... // т.е. модуль System.Rtti.pas инициализируется после FMX.Types.pas SharedContext := TRttiContext.Create; ... System.Rtti.pas class function TRttiContext.Create: TRttiContext; begin EnsurePoolToken(@Result.FContextToken); end; constructor TPoolToken.Create; begin TMonitor.Enter(PoolLock); // вот тут то и падение, модуль еще не инициализирован и PoolLock = nil try if Pool = nil then begin Pool := TRttiPool.Create; PoolRefCount := 1; end else Inc(PoolRefCount); finally TMonitor.Exit(PoolLock); end; end; procedure EnsurePoolToken(TokenRef: PInterface); var sample: Pointer; procedure DoCreate; var tok: IInterface; begin tok := TRttiContext.FGlobalContextToken; if tok = nil then tok := TPoolToken.Create; if AtomicCmpExchange(PPointer(TokenRef)^, Pointer(tok), sample) = sample then begin // We won the race to initialize the TokenRef location, so // zero-out interface reference without decrementing reference count. PPointer(@tok)^ := nil; end; end; begin sample := PPointer(TokenRef)^; if sample <> nil then Exit; DoCreate; end; initialization ... PoolLock := TObject.Create; Есть еще один нюанс, инициализация System.Rtti.pas зачем-то выполняется два раза, к краху это не приведет, но небольшой (не накопительный) memleak будет. Проблема в библиотеках, и похоже только Win32 ЗЫ. к стилям никакого отношения не имеет... достаточно одной строчки: void __fastcall TForm1::FormCreate(TObject *Sender) { TValue::From<String>("test"); }