diff --git a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/DistProperties.kt b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/DistProperties.kt index 1c02c151370..647fdb4d5bc 100644 --- a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/DistProperties.kt +++ b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/DistProperties.kt @@ -11,6 +11,7 @@ object DistProperties { private val konancDriver = if (TargetManager.host.family == Family.WINDOWS) "konanc.bat" else "konanc" val konanc: Path = dist.resolve("bin/$konancDriver") val lldb: Path = Paths.get("lldb") + val lldbPrettyPrinters: Path = dist.resolve("tools/konan_lldb.py") private fun requireProp(name: String): String = System.getProperty(name) ?: error("Property `$name` is not defined") diff --git a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Driver.kt b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Driver.kt index e0a745b710d..2cd234990bd 100644 --- a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Driver.kt +++ b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Driver.kt @@ -8,6 +8,7 @@ import java.util.concurrent.TimeUnit class ToolDriver( private val konancDriver: Path, private val lldb: Path, + private val lldbPrettyPrinters: Path, private val useInProcessCompiler: Boolean = false ) { fun compile(source: Path, output: Path, vararg args: String) { @@ -26,7 +27,8 @@ class ToolDriver( } fun runLldb(program: Path, commands: List): String { - val args = commands.flatMap { listOf("-o", it) } + val args = listOf("-o", "command script import \"$lldbPrettyPrinters\"") + + commands.flatMap { listOf("-o", it) } return subprocess(lldb, program.toString(), "-b", *args.toTypedArray()) .thrownIfFailed() .stdout diff --git a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Matchers.kt b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Matchers.kt index 63077eec57e..bba9279621b 100644 --- a/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Matchers.kt +++ b/backend.native/debugger-tests/src/main/kotlin/org/jetbrains/kotlin/compiletest/Matchers.kt @@ -64,7 +64,7 @@ fun lldbTest(@Language("kotlin") programText: String, lldbSession: String) { val source = tmpdir.resolve("main.kt") val output = tmpdir.resolve("program.kexe") - val driver = ToolDriver(DistProperties.konanc, DistProperties.lldb) + val driver = ToolDriver(DistProperties.konanc, DistProperties.lldb, DistProperties.lldbPrettyPrinters) Files.write(source, programText.trimIndent().toByteArray()) driver.compile(source, output, "-g") val result = driver.runLldb(output, lldbSessionSpec.commands) @@ -124,8 +124,9 @@ private class LldbSessionSpecification private constructor( fun match(output: String) { val blocks = output.split("""(?=\(lldb\))""".toRegex()) - check(blocks.first().startsWith("(lldb) target create")) - val responses = blocks.drop(1) + check(blocks[0].startsWith("(lldb) target create")) + check(blocks[1].startsWith("(lldb) command script import")) + val responses = blocks.drop(2) val executedCommands = responses.map { it.lines().first() } val bodies = responses.map { it.lines().drop(1) } val responsesMatch = executedCommands.size == commands.size diff --git a/backend.native/debugger-tests/src/test/kotlin/org/jetbrains/kotlin/compiletest/LldbTests.kt b/backend.native/debugger-tests/src/test/kotlin/org/jetbrains/kotlin/compiletest/LldbTests.kt index 4a4ec4c3a9e..3bb719ce41a 100644 --- a/backend.native/debugger-tests/src/test/kotlin/org/jetbrains/kotlin/compiletest/LldbTests.kt +++ b/backend.native/debugger-tests/src/test/kotlin/org/jetbrains/kotlin/compiletest/LldbTests.kt @@ -53,4 +53,24 @@ class LldbTests { (unsigned char) d = 'c' (void) e = """) + + @Test + fun `can inspect classes`() = lldbTest(""" + fun main(args: Array) { + val point = Point(1, 2) + val person = Person() + return + } + + data class Point(val x: Int, val y: Int) + class Person { + override fun toString() = "John Doe" + } + """, """ + > b main.kt:4 + > r + > fr var + (ObjHeader *) point = Point(x=1, y=2) + (ObjHeader *) person = John Doe + """) } \ No newline at end of file diff --git a/llvmDebugInfoC/src/scripts/konan_lldb.py b/llvmDebugInfoC/src/scripts/konan_lldb.py index b9cbfa62f3e..30a38def65d 100644 --- a/llvmDebugInfoC/src/scripts/konan_lldb.py +++ b/llvmDebugInfoC/src/scripts/konan_lldb.py @@ -34,13 +34,13 @@ def kotlin_object_type_summary(lldb_val, internal_dict): return lldb_val.GetTarget().EvaluateExpression(expr, lldb.SBExpressionOptions()) buff_len = evaluate( - "Konan_DebugObjectToUtf8Array((struct ObjHeader *) %s, Konan_DebugBuffer(), Konan_DebugBufferSize());" % lldb_val.GetValueAsUnsigned() + "(int)Konan_DebugObjectToUtf8Array((struct ObjHeader *) %s, (char *)Konan_DebugBuffer(), (int)Konan_DebugBufferSize());" % lldb_val.GetValueAsUnsigned() ).unsigned if not buff_len: return fallback - buff_addr = evaluate("Konan_DebugBuffer()").unsigned + buff_addr = evaluate("(char *)Konan_DebugBuffer()").unsigned error = lldb.SBError() s = lldb_val.GetProcess().ReadCStringFromMemory(int(buff_addr), int(buff_len), error)