Skip to content

Commit 36840e1

Browse files
authored
feat: debugging K/N page revamp (#4962)
1 parent 3209cf2 commit 36840e1

File tree

6 files changed

+155
-168
lines changed

6 files changed

+155
-168
lines changed

docs/kr.tree

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@
203203
<toc-element toc-title="Migration guide" topic="native-migration-guide.md"/>
204204
</toc-element>
205205
<toc-element topic="native-debugging.md"/>
206-
<toc-element topic="native-ios-symbolication.md"/>
207206
<toc-element toc-title="Reference and tips">
208207
<toc-element toc-title="Target support" topic="native-target-support.md"/>
209208
<toc-element toc-title="Improving compilation time" topic="native-improving-compilation-time.md"/>

docs/topics/native/native-debugging.md

Lines changed: 149 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
11
[//]: # (title: Debugging Kotlin/Native)
22

3-
Currently, the Kotlin/Native compiler produces debug info compatible with the DWARF 2 specification, so modern debugger tools can
4-
perform the following operations:
5-
- breakpoints
6-
- stepping
7-
- inspection of type information
8-
- variable inspection
9-
10-
>Supporting the DWARF 2 specification means that the debugger tool recognizes Kotlin as C89, because before the DWARF 5 specification, there is no identifier for the Kotlin language type in specification.
3+
The Kotlin/Native compiler can generate binaries with debug information, as well as create debug symbol files for [symbolicating
4+
crash reports](#debug-ios-applications).
5+
6+
The debug information is compatible with the [DWARF 2](https://dwarfstd.org/download.html) specification, so modern debugger
7+
tools, like LLDB and GDB can:
8+
9+
* [Set breakpoints](#set-breakpoints)
10+
* [Use stepping](#use-stepping)
11+
* [Inspect variable and type information](#inspect-variables)
12+
13+
> Supporting the DWARF 2 specification means that the debugger tool recognizes Kotlin as C89, because before the DWARF 5
14+
> specification, there is no identifier for the Kotlin language type in the specification.
1115
>
1216
{style="note"}
1317

14-
## Produce binaries with debug info with Kotlin/Native compiler
18+
## Generate binaries with debug information
19+
20+
When debugging in IntelliJ IDEA, Android Studio, or Xcode, binaries with debug information are generated automatically
21+
(unless the build is configured differently).
22+
23+
You can enable debugging manually and produce binaries that include debug information by:
24+
25+
* **Using Gradle tasks**. To get debug binaries, use `linkDebug*` Gradle tasks, for example:
26+
27+
```bash
28+
./gradlew linkDebugFrameworkNative
29+
```
30+
31+
The tasks differ depending on the binary type (for example, `linkDebugSharedNative`) or your target (for example, `linkDebugExecutableMacosX64`).
1532

16-
To produce binaries with the Kotlin/Native compiler, use the ``-g`` option on the command line.
33+
* **Using the command-line compiler**. In the command line, compile your Kotlin/Native binary with the `-g` option:
34+
35+
```bash
36+
kotlinc-native hello.kt -g -o terminator
37+
```
38+
39+
Then launch your debugger tool. For example:
40+
41+
```bash
42+
lldb terminator.kexe
43+
```
44+
45+
The debugger outputs:
1746

1847
```bash
1948
0:b-debugger-fixes:minamoto@unit-703(0)# cat - > hello.kt
2049
fun main(args: Array<String>) {
2150
println("Hello world")
22-
println("I need your clothes, your boots and your motocycle")
51+
println("I need your clothes, your boots and your motorcycle")
2352
}
2453
0:b-debugger-fixes:minamoto@unit-703(0)# dist/bin/konanc -g hello.kt -o terminator
2554
KtFile: hello.kt
@@ -35,7 +64,7 @@ Process 28473 stopped
3564
frame #0: 0x00000001000012e4 terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) at hello.kt:2
3665
1 fun main(args: Array<String>) {
3766
-> 2 println("Hello world")
38-
3 println("I need your clothes, your boots and your motocycle")
67+
3 println("I need your clothes, your boots and your motorcycle")
3968
4 }
4069
(lldb) n
4170
Hello world
@@ -44,89 +73,90 @@ Process 28473 stopped
4473
frame #0: 0x00000001000012f0 terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) at hello.kt:3
4574
1 fun main(args: Array<String>) {
4675
2 println("Hello world")
47-
-> 3 println("I need your clothes, your boots and your motocycle")
76+
-> 3 println("I need your clothes, your boots and your motorcycle")
4877
4 }
4978
(lldb)
5079
```
5180
52-
## Breakpoints
81+
## Set breakpoints
82+
83+
Modern debuggers provide several ways to set a breakpoint. See below for a tool-by-tool breakdown:
5384
54-
Modern debuggers provide several ways to set a breakpoint, see below for a tool-by-tool breakdown:
85+
### LLDB
5586
56-
### lldb
87+
* By name:
5788
58-
- by name
89+
```bash
90+
(lldb) b -n kfun:main(kotlin.Array<kotlin.String>)
91+
Breakpoint 4: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = 0x00000001000012e4
92+
```
5993

60-
```bash
61-
(lldb) b -n kfun:main(kotlin.Array<kotlin.String>)
62-
Breakpoint 4: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = 0x00000001000012e4
63-
```
94+
`-n` is optional, it's applied by default.
6495
65-
_``-n`` is optional, this flag is applied by default_
66-
- by location (filename, line number)
96+
* By location (filename, line number):
6797
68-
```bash
69-
(lldb) b -f hello.kt -l 1
70-
Breakpoint 1: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = 0x00000001000012e4
71-
```
98+
```bash
99+
(lldb) b -f hello.kt -l 1
100+
Breakpoint 1: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = 0x00000001000012e4
101+
```
72102
73-
- by address
103+
* By address:
74104
75-
```bash
76-
(lldb) b -a 0x00000001000012e4
77-
Breakpoint 2: address = 0x00000001000012e4
78-
```
105+
```bash
106+
(lldb) b -a 0x00000001000012e4
107+
Breakpoint 2: address = 0x00000001000012e4
108+
```
79109
80-
- by regex, you might find it useful for debugging generated artifacts, like lambda etc. (where used ``#`` symbol in name).
110+
* By regex. You might find it useful for debugging generated artifacts, like a lambda (with the `#` symbol in the name):
81111
82-
```bash
83-
3: regex = 'main\(', locations = 1
84-
3.1: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = terminator.kexe[0x00000001000012e4], unresolved, hit count = 0
85-
```
112+
```bash
113+
(lldb) b -r main\(
114+
3: regex = 'main\(', locations = 1
115+
3.1: where = terminator.kexe`kfun:main(kotlin.Array<kotlin.String>) + 4 at hello.kt:2, address = terminator.kexe[0x00000001000012e4], unresolved, hit count = 0
116+
```
86117
87-
### gdb
118+
### GDB
88119
89-
- by regex
120+
* By regex:
90121
91-
```bash
92-
(gdb) rbreak main(
93-
Breakpoint 1 at 0x1000109b4
94-
struct ktype:kotlin.Unit &kfun:main(kotlin.Array<kotlin.String>);
95-
```
122+
```bash
123+
(gdb) rbreak main(
124+
Breakpoint 1 at 0x1000109b4
125+
struct ktype:kotlin.Unit &kfun:main(kotlin.Array<kotlin.String>);
126+
```
96127
97-
- by name __unusable__, because ``:`` is a separator for the breakpoint by location
98-
99-
```bash
100-
(gdb) b kfun:main(kotlin.Array<kotlin.String>)
101-
No source file named kfun.
102-
Make breakpoint pending on future shared library load? (y or [n]) y
103-
Breakpoint 1 (kfun:main(kotlin.Array<kotlin.String>)) pending
104-
```
128+
* By name is _not_ possible because `:` is a separator for the breakpoint by location:
105129
106-
- by location
130+
```bash
131+
(gdb) b kfun:main(kotlin.Array<kotlin.String>)
132+
No source file named kfun.
133+
Make breakpoint pending on future shared library load? (y or [n]) y
134+
Breakpoint 1 (kfun:main(kotlin.Array<kotlin.String>)) pending
135+
```
107136
108-
```bash
109-
(gdb) b hello.kt:1
110-
Breakpoint 2 at 0x100001704: file /Users/minamoto/ws/.git-trees/hello.kt, line 1.
111-
```
137+
* By location:
112138
113-
- by address
139+
```bash
140+
(gdb) b hello.kt:1
141+
Breakpoint 2 at 0x100001704: file /Users/minamoto/ws/.git-trees/hello.kt, line 1.
142+
```
114143
115-
```bash
116-
(gdb) b *0x100001704
117-
Note: breakpoint 2 also set at pc 0x100001704.
118-
Breakpoint 3 at 0x100001704: file /Users/minamoto/ws/.git-trees/hello.kt, line 2.
119-
```
144+
* By address:
120145
121-
## Stepping
146+
```bash
147+
(gdb) b *0x100001704
148+
Note: breakpoint 2 also set at pc 0x100001704.
149+
Breakpoint 3 at 0x100001704: file /Users/minamoto/ws/.git-trees/hello.kt, line 2.
150+
```
122151
123-
Stepping functions works mostly the same way as for C/C++ programs.
152+
## Use stepping
124153
125-
## Variable inspection
154+
Stepping through functions works mostly the same way as for C/C++ programs.
126155
127-
Variable inspections for `var` variables works out of the box for primitive types.
128-
For non-primitive types there are custom pretty printers for lldb in
129-
`konan_lldb.py`:
156+
## Inspect variables
157+
158+
Variable inspection for `var` variables works out of the box for primitive types.
159+
For non-primitive types, there are custom pretty printers for LLDB in `konan_lldb.py`:
130160
131161
```bash
132162
λ cat main.kt | nl
@@ -173,9 +203,8 @@ Process 4985 launched: './program.kexe' (x86_64)
173203
(lldb)
174204
```
175205
176-
Getting representation of the object variable (var) could also be done using the
177-
built-in runtime function `Konan_DebugPrint` (this approach also works for gdb,
178-
using a module of command syntax):
206+
Getting representation of the object variable (`var`) could also be done using the
207+
built-in runtime function `Konan_DebugPrint` (this approach also works for GDB, using a module-specific syntax):
179208
180209
```bash
181210
0:b-debugger-fixes:minamoto@unit-703(0)# cat ../debugger-plugin/1.kt | nl -p
@@ -213,9 +242,56 @@ Process 80496 launched: './program.kexe' (x86_64)
213242
(lldb) expression -- (int32_t)Konan_DebugPrint(a_variable)
214243
(a_variable) one is 1(int32_t) $0 = 0
215244
(lldb)
245+
```
246+
247+
## Debug iOS applications
248+
249+
Debugging iOS applications sometimes involves analyzing crash reports in detail. Crash reports typically require
250+
symbolication, the process of translating memory addresses into readable source code locations.
251+
252+
To symbolicate addresses in Kotlin code (for example, for stack trace elements corresponding to Kotlin code), you need a
253+
special debug symbol (`.dSYM`) file. This file maps memory addresses in crash reports with actual locations in the source
254+
code, such as functions or line numbers.
255+
256+
The Kotlin/Native compiler generates `.dSYM` files for release (optimized) binaries on Apple platforms by default.
257+
When building in Xcode, the IDE looks for `.dSYM` files in standard locations and uses them automatically for symbolication.
258+
Xcode automatically detects `.dSYM` files in projects created from IntelliJ IDEA templates.
259+
260+
On other platforms, you can add debug information into the produced binaries (which increases their size)
261+
using the `-Xadd-light-debug` compiler option:
262+
263+
<tabs group="build-script">
264+
<tab title="Kotlin" group-key="kotlin">
216265
266+
```kotlin
267+
kotlin {
268+
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
269+
binaries.all {
270+
freeCompilerArgs += "-Xadd-light-debug=enable"
271+
}
272+
}
273+
}
217274
```
218275
276+
</tab>
277+
<tab title="Groovy" group-key="groovy">
278+
279+
```groovy
280+
kotlin {
281+
targets.withType(org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) {
282+
binaries.all {
283+
freeCompilerArgs += "-Xadd-light-debug=enable"
284+
}
285+
}
286+
}
287+
```
288+
289+
</tab>
290+
</tabs>
291+
292+
For more information about crash reports, see the [Apple documentation](https://developer.apple.com/documentation/xcode/diagnosing-issues-using-crash-reports-and-device-logs).
293+
219294
## Known issues
220295
221-
- performance of Python bindings.
296+
* Performance of Python bindings.
297+
* Expression evaluation in debugger tools is not supported, and currently there are no plans for implementing it.

docs/topics/native/native-ios-symbolication.md

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)