[K/N] Support stacktrace using libbacktrace

This commit is contained in:
Pavel Kunyavskiy
2021-09-14 11:09:36 +03:00
committed by Space
parent 4fa5be3e58
commit c704fd6ae7
21 changed files with 350 additions and 123 deletions
@@ -2669,16 +2669,24 @@ task extend_exception(type: KonanLocalTest) {
}
standaloneTest("check_stacktrace_format") {
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64')
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt')
flags = ['-g']
source = "runtime/exceptions/check_stacktrace_format.kt"
}
standaloneTest("check_stacktrace_format_coresymbolication") {
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xbinary=sourceInfoType=coresymbolication']
source = "runtime/exceptions/check_stacktrace_format.kt"
}
standaloneTest("stack_trace_inline") {
// TODO: Enable after the test has been fixed.
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64')
flags = ['-g', '-Xg-generate-debug-trampoline=enable']
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xg-generate-debug-trampoline=enable', '-Xbinary=sourceInfoType=coresymbolication']
source = "runtime/exceptions/stack_trace_inline.kt"
// test on simulator is writing Invalid connection: com.apple.coresymbolicationd by unknown reason
// so we need to use custom checker as workaround
outputChecker = { str -> str.split("\n").contains("0") }
}
standaloneTest("stack_trace_out_of_bounds") {
@@ -2689,9 +2697,32 @@ standaloneTest("stack_trace_out_of_bounds") {
standaloneTest("kt-37572") {
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64')
flags = ['-g']
disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xbinary=sourceInfoType=coresymbolication']
source = "runtime/exceptions/kt-37572.kt"
// test on simulator is writing Invalid connection: com.apple.coresymbolicationd by unknown reason
// so we need to use custom checker as workaround
outputChecker = { str -> str.split("\n").contains("0") }
}
standaloneTest("check_stacktrace_format_libbacktrace") {
disabled = !supportsLibBacktrace(project)|| project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xbinary=sourceInfoType=libbacktrace']
source = "runtime/exceptions/check_stacktrace_format.kt"
}
standaloneTest("stack_trace_inline_libbacktrace") {
disabled = !supportsLibBacktrace(project) || project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xbinary=sourceInfoType=libbacktrace']
source = "runtime/exceptions/stack_trace_inline.kt"
outputChecker = { str -> str.split("\n").contains("1") }
}
standaloneTest("kt-37572-libbacktrace") {
disabled = !supportsLibBacktrace(project) || project.globalTestArgs.contains('-opt')
flags = ['-g', '-Xbinary=sourceInfoType=libbacktrace']
source = "runtime/exceptions/kt-37572.kt"
outputChecker = { str -> str.split("\n").contains("2") }
}
standaloneTest("custom_hook") {
@@ -5420,6 +5451,25 @@ if (isAppleTarget(project)) {
}
swiftSources = ['framework/kt43517/']
}
frameworkTest("testStackTraceFramework") {
enabled = !project.globalTestArgs.contains('-opt')
framework('Stacktrace') {
sources = ['framework/stacktrace']
opts = ['-g']
}
swiftSources = ['framework/stacktrace/']
}
frameworkTest("testStackTraceByLibbacktraceFramework") {
enabled = !project.globalTestArgs.contains('-opt')
framework('StacktraceByLibbacktrace') {
sources = ['framework/stacktraceByLibbacktrace']
opts = ['-g', '-Xbinary=sourceInfoType=libbacktrace']
}
swiftSources = ['framework/stacktraceByLibbacktrace/']
}
}
/**
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
fun inner1() : Nothing {
throw Exception()
}
fun getStackTrace() : List<String> {
try {
inner1()
} catch (e: Exception) {
return e.getStackTrace().toList()
}
return emptyList()
}
@@ -0,0 +1,23 @@
import Foundation
import Stacktrace
func testStackTrace() throws {
let trace = StacktraceKt.getStackTrace()
try assertTrue(trace[0].contains("Throwable.kt"))
try assertTrue(trace[1].contains("Exceptions.kt"))
try assertTrue(trace[2].contains("stacktrace.kt:7"))
try assertTrue(trace[3].contains("stacktrace.kt:12"))
try assertTrue(trace[5].contains("stacktrace.swift:4"))
try assertTrue(trace[6].contains("main.swift"))
}
class StacktraceTests : TestProvider {
var tests: [TestCase] = []
init() {
providers.append(self)
tests = [
TestCase(name: "Stacktrace", method: withAutorelease(testStackTrace)),
]
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
inline fun inner2() : Nothing {
throw Exception()
}
fun inner1() : Nothing {
inner2()
}
fun getStackTrace() : List<String> {
try {
inner1()
} catch (e: Exception) {
return e.getStackTrace().toList()
}
return emptyList()
}
@@ -0,0 +1,25 @@
import Foundation
import StacktraceByLibbacktrace
func testStackTrace() throws {
let trace = StacktraceByLibbacktraceKt.getStackTrace()
try assertTrue(trace[0].contains("Throwable.kt"))
try assertTrue(trace[1].contains("Exceptions.kt"))
try assertTrue(trace[2].contains("stacktraceByLibbacktrace.kt:7"))
try assertTrue(trace[2].contains("[inlined]"))
try assertTrue(trace[3].contains("stacktraceByLibbacktrace.kt:11"))
try assertTrue(trace[4].contains("stacktraceByLibbacktrace.kt:16"))
try assertTrue(trace[6].contains("stacktraceByLibbacktrace.swift:5"))
try assertTrue(trace[7].contains("main.swift:126"))
}
class StacktraceByLibbacktraceTests : TestProvider {
var tests: [TestCase] = []
init() {
providers.append(self)
tests = [
TestCase(name: "Stacktrace", method: withAutorelease(testStackTrace)),
]
}
}
@@ -1,13 +1,17 @@
import kotlin.text.Regex
import kotlin.test.*
var inlinesCount = 0
fun main() {
try {
foo()
} catch (tw:Throwable) {
val stackTrace = tw.getStackTrace()
val stackTrace = tw.getStackTrace();
inlinesCount = stackTrace.count { it.contains("[inlined]")}
stackTrace.take(6).forEach(::checkFrame)
}
println(inlinesCount)
}
fun foo() {
@@ -25,17 +29,22 @@ fun throwException() {
throw Error()
}
internal val regex = Regex("^(\\d+)\\ +.*/(.*):(\\d+):.*$")
internal val goldValues = arrayOf<Pair<String, Int>?>(
null,
null,
"kt-37572.kt" to 25,
"kt-37572.kt" to 16,
"kt-37572.kt" to 6,
"kt-37572.kt" to 4)
internal fun checkFrame(value:String) {
val goldValues = arrayOf<Pair<String, Int>?>(
null,
null,
"kt-37572.kt" to 29,
"kt-37572.kt" to 20,
*(if (inlinesCount != 0) arrayOf(
"kt-37572.kt" to 25,
"kt-37572.kt" to 18,
) else emptyArray()),
"kt-37572.kt" to 8,
"kt-37572.kt" to 6)
val (pos, file, line) = regex.find(value)!!.destructured
goldValues[pos.toInt()]?.let{
goldValues[pos.toInt()]?.let {
assertEquals(it.first, file)
assertEquals(it.second, line.toInt())
}
@@ -1,6 +1,8 @@
import kotlin.text.Regex
import kotlin.test.*
var inlinesCount = 0
fun exception() {
error("FAIL!")
}
@@ -11,20 +13,23 @@ fun main() {
}
catch (e:Exception) {
val stackTrace = e.getStackTrace()
inlinesCount = stackTrace.count { it.contains("[inlined]")}
stackTrace.take(6).forEach(::checkFrame)
}
println(inlinesCount)
}
internal val regex = Regex("^(\\d+)\\ +.*/(.*):(\\d+):.*$")
internal val goldValues = arrayOf<Pair<String, Int>?>(
null,
null,
null,
null,
"stack_trace_inline.kt" to 5,
"stack_trace_inline.kt" to 10)
internal fun checkFrame(value:String) {
val goldValues = arrayOf<Pair<String, Int>?>(
null,
null,
null,
null,
*(if (inlinesCount != 0) arrayOf(null) else emptyArray()),
"stack_trace_inline.kt" to 7,
"stack_trace_inline.kt" to 12)
val (pos, file, line) = regex.find(value)!!.destructured
goldValues[pos.toInt()]?.let{
goldValues[pos.toInt()]?.let {
assertEquals(it.first, file)
assertEquals(it.second, line.toInt())
}