JetBrains / kotlin-native

Kotlin/Native infrastructure
Apache License 2.0
7.02k stars 566 forks source link

App crash in iOS when StringBuilder.toString() is called #3468

Closed francos closed 4 years ago

francos commented 5 years ago

I got the crash info from Crashlytics so not sure how to reproduce it.

Kotlin version: 1.3.50

iOS version: 13.1.2 (17A861) Device: iPhone XS Max

Error: SIGABRT ABORT

Stack trace:

Crashed: com.apple.main-thread
0  libsystem_kernel.dylib         0x1b4860ef4 __pthread_kill + 8
1  libsystem_pthread.dylib        0x1b4781d1c pthread_kill + 196
2  libsystem_c.dylib              0x1b4711a54 abort + 104
3  App                           0x1047360f4 KonanTerminateHandler() + 4379926772
4  App                           0x104733598 (anonymous namespace)::Kotlin_deinitRuntimeCallback(void*) + 4379915672
5  App                           0x104734d00 (anonymous namespace)::garbageCollect(MemoryState*, bool) + 4379921664
6  App                           0x1047420fc AllocArrayInstanceStrict + 4379975932
7  App                           0x10448b398 kfun:kotlin.text.StringBuilder.toString()kotlin.String + 4377129880
8  CoreFoundation                 0x1b49f107c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28
9  CoreFoundation                 0x1b49f0800 __CFRunLoopDoBlocks + 268
10 CoreFoundation                 0x1b49ebcb0 __CFRunLoopRun + 2288
11 CoreFoundation                 0x1b49eb098 CFRunLoopRunSpecific + 480
12 GraphicsServices               0x1beb55534 GSEventRunModal + 108
13 UIKitCore                      0x1b8b0b7ac UIApplicationMain + 1940
14 App                           0x1041be6a4 main + 14 (AppDelegate.swift:14)
15 libdyld.dylib                  0x1b486af30 <redacted> + 4
olonho commented 5 years ago

Not sure is reports like this one or https://github.com/JetBrains/kotlin-native/issues/3469 makes much sense without context and reproducer. The only suggestion we can provide with this much info is retry with 1.3.60.

SvyatoslavScherbina commented 5 years ago

Have you tried applying the workaround from https://github.com/JetBrains/kotlin-native/issues/3259#issuecomment-526503356?

francos commented 5 years ago

@olonho sorry, I know it's not a lot of information but unfortunately I haven't been able to reproduce this locally so I can't provide a reproducer. If I see this in my local device later I'll provide more information. In the meantime, would it help to share the stack trace of the other threads? (I have this in the Crashlytics crash) or would this not provide any useful information?

@SvyatoslavScherbina yes I have tried that workaround and I still got this error.

SvyatoslavScherbina commented 5 years ago

would it help to share the stack trace of the other threads?

This can be useful.

Do you use StableRef or DetachedObjectGraph in your code?

francos commented 5 years ago

@SvyatoslavScherbina no, I don't use StableRef or DetachedObjectGraph.

Here are the stack traces of the other threads:

