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

XCTestDynamicOverlay: prefer delay loading XCTFail #73

Merged
merged 3 commits into from
Jan 17, 2024

Conversation

compnerd
Copy link
Contributor

Similar to the ObjC XCTest, prefer to delay load the XCTest runtime. This is likely to fail on release distributions as XCTest is a developer component. However, if it is available in the library search path on (non-Darwin) Unix or in Path on Windows, it will be used.

Windows does not (yet) ship a static XCTest library. On Linux, it is unclear whether the linkage is dynamic or static, so we perform a little trick. We pass RTLD_NOLOAD to dlopen which will get a handle to libXCTest.so if it is currently loaded in the address space but not load the library if not already there. In such a case, it will return NULL. In such a case, we resort to looking within the main binary (assuming that XCTest may have been statically linked).

For both platforms, if we do not find the symbol from XCTest, we will proceed to simply use the fallback path.

Note that both GetProcAddress and dlsym do not know how to cast the resulting pointer to indicate the calling convention. As a result, we rely on the use of unsafeBitCast to restore the calling convention to swiftcall. To completely avoid the undefined behaviour here, we would need to resort to C to perform the cast as these methods return type erased pointers (i.e. void *).

@stephencelis
Copy link
Member

@compnerd Thanks for looking into this and for the PR! It does look like Ubuntu and Wasm aren't happy with the changes, though, at the moment. We have a Makefile that runs a failing test to expect the failure (since XCTExpectFailure wasn't available on those platforms), but it is no longer failing, which leads me to believe the dynamic loading isn't working.

@compnerd
Copy link
Contributor Author

Let me see if I can figure out what is going on.

Similar to the ObjC XCTest, prefer to delay load the XCTest runtime.
This is likely to fail on release distributions as XCTest is a developer
component. However, if it is available in the library search path on
(non-Darwin) Unix or in `Path` on Windows, it will be used.

Windows does not (yet) ship a static XCTest library. On Linux, it is
unclear whether the linkage is dynamic or static, so we perform a little
trick. We pass `RTLD_NOLOAD` to `dlopen` which will get a handle to
`libXCTest.so` if it is currently loaded in the address space but not
load the library if not already there. In such a case, it will return
`NULL`. In such a case, we resort to looking within the main binary
(assuming that XCTest may have been statically linked).

For both platforms, if we do not find the symbol from XCTest, we will
proceed to simply use the fallback path.

Note that both `GetProcAddress` and `dlsym` do not know how to cast the
resulting pointer to indicate the calling convention. As a result, we
rely on the use of `unsafeBitCast` to restore the calling convention to
`swiftcall`. To completely avoid the undefined behaviour here, we would
need to resort to C to perform the cast as these methods return type
erased pointers (i.e. `void *`).
@stephencelis
Copy link
Member

@compnerd Looks like just one small compiler error in the Windows debug branch. I pushed an update to Wasm's CI to get it building in case you force push again be sure not to lose it 😄

Add a cast for Windows after the last round of tweaks for Linux.
Additionally, use `LoadLibraryA` instead of `LoadLibraryW` as we know
that the library name is ASCII compliant and the array buffer does not
work with `LoadLibraryW` and would require pulling in Foundation.
@compnerd
Copy link
Contributor Author

@stephencelis - should be good to go now.

Copy link
Member

@stephencelis stephencelis left a comment

Choose a reason for hiding this comment

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

Looks good, thanks so much!

@stephencelis stephencelis merged commit 89a3632 into pointfreeco:main Jan 17, 2024
5 checks passed
@compnerd compnerd deleted the delayed branch January 22, 2024 19:20
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.

2 participants