diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 3181d6ec5f0..788e0b4a2e6 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -2036,6 +2036,12 @@ task extend_exception(type: RunKonanTest) { source = "runtime/exceptions/extend0.kt" } +task check_stacktrace_format(type: RunStandaloneKonanTest) { + disabled = !isAppleTarget(project) + flags = ['-g'] + source = "runtime/exceptions/check_stacktrace_format.kt" +} + task custom_hook(type: RunStandaloneKonanTest) { disabled = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "value 42: Error\n" diff --git a/backend.native/tests/runtime/exceptions/check_stacktrace_format.kt b/backend.native/tests/runtime/exceptions/check_stacktrace_format.kt new file mode 100644 index 00000000000..32fd5e03fde --- /dev/null +++ b/backend.native/tests/runtime/exceptions/check_stacktrace_format.kt @@ -0,0 +1,41 @@ +// Checks that on Apple targets first two lines of exception stacktrace of symbolized executable looks like +// "\tat 1 main.kexe\t\t 0x000000010d7cdb4c kfun:package.function(kotlin.Int) + 108 (/path/to/file/name.kt:10:27)\n" +// If test is broken, org.jetbrains.kotlin.idea.filters.KotlinExceptionFilter (in main Kotlin repo) should be updated. + +import kotlin.test.* +import kotlin.text.Regex + +val EXTENSION = ".kt:" +val LOCATION_PATTERN = Regex("\\d+:\\d+") + +fun checkStringFormat(s: String) { + val trimmed = s.trim() + + assertTrue(trimmed.endsWith(')'), "Line is not ended with ')'") + assertNotEquals(trimmed.indexOf('('), -1, "No '(' before filename") + + val fileName = trimmed.substring(trimmed.lastIndexOf('(') + 1, trimmed.lastIndex) + assertNotEquals(fileName.indexOf(EXTENSION), -1, "Filename 'kt' extension is absent") + + val location = fileName.substring(fileName.indexOf(EXTENSION) + EXTENSION.length) + assertTrue(LOCATION_PATTERN.matches(location), "Expected location of form 12:8") +} + +fun functionA() { + throw Error("an error") +} + +fun functionB() { + functionA() +} + +fun main(args : Array) { + try { + functionB() + } catch (e: Throwable) { + val st = e.getStackTrace() + repeat(3) { + checkStringFormat(st[it]) + } + } +} \ No newline at end of file