Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-debug/src/DebugProbes.kt (Kotlin)

Code before:
 *
 * Debug probes is a dynamic attach mechanism which installs multiple hooks into coroutines machinery.
 * It slows down all coroutine-related code, but in return provides diagnostic information, including
 * asynchronous stacktraces, coroutine dumps (similar to [ThreadMXBean.dumpAllThreads] and `jstack` via [DebugProbes.dumpCoroutines]
 * and programmatic introspection of all alive coroutines.
 * All introspecting methods throw [IllegalStateException] if debug probes were not installed.
 *
 * ### Consistency guarantees
 *
 * All snapshotting operations (e.g. [dumpCoroutines]) are *weakly-consistent*, meaning that they happen
 * concurrently with coroutines progressing their own state. These operations are guaranteed to observe
 * each coroutine's state exactly once, but the state is not guaranteed to be the most recent before the operation.
 * In practice, it means that for snapshotting operations in progress, for each concurrent coroutine either
 * the state prior to the operation or the state that was reached during the current operation is observed.
 *
 * ### Overhead
 *
 *  - Every created coroutine is stored in a concurrent hash map and hash map is looked up and
 *    updated on each suspension and resumption.
 *  - If [DebugProbes.enableCreationStackTraces] is enabled, stack trace of the current thread is captured on
 *    each created coroutine that is a rough equivalent of throwing an exception per each created coroutine.
 *
 * ### Internal machinery and classloading.
 *
 * Under the hood, debug probes replace internal `kotlin.coroutines.jvm.internal.DebugProbesKt` class with the following
 * empty static methods:
 *
 * - `probeCoroutineResumed` that is invoked on every [Continuation.resume].
 * - `probeCoroutineSuspended` that is invoked on every continuation suspension.
 * - `probeCoroutineCreated` that is invoked on every coroutine creation.
 *
 * with `kotlinx-coroutines`-specific class to keep track of all the coroutines machinery.
 *
 * The new class is located in `kotlinx-coroutines-core` module meaning that all target application classes that use
 * coroutines and `suspend` functions have to be loaded by the classloader for which `kotlinx-coroutines-core` classes are avilable.
 */
@ExperimentalCoroutinesApi
public object DebugProbes {

    /**
     * Whether coroutine creation stack traces should be sanitized.
     * Sanitization removes all frames from `kotlinx.coroutines` package except
     * the first one and the last one to simplify diagnostic.
     *
     * `true` by default.
     */
    public var sanitizeStackTraces: Boolean
        get() = DebugProbesImpl.sanitizeStackTraces
        @Suppress("INVISIBLE_SETTER") // do not remove the INVISIBLE_SETTER suppression: required in k2
        set(value) {
            DebugProbesImpl.sanitizeStackTraces = value

Review comment (bug):
```suggestion
 * Under the hood, debug probes replace internal `kotlin.coroutines.jvm.internal.DebugProbesKt` class that has the following
 * empty static methods:
```

Otherwise, we get the somewhat confusing "replace A with B with C."

Code after:
 *
 * Debug probes is a dynamic attach mechanism which installs multiple hooks into coroutines machinery.
 * It slows down all coroutine-related code, but in return provides diagnostic information, including
 * asynchronous stacktraces, coroutine dumps (similar to [ThreadMXBean.dumpAllThreads] and `jstack`) via [DebugProbes.dumpCoroutines],
 * and programmatic introspection of all alive coroutines.
 * All introspecting methods throw [IllegalStateException] if debug probes were not installed.
 *
 * ### Consistency guarantees
 *
 * All snapshotting operations (e.g. [dumpCoroutines]) are *weakly-consistent*, meaning that they happen
 * concurrently with coroutines progressing their own state. These operations are guaranteed to observe
 * each coroutine's state exactly once, but the state is not guaranteed to be the most recent before the operation.
 * In practice, it means that for snapshotting operations in progress, for each concurrent coroutine either
 * the state prior to the operation or the state that was reached during the current operation is observed.
 *
 * ### Overhead
 *
 *  - Every created coroutine is stored in a concurrent hash map, and the hash map is looked up in and
 *    updated on each suspension and resumption.
 *  - If [DebugProbes.enableCreationStackTraces] is enabled, stack trace of the current thread is captured on
 *    each created coroutine that is a rough equivalent of throwing an exception per each created coroutine.
 *
 * ### Internal machinery and classloading.
 *
 * Under the hood, debug probes replace internal `kotlin.coroutines.jvm.internal.DebugProbesKt` class that has the following
 * empty static methods:
 *
 * - `probeCoroutineResumed` that is invoked on every [Continuation.resume].
 * - `probeCoroutineSuspended` that is invoked on every continuation suspension.
 * - `probeCoroutineCreated` that is invoked on every coroutine creation.
 *
 * with a `kotlinx-coroutines`-specific class to keep track of all the coroutines machinery.
 *
 * The new class is located in the `kotlinx-coroutines-core` module, meaning that all target application classes that use
 * coroutines and `suspend` functions have to be loaded by the classloader in which `kotlinx-coroutines-core` classes are available.
 */
@ExperimentalCoroutinesApi
public object DebugProbes {

    /**
     * Whether coroutine creation stack traces should be sanitized.
     * Sanitization removes all frames from `kotlinx.coroutines` package except
     * the first one and the last one to simplify diagnostic.
     *
     * `true` by default.
     */
    public var sanitizeStackTraces: Boolean
        get() = DebugProbesImpl.sanitizeStackTraces
        @Suppress("INVISIBLE_SETTER") // do not remove the INVISIBLE_SETTER suppression: required in k2
        set(value) {
            DebugProbesImpl.sanitizeStackTraces = value