Advanced Debugging with Xcode and LLDB

## GCC? LLVM? LLDB? 

---
## LLVM(Low Level Virtual Machine)
- Xcode４からGCCを置き換えてデフォルトとして採用された
 - コンパイルが速い
 - コンパイルされたコードが速い
 - エラーメッセージがわかりやすい
 - 他のツールと連携しやすい

---
## LLDB
- **次世代の高性能デバッガ**
- Clang expressionパーサとかLLVM Disassemblerのような、より大きなLLVMプロジェクトにおいて再利用しやすいコンポーネントとしてビルドされる。
- もっと詳しい情報, チュートリアルは[こちらへ](http://lldb.llvm.org/)

---
## LLDBコマンド
 
```<noun> <verb> [-options [option-value]] [argument [argument...]]```

- 引数 (argument) が'-'から始まる場合、LLDBにオプションの終了位置を'--'で教えてやる必要がある

```(lldb) process launch --stop-at-entry -- -program_arg value```


---

## Swift Debugging Reliability
- Failed to get module from AST(abstract syntax tree) context
<img width="1192" alt="スクリーンショット 2018-07-10 14.15.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/f536dec6-d161-6efd-40c1-8e824315f965.png">

- Swift Type Resolution
<img width="1188" alt="スクリーンショット 2018-07-10 14.15.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/c03950d1-29b4-b6eb-203f-e240707eecac.png">

---

## Advanced Debugging Tips and Tricks

---

## 普段どのようにやっているか？
- 値の状態によって試してみたい
- 新しいコードを追加してみたい
- コード処理をスキップしてみたい
- Obj-Cコードの値を変更してみたい

---
## expression
- デバッグ中に値の状態を切り替えることができる
 - LLDB expressions can modify program state 
 - `(lldb) expression didSelectedHeight = false`
![WWDC 2018-07-10 14-20-13.png](https://qiita-image-store.s3.amazonaws.com/0/28329/eeb6e07c-fba6-967d-f868-12e1432323b9.png)




---
## inject code
- デバッグ中に新しいコードを追加してみたい
 - Use auto-continuing breakpoints with debugger commands to inject code live 
 - `expression dynamicAnimator.delegate =  self`
 <img width="546" alt="WWDC 2018-07-10 16-21-27.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/bb6dcc8c-8d19-3f05-b717-c1156afb2db4.png">

---  
## symbolic breakpoint & po
- 特定のコードではなく指定されたメソットにブレークポイントを入れて使う
 - Create dependent breakpoints using `breakpoint set --one-shot true`

![WWDC 2018-07-10 14-37-22.png](https://qiita-image-store.s3.amazonaws.com/0/28329/c8760e5d-2a85-00d1-fe52-e8860bbad345.png)
`breakpoint set — one-shot true — name “-[UILabel setText:]”`

 - `po $arg1 ($arg2, etc)` in assembly frames to print function arguments 

---
# breakpoint types
- (place)breakpoint
- exception breakpoint
- conditional breakpoint
- symbolic breakpoint

---
## thread jump
- コード処理をスキップできる (1)
 - Skip lines of code by dragging Instruction Pointer 
 - <img width="546" alt="WWDC 2018-07-10 14-41-24.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/f27d6e65-391d-f88a-9186-f6426dfe813c.png">
 
---
## thread jump
- コード処理をスキップできる (2)
 - Skip lines of code by `thread jump --by 1`
![WWDC 2018-07-10 14-42-41.png](https://qiita-image-store.s3.amazonaws.com/0/28329/04e44ed8-ee9b-89b1-78e0-14a45bb34ac9.png)

---
## custom debug string
- extension <Class>: CustomDebugStringConvertible
<img width="545" alt="WWDC 2018-07-10 14-44-33.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/6c5744c5-1fc5-23af-23ad-604f5aded725.png">
![WWDC 2018-07-10 14-44-53-2.png](https://qiita-image-store.s3.amazonaws.com/0/28329/af78d362-cd22-d18f-269b-7bc7a5e0ebbe.png)
 
---
## Watchpoint
- Pause when variables are modified by using watchpoints
    - 特定の値をwatchに設定する
    ![WWDC 2018-07-10 14-47-48.png](https://qiita-image-store.s3.amazonaws.com/0/28329/1e2e7e85-ca1e-d95d-e911-7e7c5f9c22d7.png)
    - その値を参照し、アクションを実行する
    ![WWDC 2018-07-10 14-48-59.png](https://qiita-image-store.s3.amazonaws.com/0/28329/55d5df5f-fad4-9e8e-f65d-df450b333a98.png)


---
## UIKitのようなObj-Cコードをいじる (1)
- Evaluate Obj-C code in Swift frames with `expression -l objc -O -- <expr>` 
![WWDC 2018-07-10 14-53-44.png](https://qiita-image-store.s3.amazonaws.com/0/28329/82440701-c99a-13cb-6c79-82581252bccf.png)
```expression -l objc -O -- [`self.view` recursiveDescription]```

---
## UIKitのようなObj-Cコードをいじる (2)
- `po unsafeBitCast(<memory addre
ss>, to: <Object>)`
![WWDC 2018-07-10 14-55-21.png](https://qiita-image-store.s3.amazonaws.com/0/28329/8d3c8b0e-d717-ede3-b4f9-7f2d5ad3d7bb.png)


---
## UIKitのようなObj-Cコードをいじる (3)
- Flush view changes to the screen using `expression CATransaction.flush()`
<img width="546" alt="WWDC 2018-07-10 14-55-53.png" src="https://qiita-image-store.s3.amazonaws.com/0/28329/bdfc069e-842c-5b39-2cda-1cba7ac0de00.png">
    
---
## LLDBコマンドをカスタムしてもっと強力に使う
- ~/.lldbinit
    - デバッグの起動時に読み込んでくれる。このファイル中は(Pythonではなく)LLDBのコマンドだけが実行できる。
    - その中でPythonスクリプトを読み込むことができる。
- command alias
    - `command alias poc expression -l objc -O -- `
    
- command script import
    - `command script import ~/nudge.py`

---
## LLDB Command Map - [download](https://www.dropbox.com/s/9sv67e7f2repbpb/lldb-commands-map.png?dl=0)
![lldb-commands-map.png](https://qiita-image-store.s3.amazonaws.com/0/28329/dadc040e-e5fd-a504-440c-e5f3653ddaa3.png)

---
## Reference
"Debugging Swift code with LLDB"
https://medium.com/flawless-app-stories/debugging-swift-code-with-lldb-b30c5cf2fd49

"More than po: Debugging in LLDB"
https://www.slideshare.net/micheletitolo/more-than-po-debugging-in-lldb-78570000

"Video : Advanced Debugging with Xcode and LLDB  / WWDC18 "
https://developer.apple.com/videos/play/wwdc2018/412/