Hi David,

> While replacing the hash table, I managed to turn it into a reproduceable 
> fault on at least one machine.  The bug is quite subtle:
> 
> We have a map from objects to weak reference structures.
> The weak reference structure points to the object.
> When we delete the last weak reference, we delete the object from the map.
> We delete the object from the map using the object as the key.
> But by the time a weak reference is deallocated, its object pointer has been 
> zeroed...
> ...so we always remove a random element from the map and leave a dangling 
> pointer in the table.

Should this already be fixed on the latest libobjc2 master?

Going back to my original issue about NSHashTable with weak objects, I’m still 
seeing it crash with the latest libobjc2 master and also using the arc-cxx 
branch.

It reproduces quite easily with the following code (compiled with ARC), which 
crashes either directly in addObject: on the first invocation (when using 
weakObjectsHashTable), or in -allObjects on the second or third invocation 
(when using hashTableWithWeakObjects).

static __strong NSHashTable *_hashTable = nil;
static __strong NSObject *_test = nil;
- (void)testHashTable
{
    @autoreleasepool {
        if (!_hashTable) {
            _hashTable = [NSHashTable weakObjectsHashTable]; // or 
hashTableWithWeakObjects 
            _test = [NSObject new];
            [_hashTable addObject:_test]; // crash 1
        } else {
            _test = nil;
        }

        NSLog(@"HashTable %@ (_test: %@)", _hashTable.allObjects, _test); // 
crash 2
    }
}

Similarly, NSMapTable crashes as well in the second invocation of the following 
function, although I’m not sure if this is the same root cause as the hash 
table crash:

static __strong NSMapTable *_mapTable = nil;
static __strong NSObject *_test = nil;
- (void)testMapTable
{
    @autoreleasepool {
        if (!_mapTable) {
            _mapTable = [NSMapTable strongToWeakObjectsMapTable];
            _test = [NSObject new];
            [_mapTable setObject:_test forKey:@"test"];
        } else {
            NSLog(@"obj pre: %@", [_mapTable objectForKey:@"test"]); // crash!!!
            _test = nil;
            NSLog(@"obj post: %@", [_mapTable objectForKey:@"test"]);
        }

        NSLog(@"MapTable %@ (_test: %@)", _mapTable.dictionaryRepresentation, 
_test);
    }
}

I’m pasting the stack traces below. I’d appreciate if anyone can shed some 
light on this.

Thanks!
Frederik



NSHashTable crash using weakObjectsHashTable:

  * frame #0: 0xeca8c1d0 libart.so`art_sigsegv_fault
    frame #1: 0xeca8c774 libart.so`art::FaultManager::HandleFault(int, 
siginfo*, void*) + 372
    frame #2: 0xeca8c49b libart.so`art::art_fault_handler(int, siginfo*, void*) 
(.llvm.650222801) + 43
    frame #3: 0x625bd6af app_process32`___lldb_unnamed_symbol22$$app_process32 
+ 623
    frame #4: 0xefee7c50 libc.so`___lldb_unnamed_symbol2$$libc.so + 1
    frame #5: 0xd1e56762 libobjc.so`objc_msgSend at objc_msgSend.x86-32.S:120
    frame #6: 0xd14f69cd libgnustep-base.so`hashObject(item=0xcf40c100, 
size=0x00000000) at NSConcretePointerFunctions.m:126
    frame #7: 0xd1400a72 libgnustep-base.so`pointerFunctionsHash(PF=0xd0ea7900, 
item=0xcf40c100) at NSConcretePointerFunctions.h:180
    frame #8: 0xd13fd9b6 libgnustep-base.so`GSIMapBucketForKey(map=0xd0ea78d4, 
key=GSIMapKey @ 0xff99f2a4) at GSIMap.h:410
    frame #9: 0xd1400ce3 libgnustep-base.so`GSIMapAddNodeToMap(map=0xd0ea78d4, 
