Get Stack Trace of Methods That Called Us

GT-Sandbox-Snapshot: StackTraceRetriever

Code

package com.glassthought.sandbox

import gt.sandbox.util.output.Out
import gt.sandbox.util.output.impl.OutSettings

val out = Out.standard(outSettings = OutSettings(printColorPerThread = true))

class StackTraceRetriever {
  companion object {
    /**
     * Returns the filtered stack trace starting from the first relevant caller.
     */
    fun getStackTrace(): List<StackTraceElement> {
      // Capture the stack trace and exclude this constructor and the wrapper class
      val allStackTrace = Throwable().stackTrace
      
      return allStackTrace.dropWhile {
        it.className == StackTraceRetriever::class.java.name || it.methodName == "getStackTrace"
      }
    }
  }
}

fun callerOne() {
  callerTwo()
}

fun callerTwo() {
  val filteredStackTrace = StackTraceRetriever.getStackTrace()
  filteredStackTrace.forEachIndexed { index, element ->
    println("[$index] ${element.className}.${element.methodName} (${element.fileName}:${element.lineNumber})")
  }
}


fun main(args: Array<String>) {
  callerOne()

}

Command to reproduce:

gt.sandbox.checkout.commit 23ac2adb62f9c844078e \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run --quiet"

Recorded output of command:

[0] com.glassthought.sandbox.MainKt.callerTwo (Main.kt:29)
[1] com.glassthought.sandbox.MainKt.callerOne (Main.kt:25)
[2] com.glassthought.sandbox.MainKt.main (Main.kt:37)
GT-Sandbox-Snapshot

Code

package com.glassthought.sandbox

import gt.sandbox.util.output.Out
import gt.sandbox.util.output.impl.OutSettings
import kotlinx.coroutines.runBlocking
import kotlin.concurrent.thread

val out = Out.standard(outSettings = OutSettings(printColorPerThread = true))

fun printCallerStackTrace() {
  val stackTrace = Throwable().stackTrace
  // The stack trace contains an array of StackTraceElement objects
  // The first element is `Throwable`, and subsequent elements are callers
  for ((index, element) in stackTrace.withIndex()) {
    println("[$index] ${element.className}.${element.methodName} (${element.fileName}:${element.lineNumber})")
  }
}

fun callerOne() {
  callerTwo()
}

fun callerTwo() {
  printCallerStackTrace()
}

fun main(args: Array<String>) {
  callerOne()

}

Command to reproduce:

gt.sandbox.checkout.commit 1a702056e0bc63b07688 \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run --quiet"

Recorded output of command:

[0] com.glassthought.sandbox.MainKt.printCallerStackTrace (Main.kt:11)
[1] com.glassthought.sandbox.MainKt.callerTwo (Main.kt:24)
[2] com.glassthought.sandbox.MainKt.callerOne (Main.kt:20)
[3] com.glassthought.sandbox.MainKt.main (Main.kt:28)