Skip to content

[DiscardingTG] Undo pointer auth workaround; fix memory leaks #65613

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 7 commits into from
May 26, 2023

Conversation

ktoso
Copy link
Contributor

@ktoso ktoso commented May 3, 2023

There are two leaks in the group.

"first error task leaks"
(a) the "the first error task that we RETAIN" and later on use to automatically re-throw the "first thrown by a child task error" task was not released;

"all values leak"
(b) due to the "hot fix" for pointer auth #65220 done for rdar://107574868 where we changed the signature of addTask from ()->() (what it must be), to ()->T in order to work around pointer-auth issues we introduced a leak and ALL "discarded" values would be leaking since we would not release that T value. The correct way to solve this is to undo this workaround and use correct pointer auth, which this PR does.

We must fix the method signature and undo the hack which #65223 was.

Resolves: rdar://108829466

@ktoso ktoso added the concurrency Feature: umbrella label for concurrency language features label May 3, 2023
@ktoso ktoso marked this pull request as draft May 3, 2023 14:19
@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch 2 times, most recently from 8f660b4 to 72f14b5 Compare May 8, 2023 08:42
@ktoso
Copy link
Contributor Author

ktoso commented May 8, 2023

@swift-ci please smoke test

priority: TaskPriority? = nil,
operation: __owned @Sendable @escaping () async -> DiscardedResult
Copy link
Contributor Author

@ktoso ktoso May 16, 2023

Choose a reason for hiding this comment

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

This entire change to () -> T was a hotfix to temporarily unbreak but it is very wrong, we must get back to -> Void

✅ This fixes the (b) leaks the by undoing what introduced them in the first place.

@ktoso ktoso requested review from rjmccall and DougGregor May 16, 2023 08:52
@ktoso ktoso changed the title [DiscardingTG] Don't leak the first error task if we had to retain it [DiscardingTG] Don't leak the first error task if we retained it, and fix addTask signature to prevent leaks May 16, 2023
@ktoso
Copy link
Contributor Author

ktoso commented May 16, 2023

This is primarily stuck on pointer auth issues

@ktoso ktoso changed the title [DiscardingTG] Don't leak the first error task if we retained it, and fix addTask signature to prevent leaks [DiscardingTG] Undo pointer auth workaround, prevent leaks May 17, 2023
@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch 2 times, most recently from 8ba48c6 to 679a24a Compare May 24, 2023 10:57
@ktoso
Copy link
Contributor Author

ktoso commented May 24, 2023

@swift-ci please smoke test

@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch from 679a24a to ae58811 Compare May 24, 2023 15:28
@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch from ae58811 to 9f5a707 Compare May 24, 2023 16:04
resumeWaitingTask(readyErrorItem.getTask(), assumed,
/*hadErrorResult=*/true,
alreadyDecrementedStatus,
/*taskWasRetained=*/true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

hunting this one down took way too long... this is another case where we dequeue the retained error task and need to release it later

@ktoso ktoso marked this pull request as ready for review May 24, 2023 16:28
@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch from cdd127b to d82de55 Compare May 24, 2023 16:47
@ktoso
Copy link
Contributor Author

ktoso commented May 24, 2023

@swift-ci please smoke test

@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch 2 times, most recently from ce1c880 to 0b088e2 Compare May 24, 2023 16:58
@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch from 0b088e2 to 760cb44 Compare May 24, 2023 16:59
@ktoso ktoso changed the title [DiscardingTG] Undo pointer auth workaround, prevent leaks [DiscardingTG] Undo pointer auth workaround; fix memory leaks May 24, 2023
@@ -1369,6 +1383,11 @@ void TaskGroupBase::resumeWaitingTask(
// locks) because we know that the child task is completed and
// we can't be holding its locks ourselves.
_swift_taskGroup_detachChild(asAbstract(this), completedTask);
if (isDiscardingResults() && hadErrorResult && taskWasRetained) {
Copy link
Contributor Author

@ktoso ktoso May 24, 2023

Choose a reason for hiding this comment

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

✅ This fixes the (a) leaks because we need to balance the extra retain we do when we store the task for future use like this.

In other words, in this case of the discarding group we were missing this balancing release:

  // Retain the task while it is in the queue; it must remain alive until
  // it is found by poll.  This retain will be balanced by the release in waitAll.
  assert(hadErrorResult); // a discarding group may only store an errored task.
  swift_retain(completedTask);

@ktoso
Copy link
Contributor Author

ktoso commented May 24, 2023

@swift-ci please smoke test

std::tie(taskEntry, initialContextSize) =
TaskCreateFlags taskCreateFlags(rawTaskCreateFlags);

if (taskCreateFlags.isDiscardingTask()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the pointer auth dance for the nullary function type:

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

Okay. I think this seems reasonable.

@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

Thanks for review John!

A bit confused why same commits worked on Windows 5.9 but not here, in a lit configuration failure. Let's try again

@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

@swift-ci please smoke test Windows

@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

Silly main + windows only issue in lit config:

  File "C:/Users/swift-ci/jenkins/workspace/swift-PR-windows/swift\test\lit.cfg", line 2324, in <module>
    escape_for_substitute_captures(config.target_run_with_leaks))
AttributeError: 'TestingConfig' object has no attribute 'target_run_with_leaks'

Fixed I hope;

@swift-ci please smoke test and merge

@ktoso ktoso force-pushed the wip-discarding-error-task-leak branch from 68a5e09 to e3d4b55 Compare May 25, 2023 17:42
@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

@swift-ci please smoke test and merge

@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

Pending on the CI unbreak: #66138

@ktoso
Copy link
Contributor Author

ktoso commented May 25, 2023

@swift-ci please smoke test and merge

@swift-ci swift-ci merged commit 9698128 into swiftlang:main May 26, 2023
kateinoigakukun added a commit to swiftwasm/swift that referenced this pull request May 30, 2023
… Void closure

Since swiftlang#65613, DiscardingTG started to
accept `() -> Void` instead of `() -> T`, but it also changed the number
of arguments accepted by the closure from 3 to 2. So it should use
`non_future_adapter` instead of `future_adapter` to avoid runtime signature
mismatch.
kateinoigakukun added a commit to swiftwasm/swift that referenced this pull request May 30, 2023
… Void closure

Since swiftlang#65613, DiscardingTG started to
accept `() -> Void` instead of `() -> T`, but it also changed the number
of arguments accepted by the closure from 3 to 2. So it should use
`non_future_adapter` instead of `future_adapter` to avoid runtime signature
mismatch.
meg-gupta pushed a commit to meg-gupta/swift that referenced this pull request Jun 2, 2023
… Void closure

Since swiftlang#65613, DiscardingTG started to
accept `() -> Void` instead of `() -> T`, but it also changed the number
of arguments accepted by the closure from 3 to 2. So it should use
`non_future_adapter` instead of `future_adapter` to avoid runtime signature
mismatch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
concurrency Feature: umbrella label for concurrency language features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants