Few cents about my commits

Debugger: adding kotlin SMAP support

|

This post continues series of debugger rework, refer to previous post. In general rework is almost complete and changes are being tested now.
Beside variable resolution problem debug of kotlin code suffered from another issue: debugger was jumping random lines when step over collection iteration with lambdas. Why this was happening is bellow:

Sample

Here is a sample class to demonstrate:

/* 1 */ package com.test
/* 2 */ class Test {
/* 3 */     var text = "";
/* 4 */     val list: List<String> = listOf("a", "b", "c")
/* 5 */     fun test() {
/* 6 */         list.forEachIndexed  { index, str ->
/* 7 */             text = str + index
/* 8 */         }
/* 9 */     }
/* 10 */}

Decompiling it with javap:

> javap -c -l -p -v com.test.Test
public final void test();
....
     LineNumberTable:
       line 6: 0
       line 11: 8
       line 12: 10
       line 7: 47
       line 8: 71
       line 13: 75
       line 9: 76

And root case of jumps to random locations is in debug line number table generated by kotlin: source code has maximum line number of 10 but debug information specifies that there are blocks of VM instruction that has to be mapped to line numbers 11, 12, 13. And these are missing

Official statement

yole, JetBrains Team answered one post with following:

Do you have the source code from which the .class was compiled? Note that Kotlin supports inline functions, and when a method calls an inline function, the code of the inline function and the code of the lambda passed to it will be compiled into the calling method. In that case, the lines from the inline function will have line numbers outside of the range of lines in the original source file, and the SMAP table will contain full information on the line number mapping between all source files involved.

SMAP

SMAP is present in class file as SourceDebugExtension attribute:

SourceDebugExtension:
  SMAP
  Test.kt
  Kotlin
  *S Kotlin
  *F
  + 1 Test.kt
  com/test/Test
  + 2 _Collections.kt
  kotlin/collections/CollectionsKt___CollectionsKt
  *L
  1#1,10:1
  1528#2,3:11
  *E
  *S KotlinDebug
  *F
  + 1 Test.kt
  com/controlj/ios/bluemax/Test
  *L
  6#1,3:11
  *E

In general it contains line number mapping table of code kotlin injected. For robovm we need only debug infomration section *S KotlinDebug. In this case it tells: 6#1,3:11 this means line numbers 11:(11+3-1) to be mapped back into 6:(6+3-1).

kotlin SMAPParser.kt was used as reference and line number mapper was introduced into RoboVM debug information plugin to handle this case.

Source code: dkimitsa/robovm, debugger_local_resolution, commit

Comments