On 4 Mar 2011, at 14:54, Banlu Kemiyatorn wrote: > On Wed, Mar 2, 2011 at 1:24 PM, Richard Frith-Macdonald > <[email protected]> wrote: >> >> On 2 Mar 2011, at 06:21, Richard Frith-Macdonald wrote: >> >> >>> >>> OK ... that should build and run for you (and does for me) without trouble. >>> If it usually works, but fails, rarely, I guess there might be some race >>> condition in gnustep-base (but from looking at the source I can't see how >>> that could be). >>> If it fails consistently, I think there is something wrong with locking or >>> threading on your machine. >> >> >> Of course, the best thing you can do is run under gdb, set a breakpoint to >> catch the exception, and try to see where/how things are going wrong. > > #0 -[NSRecursiveLock unlock] (self=0xb580a3b0, _cmd=0xb7fb5808) at > NSLock.m:270 > #1 0xb7d9b623 in +[NSUserDefaults standardUserDefaults] > (self=0xb7fb5700, _cmd=0xb7fb57f0) > at NSUserDefaults.m:691 > #2 0xb7d9b81b in GSPrivateDefaultsFlag (type=GSLogSyslog) at > NSUserDefaults.m:2144 > #3 0xb7ce6a95 in NSLogv (format=0x804a23c, > args=0xb615a264 > "��\004\b[�ȷ�_��\b�\004\bl�\004\b��\004\b(�\b\b��\004\b\b�\004\b�\210\004\b�_��\b�\004\b\020z\a\b��\025�0�Ϸ\020z\a\b\b�\004\b") > at NSLog.m:305 > #4 0xb7ce6f04 in NSLog (format=0x804a23c) at NSLog.m:252 > #5 0x08048922 in -[MyObj launch:] (self=0x8077a10, _cmd=0x804a208, > task=0x0) at problem.m:24 > #6 0xb7cfdb30 in -[NSObject performSelector:withObject:] > (self=0x8077a10, _cmd=0xb7fa5da8, > aSelector=0x804a208, anObject=0x0) at NSObject.m:1763 > #7 0xb7d6bc6a in -[NSThread main] (self=0x808df10, _cmd=0xb7fa5db0) > at NSThread.m:729 > #8 0xb7d6c291 in nsthreadLauncher (thread=0x808df10) at NSThread.m:792 > #9 0xb7b36cc9 in start_thread () from /lib/libpthread.so.0 > #10 0xb7a4569e in clone () from /lib/libc.so.6 > > Above is what I got from bt, below is the code that cause the problem > which, commenting out any NSLog will put away the "Uncaught exception > NSLockException, reason: failed to unlock mutex" problem. > > #include <unistd.h> > #import <Foundation/Foundation.h> > > @implementation NSObject (Launch) > - (void) launch:(id)task > { > id p = [NSAutoreleasePool new]; > NSLog(@"hello"); > [p release]; > } > @end > > int main (int argc, const char * argv[]) { > [NSAutoreleasePool new]; > id obj = [NSObject new]; > [NSThread detachNewThreadSelector:@selector(launch:) > toTarget:obj withObject:nil]; > NSLog(@"failing"); > [NSThread detachNewThreadSelector:@selector(launch:) > toTarget:obj withObject:nil]; > return 0; > }
I suspect that what you have run into here is a bug in the gnu Objective-C runtime. You have two threads started and immediately calling NSLog, which in turn immediately tries to access the user defaults system. The user defaults system is protected by a lock 'classLock' created in its +initialize method, which is run automatically by the runtime. The +initialize method is supposed to run in a thread-safe manner *before* any other method in the class can run ... so this should mean that classLock, created in +initialize, can safely be used later. What I think is happening is that one thread calls the +standarduserDefault method, and the runtime calls +initialize, then before +initialize has completed, the second thread calls +standardUserDefaults (and the runtime incorrectly lets it), which tries to lock classLock before it has been created. This will send a _lock method to a nil object, which does nothing. The thread then creates the shared user defaults object and tries to unlock classLock, but by this time the first thread has created the lock, so an -unlock message is sent to classLock when in has not been locked. This bug only rarely manifests, since it depends on a race condition when a class is initialized, and in most non-trivial programs, most important classes are used before any threads are started. You could check to see if this is your problem by calling any NSUserDefaults method before starting the threads... if it is, doing that will prevent the exception from occurring. Unless it's been fixed, this is probably the biggest outstanding bug in the gnu runtime. _______________________________________________ Gnustep-dev mailing list [email protected] http://lists.gnu.org/mailman/listinfo/gnustep-dev