node=0xcf40c0f0) at GSIMap.h:453
    frame #10: 0xd13fcb64 libgnustep-base.so`GSIMapAddKey(map=0xd0ea78d4, 
key=GSIMapKey @ 0xff99f334) at GSIMap.h:1118
    frame #11: 0xd13fe82f libgnustep-base.so`-[NSConcreteHashTable 
addObject:](self=0xd0ea78d4, _cmd="C", anObject=0xd0efd14c) at 
NSConcreteHashTable.m:848
    frame #12: 0xd1e2e7ff libnative-lib.so`::-[ObjectiveCTest 
testHashTable](self=0xcf40c0e4, _cmd="V\x1c") at ObjectiveCTest.mm:78

NSHashTable crash using hashTableWithWeakObjects:

  * frame #0: 0xeca8c1d0 libart.so`art_sigsegv_fault
    frame #1: 0xeca8c774 libart.so`art::FaultManager::HandleFault(int, 
siginfo*, void*) + 372
    frame #2: 0xeca8c49b libart.so`art::art_fault_handler(int, siginfo*, void*) 
(.llvm.650222801) + 43
    frame #3: 0x625bd6af app_process32`___lldb_unnamed_symbol22$$app_process32 
+ 623
    frame #4: 0xefee7c50 libc.so`___lldb_unnamed_symbol2$$libc.so + 1
    frame #5: 0xd1ea975d libobjc.so`objc_msgSend at objc_msgSend.x86-32.S:120
    frame #6: 0xd13170bd libgnustep-base.so`-[GSInlineArray 
initWithObjects:count:](self=0xcf4fd184, _cmd="\xffffff81", objects=0xff99f320, 
count=1) at GSArray.m:420
    frame #7: 0xd131a41d libgnustep-base.so`-[GSPlaceholderArray 
initWithObjects:count:](self=0xcf4fd184, _cmd="\xffffff81", objects=0xff99f320, 
count=1) at GSArray.m:1199
    frame #8: 0xd13c2b80 libgnustep-base.so`-[NSConcreteHashTable 
allObjects](self=0xd0da9a14, _cmd="m\x02") at NSConcreteHashTable.m:875
    frame #9: 0xd1df7844 libnative-lib.so`::-[ObjectiveCTest 
testHashTable](self=0xcf391444, _cmd="V\x1c") at ObjectiveCTest.mm:84

NSMapTable crash:

  * frame #0: 0xeca8c1d1 libart.so`art_sigsegv_fault + 1
    frame #1: 0xeca8c774 libart.so`art::FaultManager::HandleFault(int, 
siginfo*, void*) + 372
    frame #2: 0xeca8c49b libart.so`art::art_fault_handler(int, siginfo*, void*) 
(.llvm.650222801) + 43
    frame #3: 0x625bd6af app_process32`___lldb_unnamed_symbol22$$app_process32 
+ 623
    frame #4: 0xefee7c50 libc.so`___lldb_unnamed_symbol2$$libc.so + 1
    frame #5: 0xd1e29c6d libobjc.so`::objc_retainAutoreleasedReturnValue(id) 
[inlined] isPersistentObject(obj=0xd0bfb27c) at arc.mm:291
    frame #6: 0xd1e29c66 libobjc.so`::objc_retainAutoreleasedReturnValue(id) 
[inlined] retain(obj=0xd0bfb27c) at arc.mm:296
    frame #7: 0xd1e29c66 libobjc.so`::objc_retainAutoreleasedReturnValue(id) 
[inlined] objc_retain(obj=0xd0bfb27c) at arc.mm:587
    frame #8: 0xd1e29c62 
libobjc.so`::objc_retainAutoreleasedReturnValue(obj=0xd0bfb27c) at arc.mm:581
    frame #9: 0xd1175a04 libnative-lib.so`::-[ObjectiveCTest 
testMapTable](self=0xcf66c064, _cmd="X\x1c") at ObjectiveCTest.mm:97

_______________________________________________
Discuss-gnustep mailing list
Discuss-gnustep@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to