Skip to content

Commit

Permalink
LeakSanitizer fixups for gcc and gnu runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
rfm committed Nov 30, 2024
1 parent 7a8fb1a commit 018111e
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 59 deletions.
44 changes: 24 additions & 20 deletions Source/GSFileHandle.m
Original file line number Diff line number Diff line change
Expand Up @@ -189,48 +189,52 @@ + (id) allocWithZone: (NSZone*)z

- (void) dealloc
{
[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
* we won't generate a notification about it failing.
*/
if (readInfo)
{
DESTROY(readInfo);
}

/* If a write operation is in progress, we need to remove the handle
* from the run loop and destroy the operation information so that
* we won't generate a notification about it failing.
*/
if ([writeInfo count] > 0)
{
[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);

/* If a read operation is in progress, we need to remove the handle
* from the run loop and destroy the operation information so that
* we won't generate a notification about it failing.
*/
if (readInfo)
{
[self ignoreReadDescriptor];
DESTROY(readInfo);
}

/* If a write operation is in progress, we need to remove the handle
* from the run loop and destroy the operation information so that
* we won't generate a notification about it failing.
*/
if ([writeInfo count] > 0)
{
[self ignoreWriteDescriptor];
[writeInfo removeAllObjects];
}

/* 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.
Expand Down
49 changes: 29 additions & 20 deletions Source/NSKeyValueObserving.m
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
classTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 128);
infoTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 1024);
NSObjectMapValueCallBacks, 1024);
dependentKeyTable = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSOwnedPointerMapValueCallBacks, 128);
baseClass = NSClassFromString(@"GSKVOBase");
Expand All @@ -111,9 +111,9 @@ @interface GSKVOBase : NSObject
*/
@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;
Expand Down Expand Up @@ -475,16 +475,16 @@ - (id) initWithClass: (Class)aClass
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;
Expand All @@ -493,9 +493,13 @@ - (void) overrideSetterFor: (NSString*)aKey
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]);
Expand Down Expand Up @@ -610,10 +614,7 @@ - (void) overrideSetterFor: (NSString*)aKey
else
{
#if defined(USE_LIBFFI)
GSCodeBuffer *b;

b = cifframe_closure(sig, cifframe_callback);
[b retain];
imp = [b executable];
#else
imp = 0;
Expand All @@ -640,23 +641,32 @@ - (void) overrideSetterFor: (NSString*)aKey
}
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
{
NSMapTable *depKeys = NSMapGet(dependentKeyTable, original);

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);
Expand All @@ -667,7 +677,7 @@ - (void) overrideSetterFor: (NSString*)aKey
{
[self overrideSetterFor: mainKey];
// Mark the key as used
[keys addObject: aKey];
[keys setObject: [NSNull null] forKey: aKey];
found = YES;
}
}
Expand Down Expand Up @@ -1542,6 +1552,7 @@ - (void) addObserver: (NSObject*)anObserver
{
info = [[GSKVOInfo alloc] initWithInstance: self];
[self setObservationInfo: info];
RELEASE(info);
object_setClass(self, [r replacement]);
}

Expand Down Expand Up @@ -1591,7 +1602,6 @@ - (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath
* 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)
Expand All @@ -1618,7 +1628,6 @@ - (void) removeObserver: (NSObject*)anObserver
* turn off key-value-observing for it.
*/
object_setClass(self, [self class]);
IF_NO_GC(AUTORELEASE(info);)
[self setObservationInfo: nil];
}
[kvoLock unlock];
Expand Down
2 changes: 2 additions & 0 deletions Tests/base/Functions/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ - (const char *) sel2
int
main(int argc, char *argv[])
{
ENTER_POOL
id obj;
Class cls;
Class meta;
Expand Down Expand Up @@ -294,6 +295,7 @@ - (const char *) sel2
PASS([NSStringFromSelector(sel) isEqual: @"xxxyyy_odd_name_xxxyyy"],
"NSStringFromSelector() works for existing selector");

LEAVE_POOL
return 0;
}

6 changes: 3 additions & 3 deletions Tests/base/NSArray/general.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 5 additions & 3 deletions Tests/base/NSAutoreleasePool/autorelease_eh.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ - (void) exceptionThrowingMethod

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;
}
10 changes: 5 additions & 5 deletions Tests/base/NSData/general.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
START_SET("basic")
char *str1, *str2;
NSData *data1, *data2;
NSMutableData *mutable;
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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;
}
4 changes: 2 additions & 2 deletions Tests/base/NSFileHandle/singleton.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

int main(void)
{
NSAutoreleasePool *p = [NSAutoreleasePool new];
ENTER_POOL
NSFileHandle *a;
NSFileHandle *b;
NSFileHandle *c;
Expand All @@ -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;
}
3 changes: 3 additions & 0 deletions Tests/base/NSFileManager/general.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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];
Expand Down Expand Up @@ -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"
Expand Down
9 changes: 5 additions & 4 deletions Tests/base/NSIndexPath/general.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
ENTER_POOL
NSIndexPath *index1;
NSIndexPath *index2;
NSUInteger i0[2];
Expand Down Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions Tests/base/NSObject/test00.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 2 additions & 2 deletions Tests/base/NSOperation/threads.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ @implementation OpOrder
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
{
Expand Down
2 changes: 2 additions & 0 deletions Tests/base/lsan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
leak:__objc_exec_class
leak:class_addMethod

0 comments on commit 018111e

Please sign in to comment.