Skip to content

Fix memory leaks in ThreadBarriers.swift #12212

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

Merged
merged 5 commits into from
Jan 29, 2020

Conversation

chrisamanse
Copy link
Contributor

Fix memory leaks in PthreadBarriers.swift as indicated by FIXMEs.

// FIXME: leaking memory, leaking a mutex.
guard pthread_cond_init(barrier.pointee.cond!, nil) == 0 else {
barrier.pointee.cond!.deinitialize()
barrier.pointee.cond!.deallocate(capacity: 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mutex would also have to be cleaned up here. Maybe the whole thing belongs in a defer that just checks that barrier.pointee.count is non-zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or this can be merged into one guard statement:

guard pthread_mutex_init(barrier.pointee.mutex!, nil) == 0 && pthread_cond_init(barrier.pointee.cond!, nil) == 0 else {
  barrier.pointee.mutex!.deinitialize()
  barrier.pointee.mutex!.deallocate(capacity: 1)
  barrier.pointee.cond!.deinitialize()
  barrier.pointee.cond!.deallocate(capacity: 1)
  return -1
}

If one of them fails, both mutex and cond will be deallocated. What do you think?

Copy link
Contributor

@gparker42 gparker42 Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still doesn't call pthread_mutex_destroy when pthread_mutex_init succeeds but pthread_cond_init fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Updating code to destroy mutex when pthread_cond_init fails.

@CodaFi
Copy link
Contributor

CodaFi commented Nov 14, 2019

@airspeedswift Is this change still good to take (with some rebasing?)

if pthread_mutex_destroy(barrier.pointee.mutex!) != 0 {
// FIXME: leaking memory.
guard pthread_cond_destroy(barrier.pointee.cond!) == 0 &&
pthread_mutex_destroy(barrier.pointee.mutex!) == 0 else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failures when releasing resources kind of weird me out. This would leak or leave the barrier in an invalid state if pthread_cond_destroy fails.

According to the man page, this can only fail due to API abuse (either passing an invalid parameter, or trying to destroy it while it's in use by another thread). The callers of this function either fatalError or signal a test failure. I'm wondering if we should just not even try to pretend that this failure can be handled gracefully, and just abort here instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. The caller of this function in SwiftPrivatePthreadExtras.swift does fatalError when this returns -1. Should this function simply just return Void and fatalError in here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. If somebody wants to try to handle these errors gracefully one day, they can figure out how. No need to do that work now, only to immediately fatalError anyway.

Copy link
Contributor

@mikeash mikeash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@CodaFi
Copy link
Contributor

CodaFi commented Dec 9, 2019

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Dec 9, 2019

Build failed
Swift Test OS X Platform
Git Sha - 315f510

@swift-ci
Copy link
Contributor

swift-ci commented Dec 9, 2019

Build failed
Swift Test Linux Platform
Git Sha - 315f510

@chrisamanse
Copy link
Contributor Author

/home/buildnode/jenkins/workspace/swift-PR-Linux@2/branch-master/swift/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift:84:90: error: use of undeclared type '_stdlib_pthread_barrier_t'

My bad, that has been renamed to _stdlib_thread_barrier_t

@CodaFi
Copy link
Contributor

CodaFi commented Dec 9, 2019

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Dec 9, 2019

Build failed
Swift Test Linux Platform
Git Sha - 9e80f27

@theblixguy
Copy link
Collaborator

theblixguy commented Dec 10, 2019

Seems like you need to fix the call to pthread_mutex_init & pthread_cond_init:

/home/buildnode/jenkins/workspace/swift-PR-Linux@2/branch-master/swift/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift:85:50: error: missing argument for parameter #2 in call
17:55:49 guard pthread_mutex_init(barrier.pointee.mutex!) == 0 else {
17:55:49 ^
17:55:49 , <#UnsafePointer<pthread_mutexattr_t>?#>
17:55:49 SwiftGlibc.pthread_mutex_init:1:13: note: 'pthread_mutex_init' declared here
17:55:49 public func pthread_mutex_init(_ __mutex: UnsafeMutablePointer<pthread_mutex_t>, _ _mutexattr: UnsafePointer<pthread_mutexattr_t>!) -> Int32
17:55:49 ^
17:55:49 /home/buildnode/jenkins/workspace/swift-PR-Linux@2/branch-master/swift/stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift:88:48: error: missing argument for parameter #2 in call
17:55:49 guard pthread_cond_init(barrier.pointee.cond!) == 0 else {
17:55:49 ^
17:55:49 , <#UnsafePointer<pthread_condattr_t>?#>
17:55:49 SwiftGlibc.pthread_cond_init:1:13: note: 'pthread_cond_init' declared here
17:55:49 public func pthread_cond_init(
__cond: UnsafeMutablePointer<pthread_cond_t>, _ __cond_attr: UnsafePointer<pthread_condattr_t>!) -> Int32
17:55:49

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 9e80f27

@chrisamanse chrisamanse changed the title Fix memory leaks in PthreadBarriers.swift Fix memory leaks in ThreadBarriers.swift Dec 10, 2019
@theblixguy
Copy link
Collaborator

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 9e80f27

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 9e80f27

barrier.pointee.mutex!.deinitialize(count: 1)
barrier.pointee.mutex!.deallocate()
barrier.pointee.cond!.deinitialize(count: 1)
barrier.pointee.cond!.deallocate()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to exit the enclosing scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Rebasing isn't as straightforward as I thought, I'll try building locally this time

@chrisamanse
Copy link
Contributor Author

Ran ./utils/build-script --release-debuginfo locally. Seems to work, the command ended with:

[1775/1775][100%][1095.175s] Running utility command for swift-benchmark-macosx-x86_64

@CodaFi
Copy link
Contributor

CodaFi commented Jan 28, 2020

@swift-ci test

@CodaFi
Copy link
Contributor

CodaFi commented Jan 29, 2020

Thanks for sticking with us.

⛵️

@CodaFi CodaFi merged commit ffa6bf4 into swiftlang:master Jan 29, 2020
@drodriguez
Copy link
Contributor

Just a note, it broke Windows: https://ci-external.swift.org/job/oss-swift-windows-x86_64/2645/ (/cc @compnerd)

@chrisamanse
Copy link
Contributor Author

Just a note, it broke Windows: https://ci-external.swift.org/job/oss-swift-windows-x86_64/2645/ (/cc @compnerd)

Thanks for catching this one! I thought GitHub did a check for all platforms. I created this PR to fix it #29536

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants