Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-5280] Foundation: FileHandle.swift: memory leak in _readDataOfLength #4285

Closed
swift-ci opened this issue Jun 22, 2017 · 6 comments
Closed

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-5280
Radar rdar://problem/33145849
Original Reporter denisnone (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Ubuntu 16.04

Additional Detail from JIRA
Votes 1
Component/s Foundation
Labels Bug, Leak, Linux
Assignee mattrajca (JIRA)
Priority Medium

md5: 6496dc2585e2a226ba7a13c8978d8c65

Issue Description:

internal func readDataOfLength( length: Int, untilEOF: Bool) -> Data

Leaks memory when returns data.

        if (0 == total) {
            free(dynamicBuffer)
        }
        
        if total > 0 {
            let bytePtr = dynamicBuffer!.bindMemory(to: UInt8.self, capacity: total)
            return Data(bytesNoCopy: bytePtr, count: total, deallocator: .none)
        }

I suppose it should be:

return Data(bytesNoCopy: bytePtr, count: total, deallocator: .free)

On Apple platforms it doesn't leak because Foundation returns autoreleasing NSData, it automatically gets added to RunLoop's autorelease pool. Or if you have your own local autorelease pool to destroy object earlier.

@swift-ci
Copy link
Contributor Author

Comment by Denis S (JIRA)

This bug is especially important when you read from an infinite communication channel like tty, it eats all the memory.

@huonw
Copy link
Mannequin

huonw mannequin commented Jul 6, 2017

@swift-ci create

@swift-ci
Copy link
Contributor Author

Comment by Denis S (JIRA)

Hi! Any update on this? I've just hit it one more time. File reading is a basic operation in OS, it should be safe.

@swift-ci
Copy link
Contributor Author

swift-ci commented Aug 7, 2017

Comment by Andrew Wagner (JIRA)

I am using the following workaround for now:

extension FileHandle { 
    public func safelyReadData(ofLength length: Int) -> Data {
        #if os(Linux)
            var leakingData = self.readData(ofLength: length)
            var data: Data = Data() 
            if leakingData.count > 0 { 
                leakingData.withUnsafeMutableBytes({ (bytes: UnsafeMutablePointer<UInt8>) -> Void in
                    data = Data(bytesNoCopy: bytes, count: leakingData.count, deallocator: .free)
                })
            } 
            return data
        #else
            return self.readData(ofLength: length)
        #endif
    }
}

On Linux it is creating a copy of the data that will actually free the underlying data when deallocated.

@swift-ci
Copy link
Contributor Author

swift-ci commented Aug 9, 2017

Comment by Denis S (JIRA)

Yes, I did similar extension as you with ".free" deallocator. Thanks to Swift's Extension mechanism that allows us to plug leaks and bugs as soon as possible.

@swift-ci
Copy link
Contributor Author

Comment by Matt Rajca (JIRA)

#1155

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant