View Issue Details

IDProjectCategoryView StatusLast Update
0027016Open CASCADEOCCT:Foundation Classespublic2016-04-20 15:51
ReporterabvAssigned Tobugmaster  
Status closedResolutionfixed 
Product Version7.0.0 
Target Version7.0.0Fixed in Version7.0.0 
Summary0027016: Restore global type descriptors for old compilers
DescriptionFix made for 0026551 has removed global variables holding instances of OCCT type descriptors and ensuring initialization of all types at load time. This is safe for modern compilers that implement thread-safe initialization of static variables, and helps to essentially decrease size of produced binaries (e.g. for VC++ 14: by 22% in total by OCCT, and up to 2 times on some DLLs).

However, this variant proved to be unsafe on older compilers, in particular VC++ 10 - 12. This is caused by the fact that guard flag generated by VC++ to mark static variable as initialized gets changed before the initialization actually took place (see assembly code in Additional Information).

When the same type descriptor function is called for the first time simultaneously from two threads, one thread can access type descriptor while the other thread already set guard flag but not yet initialized the variable. This leads to usage of zero handle and hence assess violation error.
Steps To Reproducebuild with VC++ 10, 11, or 12 with TBB enabled, then run

test bugs modalg_6 bug26701
Additional information
and documentation updates
VC10 initialization of static:

    // static variable inside function ensures that descriptors
    // are initialized in correct sequence
    static Handle(Standard_Type) anInstance =
      Standard_Type::Register (typeid(T).name(), T::get_type_name(), sizeof(T),
                               type_instance<typename T::base_type>::get());
