Thu 19 Jan 2012 10:23:08 AM UTC, comment #11:
More recent versions of the GNU runtime have fixed this.
|
Fri 05 Feb 2010 06:16:22 PM UTC, comment #10:
Well, as this is not a GNUstep bug, and I've provided a fix to the gcc maintainers, I'll mark it as fixed. In practice though, people should consider either building a patched libobjc from source or experimenting with libobjc2 from the gnustep svn repository.
|
Fri 09 Jan 2009 08:33:43 AM UTC, comment #9:
Yes it is complicated :-(
And yes, the main problems are because I had to maintain performance in the normal case and maintain binary backwards compatibility.
Unfortunately the idea of the meta-class use does not seem workable (unless I misunderstand). The dispatch table of the class contains its instance methods and the dispatch table of the meta-class contains the class methods.
During execution of +initialize we therefore want both dtables to be available to the current thread, so that +initialize can call both class and (eg if a single shared instance is created at that point) instance methods. At the same time we want neither dispatch table to be visible to other threads (so the other threads can't execute eiter class methods or instance methods).
|
Mon 05 Jan 2009 09:54:43 AM UTC, comment #8:
Thanks!
I've looked at the patch and it looks correct but does seem rather complicated but I believe I understand the dilemma.
We want to avoid adding extra checks (like CLS_ISINITIALIZED which would have to be adapted anyways) the hot path.
We are constrained in the class structure layout due to binary compatibility (or we would add a preliminary dtable there to avoid the external linked list, and have message dispatch also check there under the recursive lock on the cold path).
But I'm wondering if we could use the dtable of the meta class during initialization as a fallback for the cold path under the mutex... i.e.:
if
a) the classes dtable is not set yet
b) the dtable of the meta class is set
assume we are currently initializing so lets take the mutex to insure we are thread that's initializing (double checking once we have the lock to see if some other thread was just finishing up)
If we got the lock and the dtable of the meta class is still set, we can assume this is the thread sending a message lookup during +initialize. We use the meta classes dtable for message lookup to finish processing +initialize.
I still need to verify that the dtable of the meta class isn't used for anything else. I'm also haven't convinced myself that this can't produce a deadlock yet. But it would be great if we could avoid the linked list and all the extra helper functions.
I was hoping to come up with a proof-of-concept during the holidays but that didn't work out so I decided to post the idea for now.
|
Thu 01 Jan 2009 03:04:26 PM UTC, comment #7:
I added a patch for a bugfix for this to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38307
I'd appreciate it if other people could have a look at it and spot any errors, though it seems to be working for me.
|
Mon 08 Dec 2008 01:16:44 PM UTC, comment #6:
I think that would be an excellent idea. Thanks for looking into this further. :)
|
Mon 08 Dec 2008 08:48:06 AM UTC, comment #5:
I added a gcc/libobjc bug report for this at
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38307
I can supply a patch against gcc subversion for the runtime if people are interested.
|
Mon 10 Nov 2008 07:07:52 AM UTC, comment #4:
The exception reports the class as being an NSCalendarDate instance, not an NSDate instance, so it's not that the message is going to the wrong class, but the class has no implementation of the method ... however the class does implement the method, so it must be a problem with the dispatch table causing the method lookup to fail, which certainly sounds like an objc runtime error.
My guess is that it's like bug #20163 which is due to the runtime allowing one thread to execute methods of a class while another thread is still calling +initialize
I thought I'd reported that one on the gcc bug tracker, but I can't find it.
|
Mon 10 Nov 2008 05:44:21 AM UTC, comment #3:
For some reason when it reaches the following code in NSLog.m:
else
{
prefix = [NSString
stringWithFormat: @"%@ %@[%d] ",
---->> [[NSCalendarDate calendarDate]
descriptionWithCalendarFormat: @"%Y-%m-%d %H:%M:%S.%F"],
[[NSProcessInfo processInfo] processName],
pid];
}
}
The line indicated calls the method to instatiate a calendarDate object, but for some reason in that method it appears that an NSDate is being used. I'm not sure why.
Here's the method that's being called:
+ (id) calendarDate
{
id d = [[self alloc] init];
return AUTORELEASE(d);
}
For some reason, self here is NSDate and NOT NSCalendarDate as one would expect (given that it was invoked with NSCalendarDate as the class).
Is it possible that this is a thread safety issue in the runtime?
GC
|
Mon 10 Nov 2008 04:48:42 AM UTC, comment #2:
Please see the following:
/home/heron/Development/gnustep/core/base/Testing/synctest/obj/SyncTest: Uncaught exception NSGenericException, reason: subclass NSCalendarDate(instance) should override initWithTimeIntervalSinceReferenceDate:
2008-11-09 23:50:00.149 SyncTest[31952] Before the sync block <NSThread: 0x558980>
This is happening with the attached program. It happens occasionally. This means there is a race condition between these two threads that is causing this to happen.
(file #16812)
|
Sat 08 Nov 2008 10:49:58 PM UTC, comment #1:
What is the bug? What method(s) are concerned and in what way are they unsafe?
|
Sat 08 Nov 2008 10:45:27 PM UTC, original submission:
When NSCalendarDate is entered by two threads this is causing an exception to occur. I was seeing this periodically when NSLog was trying to output information from both threads in the SyncTest tool I wrote to test @synchronize.
|