[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Deadlock in +initialize with libojbc2
From: |
Thomas Davie |
Subject: |
Re: Deadlock in +initialize with libojbc2 |
Date: |
Mon, 13 Aug 2012 15:45:35 +0100 |
Experiments say that apple's runtime is fine with this code. As you can see
from my reply, the runtime is indeed using a per-class lock, but it's also
locking on a central runtime lock, and doing so before the per-class initialize
lock in one thread, and after in the other, resulting in the deadlock.
My hack to lock on the central runtime lock works, but I'm guessing it's not
ideal to do this?
Re my code being incorrect, that's entirely possible – but I'm not aware of any
rules surrounding spawning threads, and using classes (hence triggering
+initialize), are there any?
Thanks
Tom Davie
On 13 Aug 2012, at 15:41, David Chisnall <theraven@sucs.org> wrote:
> The runtime follows the Apple semantics that +initialize uses a per-class
> lock. If you hit a deadlock here, then most likely your code is wrong and
> won't work on Apple's implementation either. The GCC runtime uses a single
> lock for all +initialize instances, so will deadlock in a different set of
> situations.
>
> David
>
> On 13 Aug 2012, at 11:26, Thomas Davie wrote:
>
>> I've done some reading through the source for libobjc2, and added a quick
>> and dirty hack to lock the runtime in objc_send_initialize, as thread 1 was
>> locking initialize lock then runtime lock while thread 2 was locking runtime
>> lock then initialize lock... I though do not understand in any way how the
>> threading model of libojbc2 works, so I probably did something pretty dumb
>> in doing that.
>>
>> I'd appreciate it if someone with knowledge of how threading is meant to
>> work here could take a look at that and see if what I did was sane.
>>
>> Thanks
>>
>> Tom Davie
>>
>> On 13 Aug 2012, at 10:11, Thomas Davie <tom.davie@gmail.com> wrote:
>>
>>> Hi all,
>>>
>>> I'm hitting an issue with deadlocks in +initialize. I'm using the latest
>>> (svn 35399) libobjc2. Gdb tells me this:
>>>
>>> (gdb) info threads
>>> Id Target Id Frame
>>> * 2 Thread 0x7fffe2612700 (LWP 8878) "bds" 0x00007ffff65f9be4 in
>>> __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
>>> 1 Thread 0x7ffff7fe6000 (LWP 8875) "bds" 0x00007ffff65f9be4 in
>>> __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
>>> (gdb) thread 1
>>> [Switching to thread 1 (Thread 0x7ffff7fe6000 (LWP 8875))]
>>> #0 0x00007ffff65f9be4 in __lll_lock_wait () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> (gdb) bt
>>> #0 0x00007ffff65f9be4 in __lll_lock_wait () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #1 0x00007ffff65f5200 in _L_lock_928 () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #2 0x00007ffff65f5099 in pthread_mutex_lock () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #3 0x00007ffff6a96919 in create_dtable_for_class (class=0x7fffdc862900,
>>> root_dtable=0xae4ab0) at dtable.c:498
>>> #4 0x00007ffff6a964b9 in objc_send_initialize (object=<optimized out>) at
>>> dtable.c:693
>>> #5 0x00007ffff6a9e776 in objc_msg_lookup_internal (receiver=<optimized
>>> out>, selector=<optimized out>, sender=<optimized out>) at sendmsg2.c:73
>>> #6 objc_msg_lookup_sender (receiver=<optimized out>, selector=<optimized
>>> out>, sender=<optimized out>) at sendmsg2.c:171
>>> #7 0x00000000005a4678 in -[Move
>>> initWithAttack:withSoldier:againstTile:rolls:preAttackHP:preAttackPositions:preAttackBuffs:defenders:]
>>> (self=0x7fffdc862878, _cmd=0x9b5770, a=0x28e5908, s=0x2e0e478,
>>> #8 A bunch of my code all the way down to main.
>>> (gdb) thread 2
>>> [Switching to thread 2 (Thread 0x7fffe2612700 (LWP 8878))]
>>> #0 0x00007ffff65f9be4 in __lll_lock_wait () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> (gdb) bt
>>> #0 0x00007ffff65f9be4 in __lll_lock_wait () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #1 0x00007ffff65f5200 in _L_lock_928 () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #2 0x00007ffff65f5099 in pthread_mutex_lock () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #3 0x00007ffff6a95fb8 in dtable_for_class (cls=<optimized out>,
>>> cls=<optimized out>, cls=<optimized out>) at ./dtable.h:66
>>> #4 classHasDtable (cls=<optimized out>, cls=<optimized out>,
>>> cls=<optimized out>) at ./dtable.h:110
>>> #5 mergeMethodsFromSuperclass (super=0x7ffff7d1a8e0, cls=<optimized out>,
>>> methods=0x65ea8f0) at dtable.c:444
>>> #6 0x00007ffff6a9628d in add_method_list_to_class (cls=0x7ffff7d1a8e0,
>>> list=<optimized out>) at dtable.c:488
>>> #7 0x00007ffff6a9aaa6 in class_addMethod (cls=0x7ffff7d1a8e0,
>>> name=<optimized out>, imp=0x7ffff77eac30 <-[NSGDate
>>> timeIntervalSince1970]>, types=<optimized out>) at runtime.c:191
>>> #8 0x00007ffff794ec4f in GSObjCAddMethods (cls=0x7ffff7d1a8e0,
>>> list=0x65ea7a0, replace=0 '\000') at GSObjCRuntime.m:559
>>> #9 0x00007ffff794f566 in GSObjCAddClassBehavior (receiver=0x7ffff7d1a8e0,
>>> behavior=0x7ffff7d1a810) at GSObjCRuntime.m:902
>>> #10 0x00007ffff77eb116 in +[GSDateSingle initialize] (self=0x7ffff7d1a8e0,
>>> _cmd=<optimized out>) at NSDate.m:1517
>>> #11 0x00007ffff6a965c6 in objc_send_initialize (object=<optimized out>) at
>>> dtable.c:733
>>> #12 0x00007ffff6a96427 in objc_send_initialize (object=<optimized out>) at
>>> dtable.c:666
>>> #13 0x00007ffff6a9e776 in objc_msg_lookup_internal (receiver=<optimized
>>> out>, selector=<optimized out>, sender=<optimized out>) at sendmsg2.c:73
>>> #14 objc_msg_lookup_sender (receiver=<optimized out>, selector=<optimized
>>> out>, sender=<optimized out>) at sendmsg2.c:171
>>> #15 0x00007ffff77e975b in +[NSDate distantFuture] (self=0x7ffff7d1a740,
>>> _cmd=<optimized out>) at NSDate.m:985
>>> #16 0x00007ffff78af10d in +[NSRunLoop initialize] (self=0x7ffff7d5fc40,
>>> _cmd=<optimized out>) at NSRunLoop.m:697
>>> #17 0x00007ffff6a965c6 in objc_send_initialize (object=<optimized out>) at
>>> dtable.c:733
>>> #18 0x00007ffff6a9e776 in objc_msg_lookup_internal (receiver=<optimized
>>> out>, selector=<optimized out>, sender=<optimized out>) at sendmsg2.c:73
>>> #19 objc_msg_lookup_sender (receiver=<optimized out>, selector=<optimized
>>> out>, sender=<optimized out>) at sendmsg2.c:171
>>> #20 0x00000000004aa888 in -[DatabaseConnection runPingThread]
>>> (self=0x2a06698, _cmd=0x9b76b0) at Classes/Database/DatabaseConnection.m:120
>>> #21 0x00007ffff786a655 in -[NSObject performSelector:withObject:]
>>> (self=<optimized out>, _cmd=<optimized out>, aSelector=0x9b76b0,
>>> anObject=0x7fffe2610500) at NSObject.m:2001
>>> #22 0x00007ffff78e336e in -[NSThread main] (self=0x2a1c5b8, _cmd=<optimized
>>> out>) at NSThread.m:741
>>> #23 0x00007ffff78e3b05 in nsthreadLauncher (thread=0x2a1c5b8) at
>>> NSThread.m:807
>>> #24 0x00007ffff65f2efc in start_thread () from
>>> /lib/x86_64-linux-gnu/libpthread.so.0
>>> #25 0x00007ffff632d59d in clone () from /lib/x86_64-linux-gnu/libc.so.6
>>> #26 0x0000000000000000 in ?? ()
>>>
>>> Does anyone have any idea why this might be happening?
>>>
>>> Thanks
>>>
>>> Tom Davie
>>> _______________________________________________
>>> Discuss-gnustep mailing list
>>> Discuss-gnustep@gnu.org
>>> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
>>
>>
>> _______________________________________________
>> Discuss-gnustep mailing list
>> Discuss-gnustep@gnu.org
>> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
>
>
> -- Sent from my PDP-11
>