Skip to content

Factory tests fail on Linux #49

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

Open
robertjpayne opened this issue Aug 3, 2019 · 3 comments
Open

Factory tests fail on Linux #49

robertjpayne opened this issue Aug 3, 2019 · 3 comments

Comments

@robertjpayne
Copy link

I'm not 100% sure why but

testClass and testGenericClass are not part of the XCTestManifest and thus don't get run on Linux.

The first testClass fails on Linux with a segfault.

Are these methods supposed to work on Linux or not?

@wickwirew
Copy link
Owner

Not sure why either, ill have to take a look. Support was added last release to get those working on linux.

What swift version are you using btw?

@Supereg
Copy link
Contributor

Supereg commented Jun 30, 2021

Is there any progress on this issue?

@Supereg
Copy link
Contributor

Supereg commented Jul 1, 2021

Alright, so. I did some digging.

First of all, what I already uncovered yesterday was, that the createInstance call fails within the swift_allocObject call made to the Swift Runtime itself:

func buildClass(type: Any.Type) throws -> Any {
var md = ClassMetadata(type: type)
let info = md.toTypeInfo()
let metadata = unsafeBitCast(type, to: UnsafeRawPointer.self)
let instanceSize = Int32(md.pointer.pointee.classSize)
let alignment = Int32(md.alignment)
guard let value = swift_allocObject(metadata, instanceSize, alignment) else {

Refer to the exemplary backtrace:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f5102e2ec02 in swift_allocObject () from /usr/lib/swift/linux/libswiftCore.so
#1  0x00005611ac5c3830 in $s7Runtime10buildClass4typeypypXp_tKF (type=...) at /usr/src/Runtime/Sources/Runtime/Factory/Factory.swift:67
#2  0x00005611ac5c3159 in $s7Runtime14createInstance2of11constructorypypXp_ypAA12PropertyInfoVKcSgtKF (type=..., constructor=...) at /usr/src/Runtime/Sources/Runtime/Factory/Factory.swift:46
#3  0x00005611ac5c2c9b in $s7Runtime14createInstance11constructorxypAA12PropertyInfoVKcSg_tKlF (constructor=...) at /usr/src/Runtime/Sources/Runtime/Factory/Factory.swift:28
#4  0x00005611ac5e5b50 in $s12RuntimeTests07FactoryB0C9testClassyyKF (self=...) at /usr/src/Runtime/Tests/RuntimeTests/FactoryTests.swift:59
#5  0x00005611ac612245 in $s12RuntimeTests07FactoryB0C05__allB0SaySS_yyKcACctGvpZfiyyKcACcfu3_yyKcfu4_ () at /usr/src/Runtime/Tests/RuntimeTests/XCTestManifests.swift:7
#6  0x00005611ac61acdf in $s12RuntimeTests07FactoryB0C05__allB0SaySS_yyKcACctGvpZfiyyKcACcfu3_yyKcfu4_TA ()
#7  0x00005611ac5e41af in $ss5Error_pIegzo_ytsAA_pIegrzo_TR ()
#8  0x00005611ac5e8c74 in $ss5Error_pIegzo_ytsAA_pIegrzo_TRTA ()
#9  0x00007f5101ffda5c in $syts5Error_pIegrzo_sAA_pIegzo_TRTA () from /usr/lib/swift/linux/libXCTest.so
#10 0x00007f5101ffd8b8 in $s6XCTest4test33_3BE257A46ADB477C7BF2D39968B39F9DLLyyAA0A4CaseCKcyyKcxcAERbzlFyAEKcfU_TA () from /usr/lib/swift/linux/libXCTest.so
#11 0x00007f5101ffd84f in $s6XCTest0A4CaseCs5Error_pIeggzo_ACytsAD_pIegnrzo_TRTA () from /usr/lib/swift/linux/libXCTest.so
#12 0x00007f5101ffdb16 in $s6XCTest0A4CaseCs5Error_pIeggzo_ACytsAD_pIegnrzo_TRTA.19 () from /usr/lib/swift/linux/libXCTest.so
#13 0x00007f5101fef528 in $s6XCTest0A4CaseCyts5Error_pIegnrzo_ACsAD_pIeggzo_TRTA () from /usr/lib/swift/linux/libXCTest.so
#14 0x00007f5101ffc1f8 in $s6XCTest0A4CaseC10invokeTestyyF () from /usr/lib/swift/linux/libXCTest.so
#15 0x00007f5101ffbfe3 in $s6XCTest0A4CaseC7performyyAA0A3RunCF () from /usr/lib/swift/linux/libXCTest.so
#16 0x00007f5101fff880 in $s6XCTestAAC3runyyF () from /usr/lib/swift/linux/libXCTest.so
#17 0x00007f5101ffddaf in $s6XCTest0A5SuiteC7performyyAA0A3RunCF () from /usr/lib/swift/linux/libXCTest.so
#18 0x00007f5101fff880 in $s6XCTestAAC3runyyF () from /usr/lib/swift/linux/libXCTest.so
#19 0x00007f5101ffddaf in $s6XCTest0A5SuiteC7performyyAA0A3RunCF () from /usr/lib/swift/linux/libXCTest.so
#20 0x00007f5101fff880 in $s6XCTestAAC3runyyF () from /usr/lib/swift/linux/libXCTest.so
#21 0x00007f5101ffac24 in $s6XCTest7XCTMain_9arguments9observerss5NeverOSayAA0A4CaseCm04testF5Class_SaySS_yAHKctG8allTeststG_SaySSGSayAA0A11Observation_pGtF () from /usr/lib/swift/linux/libXCTest.so
#22 0x00007f5101ffa5eb in $s6XCTest7XCTMainys5NeverOSayAA0A4CaseCm04testD5Class_SaySS_yAFKctG8allTeststGF () from /usr/lib/swift/linux/libXCTest.so
#23 0x00005611ac5e3d21 in main () at /usr/src/Runtime/Tests/LinuxMain.swift:8

Looking at the implementation two things caught my eye:

  • The header file docs which state that the requiredAlignmentMask parameter "always one less than a power of 2 that's at least alignof(void*)"
  • The isAlignmentMask assertion (implemented here) which enforces that restriction.

As you can see in the code snippet above, we pass md.alignment to the Swift Runtime call, which follows the following calculations:

var alignment: Int {
return (valueWitnessTable.pointee.flags & ValueWitnessFlags.alignmentMask) + 1
}

In the example of the FactoryTests.testClass() case the value passes is 8 which does not satisfy that requirement stated in the docs. Subtracting 1 agains resolves the issue and the test cases pass successfully. Not sure why it worked on macOS though (maybe some sort of compatibility layer).
In any case, instead of using md.alignment and according to the Class Metadata Layout docs we also can just use the ClassMetadataLayout.instanceAlignmentMask property:

var instanceAlignmentMask: UInt16

To my tests it holds the expected value.

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

No branches or pull requests

3 participants