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

Windows: the pointer passed to _swift_willThrow cannot be weakly referenced #62985

Open
grynspan opened this issue Jan 12, 2023 · 4 comments
Open
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. error handling Windows Platform: Windows

Comments

@grynspan
Copy link
Contributor

grynspan commented Jan 12, 2023

Description
On Windows, the pointer passed to _swift_willThrow does not appear to be a valid heap object, and attempting to weakly reference it causes a crash.

Steps to reproduce
Implement a program that sets the _swift_willThrow hook to a function like so:

struct S {
  weak var error: AnyObject
}

func swiftWillThrowHandler(_ errorAddress: UnsafeMutableRawPointer) {
  let errorObject = unsafeBitCast(errorAddress, to: AnyObject.self)
  var s = S()
  s.error = errorObject // crash
}

Expected behavior
As on Darwin/Linux, this pointer should be safe to bitcast to an object and then weakly reference.

Environment

  • Swift compiler version info compnerd.org Swift version 5.8-dev (LLVM ab856b0fa3177ee, Swift 71c62c0)
  • Deployment target: x86_64-unknown-windows-msvc
@grynspan grynspan added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. Windows Platform: Windows error handling triage needed This issue needs more specific labels labels Jan 12, 2023
@grynspan grynspan self-assigned this Jan 12, 2023
@grynspan
Copy link
Contributor Author

grynspan commented Jan 12, 2023

More detailed STR:

  1. Create a Swift package with a C++ target that declares _swift_setWillThrowHandler() appropriately. _swift_willThrow isn't getting exported correctly on Windows right now (runtime: export _swift_willThrow #62979), so you can't use it directly.
  2. Create a Swift test target in the package that imports the C++ target and calls _swift_setWillThrowHandler().
  3. In the closure you pass, bitcast (or Unmanaged-cast) the first argument from UnsafeMutableRawPointer to AnyObject.
  4. Assign the pointer to a weak reference somewhere. Crash should then happen.

@al45tair
Copy link
Contributor

Debugging this is proving somewhat tricky; the symbols in libswiftCore seem to be incomplete, or LLDB is buggy on Windows, or maybe both. It looks like it's actually blowing up in the second swift_release() call that gets generated at the end of the catch{} block. (Though the symbols are pointing to something else entirely, but they're clearly wrong.)

@grynspan
Copy link
Contributor Author

Perhaps this is failing on Darwin/Linux, but since their allocators may allow for more liberal use-after-free, it's less explosive? If so, adding a retain in the handling code manually might solve the problem (i.e. not a Swift bug.)

@grynspan
Copy link
Contributor Author

Trying at desk, just manually inserting a strong retain doesn't appear to prevent the crash.

@hborla hborla removed the triage needed This issue needs more specific labels label Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. error handling Windows Platform: Windows
Projects
None yet
Development

No branches or pull requests

3 participants