com.apple.uikit.eventfetch-thread
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  CoreFoundation                 0x187d5e068 __CFRunLoopServiceMachPort + 216
3  CoreFoundation                 0x187d59188 __CFRunLoopRun + 1444
4  CoreFoundation                 0x187d588bc CFRunLoopRunSpecific + 464
5  Foundation                     0x188098994 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 228
6  Foundation                     0x188098874 -[NSRunLoop(NSRunLoop) runUntilDate:] + 88
7  UIKitCore                      0x18be8649c -[UIEventFetcher threadMain] + 152
8  Foundation                     0x1881c90b0 __NSThread__start__ + 848
9  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
10 libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.twitter.crashlytics.ios.MachExceptionServer
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  App                            0x10106ca78 CLSMachExceptionServer + 4304472696
3  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
4  libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.apple.CoreMotion.MotionThread
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  CoreFoundation                 0x187d5e068 __CFRunLoopServiceMachPort + 216
3  CoreFoundation                 0x187d59188 __CFRunLoopRun + 1444
4  CoreFoundation                 0x187d588bc CFRunLoopRunSpecific + 464
5  CoreFoundation                 0x187d59608 CFRunLoopRun + 60
6  CoreMotion                     0x19467864c CLClientCreateIso6709Notation + 149564
7  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
8  libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  CoreFoundation                 0x187d5e068 __CFRunLoopServiceMachPort + 216
3  CoreFoundation                 0x187d59188 __CFRunLoopRun + 1444
4  CoreFoundation                 0x187d588bc CFRunLoopRunSpecific + 464
5  CFNetwork                      0x18afd3e68 (Missing)
6  Foundation                     0x1881c90b0 __NSThread__start__ + 848
7  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
8  libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.apple.CFNetwork.CustomProtocols
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  CoreFoundation                 0x187d5e068 __CFRunLoopServiceMachPort + 216
3  CoreFoundation                 0x187d59188 __CFRunLoopRun + 1444
4  CoreFoundation                 0x187d588bc CFRunLoopRunSpecific + 464
5  CFNetwork                      0x18afd3e68 (Missing)
6  Foundation                     0x1881c90b0 __NSThread__start__ + 848
7  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
8  libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.apple.CFStream.LegacyThread
0  libsystem_kernel.dylib         0x187bb75f4 mach_msg_trap + 8
1  libsystem_kernel.dylib         0x187bb6a60 mach_msg + 72
2  CoreFoundation                 0x187d5e068 __CFRunLoopServiceMachPort + 216
3  CoreFoundation                 0x187d59188 __CFRunLoopRun + 1444
4  CoreFoundation                 0x187d588bc CFRunLoopRunSpecific + 464
5  CoreFoundation                 0x187d76d60 _legacyStreamRunLoop_workThread + 260
6  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
7  libsystem_pthread.dylib        0x187b00aec thread_start + 8

com.apple.CFSocket.private
0  libsystem_kernel.dylib         0x187bd9148 __select + 8
1  CoreFoundation                 0x187d6bb3c __CFSocketManager + 636
2  libsystem_pthread.dylib        0x187afd1ec _pthread_start + 124
3  libsystem_pthread.dylib        0x187b00aec thread_start + 8

Thread #1
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #2
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #3
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #4
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #5
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #6
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #7
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #8
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #9
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #10
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8

Thread #11
0  libsystem_kernel.dylib         0x187bd9a74 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x187afdff0 _pthread_wqthread + 352
2  libsystem_pthread.dylib        0x187b00ae0 start_wqthread + 8
SvyatoslavScherbina commented 5 years ago

Unfortunately, this is clearly not enough to find the root cause. Could you share the entire application to make us able to reproduce the issue on our side?

francos commented 5 years ago

That is not possible @SvyatoslavScherbina, my employer would not allow sharing their codebase as it is private. Is there anything else I can provide to help you fix this?

SvyatoslavScherbina commented 5 years ago

Could you try to reproduce it locally? This may require running release binaries on real device instead of debug ones on a simulator.

francos commented 5 years ago

I will be looking further into it this week and trying to reproduce it @SvyatoslavScherbina. I will let you know if I find anything.

SvyatoslavScherbina commented 5 years ago

Thanks. Please note that the crash has nothing to do with toString, it may actually happen during execution of any other function.

francos commented 5 years ago

Yes, I have noticed that it happens when calling other functions as well @SvyatoslavScherbina. We have detected now some memory leaks that might be related to this and are trying to fix them. Do you know exactly why it can happen when calling any method? Do you think it might be related to the memory leaks?

SvyatoslavScherbina commented 5 years ago

Do you think it might be related to the memory leaks?

I don't think so.

francos commented 4 years ago

@olonho @SvyatoslavScherbina I have been able to reproduce an issue in KN that I think is the culprit for this.

