fun finishAndDumpTrace()

in trace-recorder/src/main/org/jetbrains/lincheck/trace/recorder/TraceCollectingEventTracker.kt [965:1038]


    fun finishAndDumpTrace() {
        // Finish existing threads, except for Main
        val mainThread = Thread.currentThread()

        threads
            .mapNotNull { (thread, _) ->
                if (thread == mainThread) null
                else {
                    val threadDescriptor = ThreadDescriptor.getThreadDescriptor(thread)
                    if (threadDescriptor == null || !threadDescriptor.isAnalysisEnabled) null
                    else {
                        // tell `thread` not to track its tracepoints anymore
                        threadDescriptor.disableAnalysis()
                        thread to threadDescriptor
                    }
                }
            }
            .forEach { (thread, threadDescriptor) ->
                completeRunningThread(thread, threadDescriptor)
            }


        // Close this thread call stack (it must be 1 element, complain about problems otherwise)
        completeMainThread(mainThread, ThreadDescriptor.getCurrentThreadDescriptor())


        val allThreads = mutableListOf<ThreadData>()
        allThreads.addAll(threads.values)
        threads.clear()

        strategy.traceEnded()
        metaInfo.traceEnded()

        Logger.debug { "Trace collected in ${System.currentTimeMillis() - startTime} ms" }
        startTime = System.currentTimeMillis()

        try {
            val roots = mutableListOf<TRTracePoint>()

            allThreads.sortBy { it.threadId }
            allThreads.forEach { threadData ->
                val rootCall = threadData.rootCall
                if (rootCall == null) {
                    Logger.error { "Trace Recorder: Thread #${threadData.threadId + 1} (\"${context.getThreadName(threadData.threadId)}\"): No root call found" }
                } else {
                    roots.add(rootCall)
                }
            }

            when (mode) {
                TraceCollectorMode.BINARY_DUMP -> {
                    saveRecorderTrace(traceDumpPath!!, context, roots)
                    if (packTrace) {
                        packRecordedTrace(traceDumpPath, metaInfo)
                    }
                }
                TraceCollectorMode.BINARY_STREAM -> {
                    if (packTrace) {
                        packRecordedTrace(traceDumpPath!!, metaInfo)
                    }
                }
                TraceCollectorMode.TEXT -> printPostProcessedTrace(traceDumpPath, context, roots, false)
                TraceCollectorMode.TEXT_VERBOSE -> printPostProcessedTrace(traceDumpPath, context, roots, true)
                TraceCollectorMode.NULL -> {}
            }
        } catch (t: Throwable) {
            Logger.error { "TraceRecorder: Cannot write output file $traceDumpPath: ${t.message} at ${t.stackTraceToString()}" }
            return
        } finally {
            if (mode != TraceCollectorMode.NULL) {
                Logger.debug { "Trace finalized in ${System.currentTimeMillis() - startTime} ms" }
            }
        }
    }