Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-debug/test/CoroutinesDumpTest.kt (Kotlin)

Code before:
    private suspend fun nestedActiveMethod(shouldSuspend: Boolean) {
        if (shouldSuspend) yield()
        notifyCoroutineStarted()
        while (currentCoroutineContext()[Job]!!.isActive) {
            try {
                Thread.sleep(60_000)
            } catch (_ : InterruptedException) {
            }
        }
    }

    private suspend fun sleepingOuterMethod(currentDispatcher: CoroutineDispatcher, latch: CompletableDeferred<Unit>) {
        sleepingNestedMethod(currentDispatcher, latch)
        yield() // TCE: make sure `sleepingOuterMethod` is contained in the continuation of `sleepingNestedMethod`
    }

    private suspend fun sleepingNestedMethod(currentDispatcher: CoroutineDispatcher, latch: CompletableDeferred<Unit>) {
        /* Schedule a computation on the current single-threaded dispatcher.
        Since that thread is currently running this code,
        the start notification will happen *after* the currently running coroutine suspends. */
        currentDispatcher.dispatch(currentDispatcher) {
            coroutineThread = Thread.currentThread()
            latch.complete(Unit)
        }
        delay(Long.MAX_VALUE)
        yield() // TCE: make sure `sleepingNestedMethod` is contained in the continuation of `delay`
    }

    private fun awaitCoroutine() = synchronized(monitor) {
        while (coroutineThread == null) (monitor as Object).wait()
        while (coroutineThread!!.state != Thread.State.TIMED_WAITING) {
            // Wait until thread sleeps to have a consistent stacktrace
        }
    }

    private fun notifyCoroutineStarted() {
        synchronized(monitor) {
            coroutineThread = Thread.currentThread()
            (monitor as Object).notifyAll()
        }
    }
}


Review comment (suggestion):
And this one avoids being inlined into `sleepingOuterMethod`, so that `sleepingNestedMethod` definitely appears in the stacktrace

Code after:
    private suspend fun nestedActiveMethod(shouldSuspend: Boolean) {
        if (shouldSuspend) yield()
        notifyCoroutineStarted()
        while (currentCoroutineContext()[Job]!!.isActive) {
            try {
                Thread.sleep(60_000)
            } catch (_ : InterruptedException) {
            }
        }
    }

    private suspend fun sleepingOuterMethod(currentDispatcher: CoroutineDispatcher, latch: CompletableDeferred<Unit>) {
        sleepingNestedMethod(currentDispatcher, latch)
        yield() // TCE: make sure `sleepingOuterMethod` is contained in the continuation of `sleepingNestedMethod`
    }

    private suspend fun sleepingNestedMethod(currentDispatcher: CoroutineDispatcher, latch: CompletableDeferred<Unit>) {
        /* Schedule a computation on the current single-threaded dispatcher.
        Since that thread is currently running this code,
        the start notification will happen *after* the currently running coroutine suspends. */
        currentDispatcher.dispatch(currentDispatcher) {
            coroutineThread = Thread.currentThread()
            latch.complete(Unit)
        }
        delay(Long.MAX_VALUE)
        yield() // TCE: make sure `sleepingNestedMethod` is contained in the continuation of `delay`
    }

    private fun awaitCoroutine() = synchronized(monitor) {
        while (coroutineThread == null) (monitor as Object).wait()
        while (coroutineThread!!.state != Thread.State.TIMED_WAITING) {
            /* Wait until the thread we're awaiting goes to sleep.
            Note: this does not establish a happens-before relationship with the thread entering `Thread.sleep`.
            There still doesn't seem to be any guarantee that the stacktrace will be accurately updated.
            <https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#getStackTrace--> says that how accurate
            a stacktrace is is implementation-dependent. */
        }
    }

    private fun notifyCoroutineStarted() {
        synchronized(monitor) {
            coroutineThread = Thread.currentThread()
            (monitor as Object).notifyAll()
        }
    }
}