00007FFE3E5CA22E mov eax,dword ptr [`opencascade::type_instance<Standard_Transient>::get'::`2'::`local static guard' (7FFE3E7D1BF8h)]
00007FFE3E5CA234 and eax,1
00007FFE3E5CA237 test eax,eax
00007FFE3E5CA239 jne opencascade::type_instance<Standard_Transient>::get+0F6h (7FFE3E5CA306h)
00007FFE3E5CA23F mov eax,dword ptr [`opencascade::type_instance<Standard_Transient>::get'::`2'::`local static guard' (7FFE3E7D1BF8h)]
00007FFE3E5CA245 or eax,1
00007FFE3E5CA248 mov dword ptr [`opencascade::type_instance<Standard_Transient>::get'::`2'::`local static guard' (7FFE3E7D1BF8h)],eax
00007FFE3E5CA24E lea rcx,[rsp+20h]
00007FFE3E5CA253 call opencascade::type_instance<void>::get (7FFE3E5C1010h)
00007FFE3E5CA258 mov qword ptr [rsp+38h],rax
00007FFE3E5CA25D mov rax,qword ptr [rsp+38h]
00007FFE3E5CA262 mov qword ptr [rsp+40h],rax
00007FFE3E5CA267 lea rdx,[__type_info_root_node (7FFE3E7D7618h)]
00007FFE3E5CA26E lea rcx,[Standard_Transient `RTTI Type Descriptor' (7FFE3E74F0B0h)]
00007FFE3E5CA275 call qword ptr [__imp_type_info::name (7FFE3E6CAB90h)]
00007FFE3E5CA27B mov r9,qword ptr [rsp+40h]
00007FFE3E5CA280 mov r8d,10h
00007FFE3E5CA286 lea rdx,[string "Standard_Transient" (7FFE3E6CD688h)]
00007FFE3E5CA28D mov rcx,rax
00007FFE3E5CA290 call Standard_Type::Register (7FFE3E624040h)
00007FFE3E5CA295 mov qword ptr [rsp+28h],rax
00007FFE3E5CA29A mov rax,qword ptr [rsp+28h]
00007FFE3E5CA29F mov qword ptr [anInstance (7FFE3E7D1BF0h)],rax
00007FFE3E5CA2A6 cmp qword ptr [anInstance (7FFE3E7D1BF0h)],0
00007FFE3E5CA2AE je opencascade::type_instance<Standard_Transient>::get+0ADh (7FFE3E5CA2BDh)
00007FFE3E5CA2B0 mov rcx,qword ptr [anInstance (7FFE3E7D1BF0h)]
00007FFE3E5CA2B7 call Standard_Transient::IncrementRefCounter (7FFE3E623B10h)
00007FFE3E5CA2BC nop
00007FFE3E5CA2BD cmp qword ptr [rsp+20h],0
00007FFE3E5CA2C3 je opencascade::type_instance<Standard_Transient>::get+0E0h (7FFE3E5CA2F0h)
00007FFE3E5CA2C5 mov rcx,qword ptr [rsp+20h]
00007FFE3E5CA2CA call Standard_Transient::DecrementRefCounter (7FFE3E623B30h)
00007FFE3E5CA2CF test eax,eax
00007FFE3E5CA2D1 jne opencascade::type_instance<Standard_Transient>::get+0E0h (7FFE3E5CA2F0h)
00007FFE3E5CA2D3 mov rax,qword ptr [rsp+20h]
00007FFE3E5CA2D8 mov rcx,qword ptr [rsp+20h]
00007FFE3E5CA2DD mov rcx,qword ptr [rcx]
00007FFE3E5CA2E0 mov qword ptr [rsp+48h],rcx
00007FFE3E5CA2E5 mov rcx,rax
00007FFE3E5CA2E8 mov rax,qword ptr [rsp+48h]
00007FFE3E5CA2ED call qword ptr [rax+8]
00007FFE3E5CA2F0 mov qword ptr [rsp+20h],0
00007FFE3E5CA2F9 lea rcx,[`opencascade::type_instance<Standard_Transient>::get'::`2'::`dynamic atexit destructor for 'anInstance'' (7FFE3E6BB080h)]
00007FFE3E5CA300 call atexit (7FFE3E689C60h)
00007FFE3E5CA305 nop
    return anInstance;
00007FFE3E5CA306 lea rax,[anInstance (7FFE3E7D1BF0h)]
TagsNo tags attached.
Test case number


related to 0026551 closedbugmaster Open CASCADE Optimization of initialization of OCCT RTTI 
related to 0027254 closedabv Community [Regression] 7.0 types initialization mechanism is not thread-safe on VS2013 



2015-12-19 14:19

administrator   ~0049320

Branch CR27016 has been created by abv.

SHA-1: 9189511636768a35cdea4a873cff96bc5bb298be

Detailed log of new commits:

Author: abv
Date: Sat Dec 19 14:19:31 2015 +0300

    0027016: Restore global type descriptors for old compilers
    Global type descriptors are restored for VC++ 10 - 12 and GCC before 4.3.
    Checks of GCC version are corrected in Standard_Handle.hxx


2015-12-19 20:42

administrator   ~0049322

Branch CR27016 has been updated forcibly by abv.

SHA-1: 261d758a9c0e87afdb9b3b9ec3b504353600c3f9


2015-12-20 08:46

manager   ~0049323

Fix pushed to CR27016, please review


2015-12-20 09:29

developer   ~0049324

Please test the patch.


2015-12-20 14:44

administrator   ~0049325

Branch CR27016 has been updated forcibly by abv.

SHA-1: e8a2764dae5b10435260ae220dabfa2c88286ab4


2015-12-20 14:45

manager   ~0049326

The last push contains just a minor amendment in comment, please use it


2015-12-21 10:54

administrator   ~0049341

Branch CR27016 has been updated forcibly by inv.

SHA-1: e26f159dec97c14df7996a15541eee1e11095db9


2015-12-21 16:47

administrator   ~0049377

Branch CR27016 from occt git-repository (and master from products git-repository) was compiled on Linux, MacOS and Windows platforms and tested.
SHA-1: e26f159dec97c14df7996a15541eee1e11095db9

Number of compiler warnings:
occt component:
   Linux: 0 (0 on master)
   Windows: 0 (0 on master)
   MacOS: 137 (136 on master)
products component:
   Linux: 0 (0 on master)
   Windows: 0 (0 on master)

Not detected

Testing cases:
Not needed

Testing on Linux:
Total MEMORY difference: 89527351 / 89628557 [-0.11%]
Total CPU difference: 19198.079999999885 / 18960.5199999998 [+0,13%]

Testing on Windows:
Total MEMORY difference: 56655760 / 54322241 [+0.30%]
Total CPU difference: 17484.170877298715 / 17551.25130729881 [-0.38%]


2016-04-17 14:14

administrator   ~0053112

Branch CR27016 has been deleted by kgv.

SHA-1: e26f159dec97c14df7996a15541eee1e11095db9

Related Changesets

occt: master d9e90905

2015-12-19 14:55:41


Committer: bugmaster Details Diff
0027016: Restore global type descriptors for old compilers

Global type descriptors are restored for VC++ 10 - 12 and GCC before 4.3.

Checks of compiler support of C++ features are corrected for GCC, ICC, and CLang in Standard_Handle.hxx
Affected Issues
mod - src/Standard/Standard_Handle.hxx Diff File
mod - src/Standard/Standard_Type.hxx Diff File

Issue History

Date Modified Username Field Change
2015-12-19 14:15 abv New Issue
2015-12-19 14:15 abv Assigned To => abv
2015-12-19 14:15 abv Relationship added related to 0026551
2015-12-19 14:19 git Note Added: 0049320
2015-12-19 20:42 git Note Added: 0049322
2015-12-20 08:46 abv Note Added: 0049323
2015-12-20 08:46 abv Assigned To abv => kgv
2015-12-20 08:46 abv Status new => resolved
2015-12-20 08:47 abv Priority normal => urgent
2015-12-20 09:29 kgv Note Added: 0049324
2015-12-20 09:29 kgv Assigned To kgv => bugmaster
2015-12-20 09:29 kgv Status resolved => reviewed
2015-12-20 14:44 git Note Added: 0049325
2015-12-20 14:45 abv Note Added: 0049326
2015-12-21 10:54 git Note Added: 0049341
2015-12-21 16:47 bugmaster Note Added: 0049377
2015-12-21 16:47 bugmaster Status reviewed => tested
2015-12-25 19:04 bugmaster Changeset attached => occt master d9e90905
2015-12-25 19:04 bugmaster Status tested => verified
2015-12-25 19:04 bugmaster Resolution open => fixed
2016-03-11 17:44 Roman Lygin Relationship added related to 0027254
2016-04-17 14:14 git Note Added: 0053112
2016-04-20 15:42 aiv Fixed in Version => 7.0.0
2016-04-20 15:51 aiv Status verified => closed