Prevent infinite recursion in case of circular suppressed chains
#KT-37603 (cherry picked from commit 3346ad37999edf69efd1c49382bb987da48e281c)
This commit is contained in:
committed by
Vasily Levchenko
parent
f0224c6c07
commit
b80b1d65ca
@@ -45,24 +45,28 @@ public open class Throwable(open val message: String?, open val cause: Throwable
|
||||
/**
|
||||
* Prints the [detailed description][Throwable.stackTraceToString] of this throwable to the standard output.
|
||||
*/
|
||||
public fun printStackTrace(): Unit = dumpStackTrace("", "") { println(it) }
|
||||
public fun printStackTrace(): Unit = dumpStackTrace("", "", { println(it) }, mutableSetOf())
|
||||
|
||||
internal fun dumpStackTrace(): String = buildString {
|
||||
dumpStackTrace("", "") { appendln(it) }
|
||||
dumpStackTrace("", "", { appendln(it) }, mutableSetOf())
|
||||
}
|
||||
|
||||
private fun Throwable.dumpStackTrace(indent: String, qualifier: String, writeln: (String) -> Unit) {
|
||||
this.dumpSelfTrace(indent, qualifier, writeln)
|
||||
private fun Throwable.dumpStackTrace(indent: String, qualifier: String, writeln: (String) -> Unit, visited: MutableSet<Throwable>) {
|
||||
this.dumpSelfTrace(indent, qualifier, writeln, visited) || return
|
||||
|
||||
var cause = this.cause
|
||||
while (cause != null) {
|
||||
// TODO: should skip common stack frames
|
||||
cause.dumpSelfTrace(indent, "Caused by: ", writeln)
|
||||
cause.dumpSelfTrace(indent, "Caused by: ", writeln, visited)
|
||||
cause = cause.cause
|
||||
}
|
||||
}
|
||||
|
||||
private fun Throwable.dumpSelfTrace(indent: String, qualifier: String, writeln: (String) -> Unit) {
|
||||
private fun Throwable.dumpSelfTrace(indent: String, qualifier: String, writeln: (String) -> Unit, visited: MutableSet<Throwable>): Boolean {
|
||||
if (!visited.add(this)) {
|
||||
writeln(indent + qualifier + "[CIRCULAR REFERENCE, SEE ABOVE: $this]")
|
||||
return false
|
||||
}
|
||||
writeln(indent + qualifier + this.toString())
|
||||
for (element in stackTraceStrings) {
|
||||
writeln("$indent\tat $element")
|
||||
@@ -71,9 +75,10 @@ public open class Throwable(open val message: String?, open val cause: Throwable
|
||||
if (!suppressed.isNullOrEmpty()) {
|
||||
val suppressedIndent = indent + '\t'
|
||||
for (s in suppressed) {
|
||||
s.dumpStackTrace(suppressedIndent, "Suppressed: ", writeln)
|
||||
s.dumpStackTrace(suppressedIndent, "Suppressed: ", writeln, visited)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user