This happened in Kotlin Native 1.3.61

The issue happens when, inside a companion object, we call a "static" method (that creates a String dynamically) from inside a val (while this is not the best practice, we were doing it for some reason, and the compiler never complained so we assumed it'd work fine in iOS as it does in the JVM).

Example code:

class SomeClass {

    suspend fun authenticate() {
        val url = AUTHENTICATE_URL
    }

    companion object {

        private const val BASE_URL = "https://baseurl"
        private const val AUTH_BASE_URL = "$BASE_URL/auth"

        private const val AUTH_REDIRECT_URL = "redirectUrl"

        private val AUTHENTICATE_URL = "$BASE_URL/whatever?goto=${getAuthorizeUrl()}"

        private fun getAuthorizeUrl(): String {
            return "$AUTH_BASE_URL/whatever?redirect=${AUTH_REDIRECT_URL.toUrlEncoded()}"
        }

    }

}

The crash happens when calling SomeClass().authenticate().

The toUrlEncoded() method is an extension function that we created as expect in the common module:

expect fun String.toUrlEncoded(): String

and the implementation in the iOS module is:

@Suppress("CAST_NEVER_SUCCEEDS")
actual fun String.toUrlEncoded(): String {
    return (this as NSString).stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet)
            ?: ""
}

When I replace AUTHENTICATE_URL with a method that returns the same String then everything works fine.

SvyatoslavScherbina commented 4 years ago

This particular code fragment doesn't actually reproduce the issue on our side. Have you modified the reproducer before posting it here? Does SomeClass have a super class in your code base?

francos commented 4 years ago

@SvyatoslavScherbina sorry for the confusion. I did change the reproducer to not share the actual code from the app and I thought it caused the crash but seems like it didn't.

I have tried it out and the issue turned out to be something different than what I initially thought. It appears when you define a constant after a static method and use that constant inside the method.

This is the real reproducer now:

class SomeClass {

    fun authenticate() {
        val url = AUTHENTICATE_URL
    }

    companion object {

        private val AUTHENTICATE_URL = "https://whatever?goto=${getAuthorizeUrl()}"

        private fun getAuthorizeUrl(): String {
            return "https://whatever?param1=$PARAM"
        }

        private const val PARAM = "paramvalue"

    }

}
artdfel commented 4 years ago

Hi @FrancoSabadini! It seems that the latest reproducer you shared cannot help here. It crashes, but differently from the original issue. Here, when you're executing the getAuthorizeUrl() function, your PARAM is not initialized. In my case, just changing the declaration order helped. Anyway, this is not the same problem that was stated at the beginning of this thread.

francos commented 4 years ago

Hi @artdfel, I thought it might not be the same problem but since it was in the same class I thought they might be related.

I noticed that changing the order of the declarations prevents the issue, but I think the compiler should either show error at build time or this should be allowed. The crash at runtime doesn't seem to be acceptable as people need to guess why this is happening. Should I create a different issue for this error in this case?

francos commented 4 years ago

Hi @SvyatoslavScherbina @artdfel, any news on this? Should I create a new issue for the problem described in my previous comment?

artdfel commented 4 years ago

Hello @FrancoSabadini! Yes, I think you can create another issue as far as this snippet behave differently for the Kotlin/Native and the Kotlin/JVM. Also, I got to ask you about the current status of the original problem. So far, we cannot reproduce it locally by any of your samples. Is there anything else that you can share?

francos commented 4 years ago

Perfect @artdfel I have created a new issue for this now: https://github.com/JetBrains/kotlin-native/issues/3750

Regarding the original issue, I haven't been able to get any more information, but I have just released a new app version that uses the latest version of Kotlin (1.3.61) so I'll let you know if this still happens there once users start updating the app.

francos commented 4 years ago

After updating to Kotlin 1.3.61 I have not seen this anymore, I'll close this for now and if I see it again I'll re-open it.