From 4d6fb2926dc893498ec240732d26f31a6eb157bf Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Fri, 21 Dec 2018 18:20:53 +0300 Subject: [PATCH] Improve symbolicator, generate better debug info (#2488) --- .../backend/konan/llvm/CodeGenerator.kt | 2 +- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 40 +++++++++++-------- .../cinterop/coreSymbolication.def | 1 + .../src/symbolicationMain/kotlin/main.kt | 38 +++++++++++++----- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 5c8adc53f4a..5f89fccfe95 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -89,7 +89,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { } fun generateLocationInfo(locationInfo: LocationInfo): DILocationRef? { - return LLVMCreateLocation(LLVMGetModuleContext(context.llvmModule), locationInfo.line, locationInfo.line, locationInfo.scope) + return LLVMCreateLocation(LLVMGetModuleContext(context.llvmModule), locationInfo.line, locationInfo.column, locationInfo.scope) } val objCDataGenerator = when (context.config.target.family) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index b597b07281a..a8a91668ac4 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.SourceManager +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor import org.jetbrains.kotlin.ir.expressions.* @@ -728,8 +729,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map Unit = {}): ContinuationBlock { + private fun continuationBlock( + type: IrType, locationInfo: LocationInfo?, code: (ContinuationBlock) -> Unit = {}): ContinuationBlock { + val entry = functionGenerationContext.basicBlock("continuation_block", locationInfo) functionGenerationContext.appendingTo(entry) { @@ -1697,7 +1699,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map TODO("unsupported $arch") } +fun sourceInfoString(owner: CValue, address: ULong): String? { + var sourceInfo: CValue? = CSSymbolOwnerGetSourceInfoWithAddress(owner, address) + if (CSIsNull(sourceInfo!!)) return null + var lineNumber = CSSourceInfoGetLineNumber(sourceInfo) + var maybe = false + if (lineNumber == 0u) { + // Workaround compiler bug. + sourceInfo = null + for (maybeAddress in address - 10u .. address + 10u) { + val maybeSourceInfo = CSSymbolOwnerGetSourceInfoWithAddress(owner, maybeAddress) + if (CSIsNull(maybeSourceInfo)) continue + var maybeLineNumber = CSSourceInfoGetLineNumber(maybeSourceInfo) + if (maybeLineNumber != 0u) { + lineNumber = maybeLineNumber + sourceInfo = maybeSourceInfo + maybe = true + break + } + } + } + if (sourceInfo == null) return null + val filePath = CSSourceInfoGetPath(sourceInfo)?.toKString() ?: return null + val columnNumber = CSSourceInfoGetColumn(sourceInfo) + return "$filePath:${if (maybe) "~" else ""}$lineNumber:$columnNumber" +} + fun analyzeTrace(program: String, arch: String, input: Sequence) { val symbolicator = CSSymbolicatorCreateWithPathAndArchitecture(program, archToCpuName(arch)) if (CSIsNull(symbolicator)) throw Error("Cannot create \"$arch\" symbolicator for $program") @@ -39,15 +65,9 @@ fun analyzeTrace(program: String, arch: String, input: Sequence) { if (!CSIsNull(symbol)) { CSSymbolGetRange(symbol).useContents { val address = this.location + offsetInFunction - val sourceInfo = CSSymbolOwnerGetSourceInfoWithAddress(owner, address) - if (!CSIsNull(sourceInfo)) { - val filePath = CSSourceInfoGetPath(sourceInfo)?.toKString() - // or val fileName = CSSourceInfoGetFilename(sourceInfo)?.toKString() - val lineNumber = CSSourceInfoGetLineNumber(sourceInfo) - val lineNumberString = if (lineNumber != 0u) lineNumber.toString() else "" - if (filePath != null) - result = matcher.replaceFirst(line, - "$atPart$functionName $filePath:$lineNumberString") + val sourceInfo = sourceInfoString(owner, address) + if (sourceInfo != null) { + result = matcher.replaceFirst(line, "$atPart$functionName $sourceInfo") } } }