Skip to content

Strange StackOverflowError in crash report #1804

Closed
@epetrenko

Description

@epetrenko

Hi there.

First, prehistory. I've published an app which I was working on to Google Play as alpha version and got strange crash reports in Crashlytics with StackOverflowError. I'm not even sure that the problem is related to coroutines (it seems to be more related to ProGuard or R8 tools), but stacktraces include links to coroutines, so that's why I'm placing an issue here.

I created a simple repository as example to show the issue. It's simplified a lot, production app has much more complicated architecture and uses coroutines as base for domain layer.

Example has a simple view model, which has live data based on state:

private val _state = MutableLiveData(MainViewState())
val state: LiveData<MainViewState>
    get() = _state

State is a data class:

data class MainViewState(val list: List<Int> = emptyList())

Activity observes this live data state:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    viewModel.state.observe(this, Observer(::renderViewState))
}

In the production app view model collects flow returned by Room library in init block. In the example repo I just created a simple flow:

init {
    viewModelScope.launch {
        flow {
            val list = arrayListOf<Int>()
            for (i in 0..100) {
                list.add(Random(100).nextInt())
            }
            emit(list)
        }.flowOn(Dispatchers.Default)
            .distinctUntilChanged()
            .collect { list ->
                Log.e("Collect list", list.toString())
            }
    }
}

flowOn(Dispatchers.Default) and distinctUntilChanged() methods are placed here just to match the behavior of the actual app. Also I emulated release mode by setting the following in build.gradle:

debug {
    debuggable false
    minifyEnabled true
    shrinkResources true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

And android.enableR8.fullMode=true in gradle.properties.

Actual issue is in that app crashes with these parameters, but everything works fine with another variations. I've got the following results. Crash doesn't appear if:

  1. Set debuggable to true
  2. Using proguard-android.txt instead of proguard-android-optimize.txt
  3. Removing android.enableR8.fullMode=true. Works for both proguard-android.txt and proguard-android-optimize.txt
  4. Removing .flowOn(Dispatchers.Default) from chain
  5. Using the same dispatchers for .flowOn() and viewModelScope.launch()

Each item in the above list describes changing of single parameter without affecting the rest. Maybe I missed something or just misunderstood basic concepts, but it's interesting why stacktrace points to StackOverflowError exception.

Deobfuscated stacktrace for example app is attached: stacktrace.txt.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions