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

Accessing 'stackTrace' on JobCancellationException instance leads to crash on Android 6.0 and below #1866

Closed
varahash opened this issue Mar 14, 2020 · 1 comment
Assignees
Labels

Comments

@varahash
Copy link

varahash commented Mar 14, 2020

Here is simple example:

runBlocking {
    val job = launch {
        try {
            delay(1000)
        } catch (e: Exception) {
            e.stackTrace // accessing 'stackTrace' lead to crash
        }
    }
    yield()
    job.cancelAndJoin()
}

When you run the code above on Android 6.0 and lower, application will crash with following exception:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.Object.clone()' on a null object reference

The analogue issue is akaita/RxJava2Debug#2

Due to the bug on Android 6.0 and below, when you override fillInStackTrace and don't call super method, under-the-hood the exception stack trace not filled by nativeFillInStackTrace() method, so next time when you try to call getStackTrace(), under-the-hood the nativeGetStackTrace() method will return null and clone() will be called on that null.

Solution
To fix this issue you should set empty stack trace, when overriding fillInStackTrace method, like following:

override fun fillInStackTrace(): Throwable {
    stackTrace = emptyArray<StackTraceElement>()
    return this
}

Also to reduce garbage, this empty array can be defined as global constant.

This fix must be applied to all custom exceptions, those override fillInStackTrace, currently these are:

internal actual class JobCancellationException public actual constructor(

internal actual class AbortFlowException actual constructor(

internal actual class ChildCancelledException : CancellationException("Child of the scoped flow was cancelled") {

Workaround
Enable Debug Mode, so that fillInStackTrace will work as expected.

@elizarov
Copy link
Contributor

Thanks a lot for a detailed writeup on the problem and how to work around it.

qwwdfsad added a commit that referenced this issue Mar 16, 2020
…roperly work on Android <= 6.0 that had a bug on a code-path with an empty stacktrace

Fixes #1866
qwwdfsad added a commit that referenced this issue Mar 16, 2020
…roperly work on Android <= 6.0 that had a bug on a code-path with an empty stacktrace (#1868)

Fixes #1866
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants