When the first attempt to use a class is made, the +initialize method is supposed to be called automatically and safely. The current code check to see whether +initialize needs to be called by seeing if the dispatch table is installed. If the table is not installed, it installs the dispatch table and calls +initialize using locking to prevent another thread from trying to do the same thing, but there is a problem ... once the dispatch table for the class has been installed, it is possible for another thread to use the class before +initialize completes (ie before the method has had a chance to set up all the class variables). This is a rare race condition, but when it occurs it's extremely hard to recognise and track down.
I think the fix is reasonably straightforward: when this occurs we need to refrain from installing the dispatch table until +initialize has completed, but we must make sure that the initializing thread is able to call methods of the class while it is executing. The obvious way to do this is to set up a copy of the dispatch table and have the method lookup use that copy (but only if locking permits) if there is no installed dispatch table. Upon completion of +initialize, the copy is installed as the normal dispatch table so that all threads can use it. Unfortunately I haven't had time to implement/test such a fix yet. -- Summary: Calling of the +initialize method is not completely thread-safe Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libobjc AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rfm at gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38307