Hello!
After upgrading to 1.3.70, our iOS app crashes with this error
/Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/cpp/ObjCExport.mm:332: runtime assert:
Tried digging around but no luck. ☹️
Hello. Could you please show the stack trace?
Hello! I'm not sure how to get the stack trace. I just got this by running bt from lldb
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x00007fff523bc2c6 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff52462bf1 libsystem_pthread.dylib`pthread_kill + 284
frame #2: 0x00007fff5234ba5c libsystem_c.dylib`abort + 120
frame #3: 0x000000010e9cef39 aegon`konan::abort() + 9
frame #4: 0x000000010e9c55ca aegon`RuntimeAssertFailed(char const*, char const*) + 170
frame #5: 0x000000010e9f5b8c aegon`__Kotlin_ObjCExport_initialize_block_invoke + 764
frame #6: 0x0000000113c35d48 libdispatch.dylib`_dispatch_client_callout + 8
frame #7: 0x0000000113c37297 libdispatch.dylib`_dispatch_once_callout + 66
frame #8: 0x000000010e9f5878 aegon`Kotlin_ObjCExport_initialize + 40
frame #9: 0x000000010e2c91b7 aegon`+[KotlinBase initialize] + 55
frame #10: 0x00007fff513fc103 libobjc.A.dylib`CALLING_SOME_+initialize_METHOD + 17
frame #11: 0x00007fff513fcee9 libobjc.A.dylib`initializeNonMetaClass + 624
frame #12: 0x00007fff513fccc2 libobjc.A.dylib`initializeNonMetaClass + 73
frame #13: 0x00007fff513fccc2 libobjc.A.dylib`initializeNonMetaClass + 73
frame #14: 0x00007fff513fd4ba libobjc.A.dylib`initializeAndMaybeRelock(objc_class*, objc_object*, mutex_tt<false>&, bool) + 157
frame #15: 0x00007fff51407a5d libobjc.A.dylib`lookUpImpOrForward + 595
frame #16: 0x00007fff513f8219 libobjc.A.dylib`_objc_msgSend_uncached + 73
frame #17: 0x00000001134ffed3 libswiftCore.dylib`swift_dynamicCastObjCClassMetatype + 83
frame #18: 0x00000001134a8d6d libswiftCore.dylib`swift_dynamicCastMetatypeImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*) + 93
frame #19: 0x00000001134d5e4c libswiftCore.dylib`swift::_checkGenericRequirements(llvm::ArrayRef<swift::TargetGenericRequirementDescriptor<swift::InProcess> >, llvm::SmallVectorImpl<void const*>&, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 1212
frame #20: 0x00000001134d2935 libswiftCore.dylib`_gatherGenericParameters(swift::TargetContextDescriptor<swift::InProcess> const*, llvm::ArrayRef<swift::TargetMetadata<swift::InProcess> const*>, swift::TargetMetadata<swift::InProcess> const*, llvm::SmallVectorImpl<unsigned int>&, llvm::SmallVectorImpl<void const*>&, swift::Demangle::Demangler&) + 773
frame #21: 0x00000001134d0fec libswiftCore.dylib`(anonymous namespace)::DecodedMetadataBuilder::createBoundGenericType(swift::TargetContextDescriptor<swift::InProcess> const*, llvm::ArrayRef<swift::TargetMetadata<swift::InProcess> const*>, swift::TargetMetadata<swift::InProcess> const*) const + 124
frame #22: 0x00000001134cfe0e libswiftCore.dylib`swift::Demangle::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::Node*) + 3726
frame #23: 0x00000001134cd2bb libswiftCore.dylib`swift_getTypeByMangledNodeImpl(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 411
frame #24: 0x00000001134cd0c2 libswiftCore.dylib`swift::swift_getTypeByMangledNode(swift::MetadataRequest, swift::Demangle::Demangler&, swift::Demangle::Node*, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 482
frame #25: 0x00000001134cd64b libswiftCore.dylib`swift_getTypeByMangledNameImpl(swift::MetadataRequest, llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 779
frame #26: 0x00000001134cb202 libswiftCore.dylib`swift::swift_getTypeByMangledName(swift::MetadataRequest, llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 482
frame #27: 0x00000001134bfdba libswiftCore.dylib`getSuperclassMetadata(swift::TargetClassMetadata<swift::InProcess>*, bool) + 330
frame #28: 0x00000001134ba57b libswiftCore.dylib`_swift_initClassMetadataImpl(swift::TargetClassMetadata<swift::InProcess>*, swift::ClassLayoutFlags, unsigned long, swift::TypeLayout const* const*, unsigned long*, bool) + 43
frame #29: 0x000000010e081469 aegon`type metadata completion function for DashboardController at <compiler-generated>:0
frame #30: 0x00000001134c2db2 libswiftCore.dylib`swift::MetadataCacheEntryBase<(anonymous namespace)::SingletonMetadataCacheEntry, int>::doInitialization(swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) + 370
frame #31: 0x00000001134b8be8 libswiftCore.dylib`swift_getSingletonMetadata + 936
frame #32: 0x000000010e07dda8 aegon`type metadata accessor for DashboardController at <compiler-generated>:0
frame #33: 0x000000010e084861 aegon`___lldb_unnamed_symbol50$$aegon + 17
frame #34: 0x000000011148f3a7 dyld_sim`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 517
frame #35: 0x000000011148f7b8 dyld_sim`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
frame #36: 0x000000011148a9a2 dyld_sim`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 456
frame #37: 0x00000001114897a6 dyld_sim`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 188
frame #38: 0x0000000111489846 dyld_sim`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 82
frame #39: 0x000000011147e08c dyld_sim`dyld::initializeMainExecutable() + 199
frame #40: 0x00000001114820fc dyld_sim`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 3831
frame #41: 0x000000011147d1cd dyld_sim`start_sim + 122
frame #42: 0x0000000114033234 dyld`dyld::useSimulatorDyld(int, macho_header const*, char const*, int, char const**, char const**, char const**, unsigned long*, unsigned long*) + 2238
frame #43: 0x00000001140310ce dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 522
frame #44: 0x000000011402c503 dyld`dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 1167
frame #45: 0x000000011402c036 dyld`_dyld_start + 54
Is this what you were looking for?
Is this what you were looking for?
Yes, exactly.
Could you please share a reproducer?
Sadly, I can't. I've been trying to create one but no luck. Sorry.
I also had two other projects which I also upgraded but they had no problems. The difference with this project is that it's using xcodegen. Other than that, they have the same exact configurations which make it weird.
And sharing the entire project is not an option too, I guess?
And sharing the entire project is not an option too, I guess?
Yep. It's internal. ☹️
Could you please show how DashboardController is declared? Only the class header (including attributes and super type), class body is not required.
Nevermind, I've been able to reproduce the issue on our side.
DashboardController is probably declared like
class Generic<T : KotlinClass1>
@objc(custom_name)
class DashboardController : Generic<KotlinClass2> {
To workaround the issue, please try to do _one_ of the following:
@objc attributeKotlinClass2 in the example)KotlinClass1 in the example)Thanks @SvyatoslavScherbina!
The class is declared this way
class DashboardController : ViewModelController<SwiftView, KotlinViewModel>
Don't use Kotlin class as generic argument of super class (KotlinClass2 in the example)
Don't use Kotlin class as generic type parameter upper bound (KotlinClass1 in the example)
Are these limitations of K/N or are these bugs going to be fixed in the next release?
Make Kotlin framework dynamic instead of static (might be tricky if you use cocoapods plugin)
I'm gonna have to try this out or maybe do away with the generics.
Are these limitations of K/N or are these bugs going to be fixed in the next release?
No, this is the bug reproduced under complicated circumstances (so each workaround above generally removes one of the conditions). Thank you for the report, btw!
Unfortunately, it is too late to include the fix to 1.3.71 release, so the bug will be fixed only in Kotlin 1.4.
I've tried making the framework dynamic through
binaries.withType<Framework>().configureEach {
isStatic = false
}
And setting this in the podspec file
spec.static_framework = false
However I'm getting linking errors next
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors
I found this snippet from slack which fixes linking error due to module name conflicts
// Workaround for https://youtrack.jetbrains.com/issue/KT-36721.
// Put this snippet into your root buildscript.
allprojects {
pluginManager.withPlugin("kotlin-multiplatform") {
val kotlinExtension = project.extensions.getByName("kotlin")
as org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
val uniqueName = "${project.group}.${project.name}"
kotlinExtension.targets.withType(org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget::class.java) {
compilations["main"].kotlinOptions.freeCompilerArgs += listOf("-module-name", uniqueName)
}
}
But it still has the linking error.
I found this snippet from slack which fixes linking error due to module name conflicts
That issue is likely unrelated.
If you have CocoaPods dependencies imported with cocoapods plugin, then with dynamic framework you may need to add these dependencies to the framework link options manually. That's what I meant by "might be tricky if you use cocoapods plugin".
Oh. I'll try to refactor the generics first then I'll let you know if it solves the problem
Also, another possible workaround is to make project deployment target iOS 12.2 or newer
(if you don't have @objc attribute on DashboardController).
Hello @SvyatoslavScherbina!
We've tried making the deployment target to iOS 12.2 and doing away with the generics and both of them worked but we decided to just remove the generics first since we have a project using iOS 13 because of SwiftUI and it gave us new issues. Anyway, thanks for the workarounds!