blob: e8d69739c57d4ed6715fd9408afed18fa3bb17b1 [file] [log] [blame]
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "LeakChecker.h"
#import <Foundation/Foundation.h>
#include <unistd.h> // For getpid()
@interface LeakChecker : NSObject
- (BOOL)hasMemoryLeaks;
@end
@implementation LeakChecker
- (BOOL)hasMemoryLeaks
{
#if TARGET_OS_OSX
pid_t pid = getpid();
auto * pidString = [NSString stringWithFormat:@"%d", pid];
auto * task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/leaks";
task.arguments = @[ pidString ];
auto * pipe = [NSPipe pipe];
task.standardOutput = pipe;
task.standardError = pipe;
NSFileHandle * fileHandle = [pipe fileHandleForReading];
[task launch];
[task waitUntilExit];
int exitCode = [task terminationStatus];
if (exitCode) {
NSData * data = [fileHandle readDataToEndOfFile];
NSString * output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", output);
return YES;
}
#else
NSLog(@"Running leaks as a task is supported on this platform.");
#endif // TARGET_OS_OSX
return NO;
}
@end
int ConditionalLeaksCheck(int exitCode)
{
#ifdef DFT_ENABLE_LEAK_CHECKING
@autoreleasepool {
auto * leakChecker = [[LeakChecker alloc] init];
if ([leakChecker hasMemoryLeaks]) {
return EXIT_FAILURE;
}
}
#endif // DFT_ENABLE_LEAK_CHECKING
return exitCode;
}