View Issue Details

IDProjectCategoryView StatusLast Update
0027584CommunityOCCT:Foundation Classespublic2017-10-07 09:58
ReporterRoman Lygin Assigned Toabv 
PrioritynormalSeveritymajor 
Status closedResolutionunable to reproduce 
Platform64 bitOSLinux 
Product Version7.0.0 
Summary0027584: __gnu_cxx::recursive_init_error thrown when concurrently accessing STANDARD_TYPE
DescriptionThe new RTTI type mechanism introduced in 0026551 exposed an issue of gcc-specific fragile concurrent initialization of static variables due to recursive calls in template <typename T> const Handle(Standard_Type)& type_instance<T>::get().

Although this is a sighting (i.e. an effect that is not always reproduced) we periodically encounter it in our code. The symptom is a thrown exception __gnu_cxx::recursive_init_error when concurrently invoking a function theType::get_type_descriptor() via a macro STANDARD_TYPE(XXX), when a type is initialized for the first time, for instance:

void foo (const Geom_Curve& theCurve)
{
   if (theCurve.IsKind (STANDARD_TYPE (Geom_BSplineCurve))) {
   }
}

We did not manage to create an isolated reproducer but investigation revealed that this has something to do with gcc implementation of concurrent initialization of static variables with recursion. Refer for instance to these discussions:
https://bugs.chromium.org/p/nativeclient/issues/detail?id=3948
https://bugs.chromium.org/p/chromium/issues/detail?id=413513
and their references.

As a work-around we currently plan to enforce initialization of the types during load-time (i.e. similarly to what existed in OCC prior to version 7.0). For OCC a possible recommendation could be to introduce a macro that (if defined during compile time) could select a code branch to use 'older compiler'-like behavior in type_instance<T>::get().
TagsNo tags attached.
Test case number

Relationships

related to 0026551 closedbugmaster Open CASCADE Optimization of initialization of OCCT RTTI 

Activities

abv

2016-06-14 18:56

manager   ~0054982

Roman, can you precise what versions of GCC suffer from this problem? does it appear with older versions? or newest ones are also affected? do you really believe that this error is due to new implementation of the type system in OCCT 7.0, or it would be the same with OCCT 6.9.x implementation?

My understanding was that GCC should have implemented 'safe statics' feature of C++11 reasonably well, but your report seems indicate that it is not the case.

Actually reading more on the subject I got a feeling that this problem should not be related to concurrency but rather be really a recursion problem. To my understanding, normally there should be no recursion in type initializers of OCCT classes, as soon as they form a tree-like hierarchy. The recursion may probably appear if inheritance is incorrectly specified in DEFINE_STANDARD_RTTI macro. Thus I suggest that you can try to debug this problem and see at least on initializer(s) of what particular type(s) it occurs.

Roman Lygin

2016-06-16 13:08

developer   ~0055073

Andrey,

The issue is reproduced on Linux only, in the following configurations
- gcc 4.8.2
- gcc 4.9.2
- clang 3.6 with gcc 4.9.2 back-end

So it happens with relatively up to date compiler and moreover the issue is apparently in the run-time library, not in the code gen.

I do believe it is connected with new type system in 7.0 - most likely due to use of static variables in templated methods. Perhaps this has something to do with multiple injection of the same variable into multiple modules and some name conflict (on Linux there is a global map of symbol names, regardless of modules where each symbol was defined).

This only happens when two modules concurrently call STANDARD_TYPE() of some Geom_Curve subclass and on the stack there are always at least two threads with type creation of Geom_Curve.

What we did to work-around this after having spent a few person-hours trying to debug and investigate the issue is to call STANDARD_TYPE() for all subclasses of Geom_Curve, Geom2d_Curve and Geom_Surface during single threaded initialization. The ideas is to ensure single threaded initialization of respective static variables.

abv

2017-10-06 15:03

manager   ~0071265

Hello Roman,

I am going to close this issue since:
- it is not reported by any other user except you;
- there are no known ways to reproduce it;
- there is no explanation how recursive initialization can theoretically happen in OCCT type system.

Thus my impression is that the problem you observed might have been caused by some issue in your application, or combination of your app specifics with some bug in GNU standard C library.

If you have some new information on this subject, please feel free to share.

Roman Lygin

2017-10-07 08:30

developer   ~0071277

Hello Andrey,
Let's close the bug indeed.

Issue History

Date Modified Username Field Change
2016-06-08 20:59 Roman Lygin New Issue
2016-06-08 20:59 Roman Lygin Assigned To => abv
2016-06-09 09:50 Roman Lygin Relationship added related to 0026551
2016-06-14 18:56 abv Note Added: 0054982
2016-06-14 18:59 abv Assigned To abv => Roman Lygin
2016-06-14 18:59 abv Status new => feedback
2016-06-16 12:59 Roman Lygin Assigned To Roman Lygin => abv
2016-06-16 13:08 Roman Lygin Note Added: 0055073
2016-06-16 17:37 Roman Lygin Status feedback => assigned
2016-11-09 11:16 abv Target Version 7.1.0 => 7.2.0
2017-08-15 12:59 abv Target Version 7.2.0 => Unscheduled
2017-10-06 15:03 abv Note Added: 0071265
2017-10-06 15:03 abv Assigned To abv => Roman Lygin
2017-10-06 15:03 abv Status assigned => feedback
2017-10-07 08:30 Roman Lygin Assigned To Roman Lygin => abv
2017-10-07 08:30 Roman Lygin Note Added: 0071277
2017-10-07 09:58 abv Status feedback => closed
2017-10-07 09:58 abv Resolution open => unable to reproduce
2017-10-07 09:58 abv Target Version Unscheduled =>