LeakSanitizer fixups for gcc and gnu runtime

This commit is contained in:
rfm 2024-11-30 18:23:48 +00:00
parent 7a8fb1a0e7
commit 018111efbb
12 changed files with 87 additions and 62 deletions

View file

@ -189,27 +189,8 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey";
- (void) dealloc
{
if (self == fh_stdin)
{
fh_stdin = nil;
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard input handle"];
}
if (self == fh_stdout)
{
fh_stdout = nil;
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard output handle"];
}
if (self == fh_stderr)
{
fh_stderr = nil;
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard error handle"];
}
DESTROY(address);
DESTROY(service);
DESTROY(protocol);
[self ignoreReadDescriptor];
[self ignoreWriteDescriptor];
/* If a read operation is in progress, we need to remove the handle
* from the run loop and destroy the operation information so that
@ -217,7 +198,6 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey";
*/
if (readInfo)
{
[self ignoreReadDescriptor];
DESTROY(readInfo);
}
@ -227,10 +207,34 @@ static NSString* NotificationKey = @"NSFileHandleNotificationKey";
*/
if ([writeInfo count] > 0)
{
[self ignoreWriteDescriptor];
[writeInfo removeAllObjects];
}
if (self == fh_stdin)
{
fh_stdin = nil;
DEALLOC
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard input handle"];
}
if (self == fh_stdout)
{
fh_stdout = nil;
DEALLOC
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard output handle"];
}
if (self == fh_stderr)
{
fh_stderr = nil;
DEALLOC
[NSException raise: NSGenericException
format: @"Attempt to deallocate standard error handle"];
}
DESTROY(address);
DESTROY(service);
DESTROY(protocol);
/* Finalize *after* ending read and write operations so that, if the
* file handle needs to be closed, we don't generate any notifications
* containing the deallocated object. Thanks to David for this fix.

View file

@ -89,7 +89,7 @@ setup()
classTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 128);
infoTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 1024);
NSObjectMapValueCallBacks, 1024);
dependentKeyTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSOwnedPointerMapValueCallBacks, 128);
baseClass = NSClassFromString(@"GSKVOBase");
@ -111,9 +111,9 @@ setup()
*/
@interface GSKVOReplacement : NSObject
{
Class original; /* The original class */
Class replacement; /* The replacement class */
NSMutableSet *keys; /* The observed setter keys */
Class original; /* The original class */
Class replacement; /* The replacement class */
NSMutableDictionary *keys; /* The observed setter keys */
}
- (id) initWithClass: (Class)aClass;
- (void) overrideSetterFor: (NSString*)aKey;
@ -475,16 +475,16 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
replacement = NSClassFromString(name);
GSObjCAddClassBehavior(replacement, baseClass);
/* Create the set of setter methods overridden.
/* Create the dictionary of setter methods overridden.
*/
keys = [NSMutableSet new];
keys = [NSMutableDictionary new];
return self;
}
- (void) overrideSetterFor: (NSString*)aKey
{
if ([keys member: aKey] == nil)
if ([keys objectForKey: aKey] == nil)
{
NSMethodSignature *sig;
SEL sel;
@ -493,9 +493,13 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
NSString *suffix;
NSString *a[2];
unsigned i;
BOOL found = NO;
NSString *tmp;
unichar u;
unichar u;
#if defined(USE_LIBFFI)
GSCodeBuffer *b = nil;
#endif
suffix = [aKey substringFromIndex: 1];
u = uni_toupper([aKey characterAtIndex: 0]);
@ -610,10 +614,7 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
else
{
#if defined(USE_LIBFFI)
GSCodeBuffer *b;
b = cifframe_closure(sig, cifframe_callback);
[b retain];
imp = [b executable];
#else
imp = 0;
@ -640,7 +641,16 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
}
if (found == YES)
{
[keys addObject: aKey];
id info = nil;
#if defined(USE_LIBFFI)
info = b; // Need to safe the code buffer
#endif
if (nil == info)
{
info = [NSNull null];
}
[keys setObject: info forKey: aKey];
}
else
{
@ -648,15 +658,15 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
if (depKeys)
{
NSMapEnumerator enumerator = NSEnumerateMapTable(depKeys);
NSString *mainKey;
NSHashTable *dependents;
NSMapEnumerator enumerator = NSEnumerateMapTable(depKeys);
NSString *mainKey;
NSHashTable *dependents;
while (NSNextMapEnumeratorPair(&enumerator, (void **)(&mainKey),
(void**)&dependents))
{
NSHashEnumerator dependentKeyEnum;
NSString *dependentKey;
NSHashEnumerator dependentKeyEnum;
NSString *dependentKey;
if (!dependents) continue;
dependentKeyEnum = NSEnumerateHashTable(dependents);
@ -667,7 +677,7 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
{
[self overrideSetterFor: mainKey];
// Mark the key as used
[keys addObject: aKey];
[keys setObject: [NSNull null] forKey: aKey];
found = YES;
}
}
@ -1542,6 +1552,7 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
{
info = [[GSKVOInfo alloc] initWithInstance: self];
[self setObservationInfo: info];
RELEASE(info);
object_setClass(self, [r replacement]);
}
@ -1591,7 +1602,6 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
* turn off key-value-observing for it.
*/
object_setClass(self, [self class]);
IF_NO_ARC(AUTORELEASE(info);)
[self setObservationInfo: nil];
}
if ([aPath rangeOfString:@"."].location != NSNotFound)
@ -1618,7 +1628,6 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
* turn off key-value-observing for it.
*/
object_setClass(self, [self class]);
IF_NO_GC(AUTORELEASE(info);)
[self setObservationInfo: nil];
}
[kvoLock unlock];

View file

@ -79,6 +79,7 @@ static int c1load = 0;
int
main(int argc, char *argv[])
{
ENTER_POOL
id obj;
Class cls;
Class meta;
@ -294,6 +295,7 @@ main(int argc, char *argv[])
PASS([NSStringFromSelector(sel) isEqual: @"xxxyyy_odd_name_xxxyyy"],
"NSStringFromSelector() works for existing selector");
LEAVE_POOL
return 0;
}

View file

@ -10,9 +10,9 @@ int main()
val1 = @"Hello";
val2 = @"A Goodbye";
val3 = @"Testing all strings";
vals1 = [[[NSArray arrayWithObject:val1] arrayByAddingObject:val2] retain];
vals2 = [[vals1 arrayByAddingObject:val2] retain];
vals3 = [[vals1 arrayByAddingObject:val3] retain];
vals1 = [[NSArray arrayWithObject:val1] arrayByAddingObject:val2];
vals2 = [vals1 arrayByAddingObject:val2];
vals3 = [vals1 arrayByAddingObject:val3];
obj = [NSArray new];
arr = obj;

View file

@ -45,11 +45,13 @@
int main(int argc, char** argv)
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
ENTER_POOL
TestClass *testClass = [[TestClass new] autorelease];
[testClass runTest];
[pool release];
PASS(1, "Destroying pools in the wrong order didn't break anything...");
LEAVE_POOL
ENTER_POOL
PASS(1, "Destroying pools in the wrong order didn't break anything...")
LEAVE_POOL
return 0;
}

View file

@ -6,7 +6,7 @@
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
START_SET("basic")
char *str1, *str2;
NSData *data1, *data2;
NSMutableData *mutable;
@ -70,12 +70,12 @@ int main()
&& [data2 bytes] == str1,
"+dataWithBytesNoCopy:length:freeWhenDone: works")
[arp release]; arp = nil;
END_SET("basic")
{
START_SET("segault check")
BOOL didNotSegfault = YES;
PASS(didNotSegfault, "+dataWithBytesNoCopy:length:freeWhenDone:NO doesn't free memory");
}
END_SET("segfault check")
START_SET("deallocator blocks")
@ -133,6 +133,6 @@ int main()
# else
SKIP("No Blocks support in the compiler.")
# endif
END_SET("deallocator blocks")
END_SET("deallocator blocks")
return 0;
}

