Brightify/Cuckoo

Segmentation fault 11 with closure and Alamofire?

arnlen opened this issue · 4 comments

Source to test:

// class ApiTools
// [...]

func callApi(with router: URLRequestConvertible,
            from caller: ApiCompatibleProtocol,
            responseStatusCode: Int,
            _ redirectionClosure: @escaping () -> ()) {
  
  Alamofire.request(router)
      .validate(statusCode: [responseStatusCode])
      .validate(contentType: ["application/json"])
      .responseJSON { response in
          switch response.result {
          case .success:
              let json = response.result.value as? [String: Any]
              caller.onSuccessClosure(json!, redirectionClosure)
              
          case .failure(let error):
              // [...]
          }
  }
}

Test code:

let mock = MockApiTools()
        
stub(mock) { stub in
    when(stub.callApi(with: SessionRouter.signin(parameters) as URLRequestConvertible,
        from: sessionService,
        responseStatusCode: 201,
        {})
    )
}

Boom error:

CompileSwift normal x86_64 <app_path>/AppTests/SessionServiceTests.swift
cd <app_path>
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c <app_path>/AppTests/Alamofire.swift <app_path>/AppTests/GeneratedMocks.swift <app_path>/AppTests/CurrentUser.swift <app_path>/AppTests/CameraViewControllerSpec.swift -primary-file <app_path>/AppTests/SessionServiceTests.swift <app_path>/AppTests/UserTests.swift -target x86_64-apple-ios10.3 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk -I <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/Cuckoo -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/Alamofire -F /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path <user_path>/Library/Developer/Xcode/DerivedData/ModuleCache -D DEBUG -D COCOAPODS -serialize-debugging-options -serialize-debugging-options -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/swift-overrides.hmap -Xcc -iquote -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-generated-files.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-own-target-headers.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/all-product-headers.yaml -Xcc -iquote -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-project-headers.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/include -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/DerivedSources/x86_64 -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -DCOCOAPODS=1 -Xcc -working-directory<app_path> -emit-module-doc-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests~partial.swiftdoc -serialize-diagnostics-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.dia -Onone -module-name AppTests -emit-module-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests~partial.swiftmodule -emit-dependencies-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.d -emit-reference-dependencies-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.swiftdeps -o <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.o

0  swift                    0x00000001053084f7 PrintStackTraceSignalHandler(void*) + 39
1  swift                    0x00000001053079a6 SignalHandler(int) + 646
2  libsystem_platform.dylib 0x00007fff97d4db3a _sigtramp + 26
3  libsystem_platform.dylib 0x000000010622f400 _sigtramp + 1850611936
4  swift                    0x0000000102969e7c swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 124
5  swift                    0x000000010297ced6 swift::Lowering::SILGenFunction::emitIgnoredExpr(swift::Expr*) + 598
6  swift                    0x00000001029c6e4a swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 14554
7  swift                    0x0000000102986509 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 409
8  swift                    0x000000010290789b swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 1867
9  swift                    0x00000001029068a2 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 642
10 swift                    0x00000001029cbefb (anonymous namespace)::SILGenType::emitType() + 971
11 swift                    0x00000001029cbacd swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 29
12 swift                    0x0000000102913ecb swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1483
13 swift                    0x0000000102915aa9 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 1593
14 swift                    0x0000000102126604 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 42516
15 swift                    0x00000001020d5d6c main + 9052
16 libdyld.dylib            0x00007fff97b3e235 start + 1
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c <app_path>/AppTests/Alamofire.swift <app_path>/AppTests/GeneratedMocks.swift <app_path>/AppTests/CurrentUser.swift <app_path>/AppTests/CameraViewControllerSpec.swift -primary-file <app_path>/AppTests/SessionServiceTests.swift <app_path>/AppTests/UserTests.swift -target x86_64-apple-ios10.3 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk -I <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/Cuckoo -F <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/Alamofire -F /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path <user_path>/Library/Developer/Xcode/DerivedData/ModuleCache -D DEBUG -D COCOAPODS -serialize-debugging-options -serialize-debugging-options -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/swift-overrides.hmap -Xcc -iquote -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-generated-files.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-own-target-headers.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/all-product-headers.yaml -Xcc -iquote -Xcc <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/AppTests-project-headers.hmap -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Products/Debug-iphonesimulator/include -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/DerivedSources/x86_64 -Xcc -I<user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -DCOCOAPODS=1 -Xcc -working-directory<app_path> -emit-module-doc-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests~partial.swiftdoc -serialize-diagnostics-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.dia -Onone -module-name AppTests -emit-module-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests~partial.swiftmodule -emit-dependencies-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.d -emit-reference-dependencies-path <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.swiftdeps -o <user_path>/Library/Developer/Xcode/DerivedData/App-baunpnxvwmqdmbchmzslemtzcbab/Build/Intermediates/App.build/Debug-iphonesimulator/AppTests.build/Objects-normal/x86_64/SessionServiceTests.o 
1.  While emitting SIL for 'testSigninWith' at <app_path>/AppTests/SessionServiceTests.swift:30:5

It appear to be linked to the use closure.

Hi, please show us the signature of callApi. Segmentation Fault 11 is a compiler crashing, so it might not be something we'll be able to workaround.

Hi @TadeasKriz and thx for your answer.
I've updated my question above to add the source code for callApi.

@arnlen Please come to our Slack channel: http://swiftkit.brightify.org/ to discuss this, I'll try to guide you so we can find what's causing this.

Problem solved thanks to @TadeasKriz. 🎉

For future reference, the problem is that Cuckoo doesn’t know the URLRequestConvertible protocol used by Alamofire, and so it doesn’t know how to match it.

Solution: add a equal(to:) method inside the test file to provide the missing information:

func equal(to value: URLRequestConvertible) -> ParameterMatcher<URLRequestConvertible> {
    return ParameterMatcher { tested in
        (try? tested.asURLRequest()) == (try? value.asURLRequest())
    }
}

Final version of the test method:

func testSigninWith() {
  let parameters: Parameters = [
    "email": "user@example.com",
    "password": "foobar"
  ]

  let mock = MockApiTools()

  stub(mock) { stub in
    _ = stub.callApi(with: equal(to: SessionRouter.signin(parameters)), from: any(), responseStatusCode: 201, anyClosure())
  }

  // [...] Test implmentation
}