Skip to content

Commit 12695b7

Browse files
committed
Debug agent code style
1 parent 5a80d2a commit 12695b7

File tree

3 files changed

+51
-80
lines changed

3 files changed

+51
-80
lines changed

core/kotlinx-coroutines-debug/src/debug/CoroutineState.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public data class CoroutineState internal constructor(
5050
internal constructor(coroutine: Continuation<*>, state: CoroutineState) : this(
5151
coroutine,
5252
state.creationStackBottom,
53-
state.sequenceNumber) {
53+
state.sequenceNumber
54+
) {
5455
_state = state.state
5556
this.lastObservedFrame = state.lastObservedFrame
5657
}
@@ -71,7 +72,6 @@ public data class CoroutineState internal constructor(
7172

7273
internal fun updateState(state: State, frame: Continuation<*>) {
7374
if (_state == state && lastObservedFrame != null) return
74-
7575
_state = state
7676
lastObservedFrame = frame as? CoroutineStackFrame
7777
}

core/kotlinx-coroutines-debug/src/debug/internal/DebugProbesImpl.kt

Lines changed: 43 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ internal object DebugProbesImpl {
3333

3434
@Synchronized
3535
public fun install() {
36-
if (++installations > 1) {
37-
return
38-
}
36+
if (++installations > 1) return
3937

4038
ByteBuddyAgent.install()
4139
val cl = Class.forName("kotlin.coroutines.jvm.internal.DebugProbesKt")
@@ -50,7 +48,7 @@ internal object DebugProbesImpl {
5048

5149
@Synchronized
5250
public fun uninstall() {
53-
if (installations == 0) error("Agent was not installed")
51+
check(isInstalled) { "Agent was not installed" }
5452
if (--installations != 0) return
5553

5654
capturedCoroutines.clear()
@@ -66,17 +64,13 @@ internal object DebugProbesImpl {
6664

6765
@Synchronized
6866
public fun hierarchyToString(job: Job): String {
69-
if (!isInstalled) {
70-
error("Debug probes are not installed")
71-
}
72-
67+
check(isInstalled) { "Debug probes are not installed" }
7368
val jobToStack = capturedCoroutines
7469
.filterKeys { it.delegate.context[Job] != null }
7570
.mapKeys { it.key.delegate.context[Job]!! }
76-
77-
val sb = StringBuilder()
78-
job.build(jobToStack, sb, "")
79-
return sb.toString()
71+
return buildString {
72+
job.build(jobToStack, this, "")
73+
}
8074
}
8175

8276
private fun Job.build(map: Map<Job, CoroutineState>, builder: StringBuilder, indent: String) {
@@ -94,57 +88,48 @@ internal object DebugProbesImpl {
9488
val contState = state.state
9589
builder.append("$str, continuation is $contState at line $element\n")
9690
}
97-
9891
for (child in children) {
9992
child.build(map, builder, indent + "\t")
10093
}
10194
}
10295

10396
@Synchronized
10497
public fun dumpCoroutinesState(): List<CoroutineState> {
105-
if (!isInstalled) {
106-
error("Debug probes are not installed")
107-
}
108-
98+
check(isInstalled) { "Debug probes are not installed" }
10999
return capturedCoroutines.entries.asSequence()
110100
.map { CoroutineState(it.key.delegate, it.value) }
111101
.sortedBy { it.sequenceNumber }
112102
.toList()
113103
}
114104

115105
public fun dumpCoroutines(out: PrintStream) {
116-
if (!isInstalled) {
117-
error("Debug probes are not installed")
118-
}
119-
120-
// Avoid inference with other out/err invocations
121-
val resultingString = dumpCoroutines()
122-
out.println(resultingString)
106+
check(isInstalled) { "Debug probes are not installed" }
107+
// Avoid inference with other out/err invocations by creating a string first
108+
dumpCoroutines().let { out.println(it) }
123109
}
124110

125111
@Synchronized
126-
private fun dumpCoroutines(): String {
112+
private fun dumpCoroutines(): String = buildString {
127113
// Synchronization window can be reduce even more, but no need to do it here
128-
return buildString {
129-
append("Coroutines dump ${dateFormat.format(System.currentTimeMillis())}")
130-
capturedCoroutines
131-
.asSequence()
132-
.sortedBy { it.value.sequenceNumber }
133-
.forEach { (key, value) ->
134-
val state = if (value.state == State.RUNNING)
135-
"${value.state} (Last suspension stacktrace, not an actual stacktrace)"
136-
else value.state.toString()
137-
138-
append("\n\nCoroutine $key, state: $state")
139-
val observedStackTrace = value.lastObservedStackTrace()
140-
if (observedStackTrace.isEmpty()) {
141-
append("\n\tat ${artificialFrame(ARTIFICIAL_FRAME_MESSAGE)}")
142-
printStackTrace(value.creationStackTrace)
143-
} else {
144-
printStackTrace(value.lastObservedStackTrace())
145-
}
114+
append("Coroutines dump ${dateFormat.format(System.currentTimeMillis())}")
115+
capturedCoroutines
116+
.asSequence()
117+
.sortedBy { it.value.sequenceNumber }
118+
.forEach { (key, value) ->
119+
val state = if (value.state == State.RUNNING)
120+
"${value.state} (Last suspension stacktrace, not an actual stacktrace)"
121+
else
122+
value.state.toString()
123+
124+
append("\n\nCoroutine $key, state: $state")
125+
val observedStackTrace = value.lastObservedStackTrace()
126+
if (observedStackTrace.isEmpty()) {
127+
append("\n\tat ${artificialFrame(ARTIFICIAL_FRAME_MESSAGE)}")
128+
printStackTrace(value.creationStackTrace)
129+
} else {
130+
printStackTrace(value.lastObservedStackTrace())
146131
}
147-
}
132+
}
148133
}
149134

150135
private fun StringBuilder.printStackTrace(frames: List<StackTraceElement>) {
@@ -158,10 +143,7 @@ internal object DebugProbesImpl {
158143
internal fun probeCoroutineSuspended(frame: Continuation<*>) = updateState(frame, State.SUSPENDED)
159144

160145
private fun updateState(frame: Continuation<*>, state: State) {
161-
if (!isInstalled) {
162-
return
163-
}
164-
146+
if (!isInstalled) return
165147
// Find ArtificialStackFrame of the coroutine
166148
val owner = frame.owner()
167149
updateState(owner, frame, state)
@@ -174,28 +156,23 @@ internal object DebugProbesImpl {
174156
warn(frame, state)
175157
return
176158
}
177-
178159
coroutineState.updateState(state, frame)
179160
}
180161

181-
private fun Continuation<*>.owner(): ArtificialStackFrame<*>? = (this as? CoroutineStackFrame)?.owner()
162+
private fun Continuation<*>.owner(): ArtificialStackFrame<*>? =
163+
(this as? CoroutineStackFrame)?.owner()
182164

183-
private tailrec fun CoroutineStackFrame.owner(): ArtificialStackFrame<*>? = if (this is ArtificialStackFrame<*>) this else callerFrame?.owner()
165+
private tailrec fun CoroutineStackFrame.owner(): ArtificialStackFrame<*>? =
166+
if (this is ArtificialStackFrame<*>) this else callerFrame?.owner()
184167

185168
internal fun <T> probeCoroutineCreated(completion: Continuation<T>): Continuation<T> {
186-
if (!isInstalled) {
187-
return completion
188-
}
189-
169+
if (!isInstalled) return completion
190170
/*
191171
* If completion already has an owner, it means that we are in scoped coroutine (coroutineScope, withContext etc.),
192172
* then piggyback on its already existing owner and do not replace completion
193173
*/
194174
val owner = completion.owner()
195-
if (owner != null) {
196-
return completion
197-
}
198-
175+
if (owner != null) return completion
199176
/*
200177
* Here we replace completion with a sequence of CoroutineStackFrame objects
201178
* which represents creation stacktrace, thus making stacktrace recovery mechanism
@@ -208,11 +185,10 @@ internal object DebugProbesImpl {
208185
override val callerFrame: CoroutineStackFrame? = acc
209186
override fun getStackTraceElement(): StackTraceElement = frame
210187
}
211-
}!!
212-
213-
val result = ArtificialStackFrame(completion, frame)
214-
storeFrame(result, completion)
215-
return result
188+
}
189+
return ArtificialStackFrame(completion, frame!!).also {
190+
storeFrame(it, completion)
191+
}
216192
}
217193

218194
@Synchronized
@@ -227,8 +203,8 @@ internal object DebugProbesImpl {
227203

228204
private class ArtificialStackFrame<T>(
229205
@JvmField val delegate: Continuation<T>,
230-
frame: CoroutineStackFrame) : Continuation<T> by delegate, CoroutineStackFrame by frame {
231-
206+
frame: CoroutineStackFrame
207+
) : Continuation<T> by delegate, CoroutineStackFrame by frame {
232208
override fun resumeWith(result: Result<T>) {
233209
probeCoroutineCompleted(this)
234210
delegate.resumeWith(result)
@@ -240,14 +216,7 @@ internal object DebugProbesImpl {
240216
private fun <T : Throwable> sanitizeStackTrace(throwable: T): List<StackTraceElement> {
241217
val stackTrace = throwable.stackTrace
242218
val size = stackTrace.size
243-
244-
var probeIndex = -1
245-
for (i in 0 until size) {
246-
val name = stackTrace[i].className
247-
if ("kotlin.coroutines.jvm.internal.DebugProbesKt" == name) {
248-
probeIndex = i
249-
}
250-
}
219+
val probeIndex = stackTrace.indexOfLast { it.className == "kotlin.coroutines.jvm.internal.DebugProbesKt" }
251220

252221
if (!DebugProbes.sanitizeStackTraces) {
253222
return List(size - probeIndex) {

core/kotlinx-coroutines-debug/test/debug/StracktraceUtils.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ package kotlinx.coroutines.debug
77
import java.io.*
88
import kotlin.test.*
99

10-
public fun String.trimStackTrace(): String {
11-
return trimIndent().replace(Regex(":[0-9]+"), "").replace(Regex("#[0-9]+"), "").applyBackspace()
12-
}
10+
public fun String.trimStackTrace(): String =
11+
trimIndent()
12+
.replace(Regex(":[0-9]+"), "")
13+
.replace(Regex("#[0-9]+"), "")
14+
.applyBackspace()
1315

1416
public fun String.applyBackspace(): String {
1517
val array = toCharArray()
@@ -46,7 +48,7 @@ public fun verifyStackTrace(e: Throwable, traces: List<String>) {
4648
}
4749

4850
public fun toStackTrace(t: Throwable): String {
49-
val sw = StringWriter() as Writer
51+
val sw = StringWriter()
5052
t.printStackTrace(PrintWriter(sw))
5153
return sw.toString()
5254
}

0 commit comments

Comments
 (0)