View file

@ -5,7 +5,7 @@ id a,b,c;
int main(void)
{
NSAutoreleasePool *p = [NSAutoreleasePool new];
ENTER_POOL
NSFileHandle *a;
NSFileHandle *b;
NSFileHandle *c;
@ -19,6 +19,6 @@ int main(void)
PASS_EXCEPTION([b release], NSGenericException, "Cannot dealloc stdout");
PASS_EXCEPTION([c release], NSGenericException, "Cannot dealloc stderr");
[p drain];
LEAVE_POOL
return 0;
}

View file

@ -186,6 +186,7 @@ int main()
NSData *dat1 = [mgr contentsAtPath: @"NSFMFile"];
str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
PASS([str1 isEqualToString: str2], "NSFileManager file contents match");
DESTROY(str2);
}
[NSThread sleepForTimeInterval: 1.0]; // So date of file is clearly in past
[handler reset];
@ -198,6 +199,7 @@ int main()
NSData *dat1 = [mgr contentsAtPath: @"NSFMCopy"];
str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
PASS([str1 isEqual: str2],"NSFileManager copied file contents match");
DESTROY(str2);
}
NSDictionary *oa = [mgr fileAttributesAtPath: @"NSFMFile" traverseLink: NO];
NSDictionary *na = [mgr fileAttributesAtPath: @"NSFMCopy" traverseLink: NO];
@ -245,6 +247,7 @@ int main()
NSData *dat1 = [mgr contentsAtPath: @"NSFMMove"];
str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
PASS([str1 isEqualToString: str2],"NSFileManager moved file contents match")
DESTROY(str2);
}
PASS(![mgr copyPath: @"NSFMFile"

View file

@ -5,7 +5,7 @@
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
ENTER_POOL
NSIndexPath *index1;
NSIndexPath *index2;
NSUInteger i0[2];
@ -70,10 +70,11 @@ int main()
PASS([index2 compare: index1] == NSOrderedDescending,
"longer index2 comparison the other way works");
[arp release]; arp = nil;
{
LEAVE_POOL
START_SET("segfault")
BOOL didNotSegfault = YES;
PASS(didNotSegfault, "+indexPathWithIndex: doesn't mess up memory");
}
END_SET("segfault")
return 0;
}

View file

@ -5,8 +5,10 @@
int main()
{
ENTER_POOL
Class theClass = NSClassFromString(@"NSObject");
PASS(theClass == [NSObject class],
"'NSObject' %s","uses +class to return self");
LEAVE_POOL
return 0;
}

View file

@ -124,8 +124,8 @@ static NSLock *lock = nil;
static NSMutableArray *list = nil;
+ (void) initialize
{
lock = [NSLock new];
list = [NSMutableArray new];
if (nil == lock) lock = [NSLock new];
if (nil == list) list = [NSMutableArray new];
}
- (void) main
{

2
Tests/base/lsan.txt Normal file
View file

@ -0,0 +1,2 @@
leak:__objc_exec_class
leak:class_addMethod