LLDB　使い方まとめ 2.0


微妙にgdbと違うため、メモ
xcodeはもちろん、
コマンドラインからデバッグすることができます。


## LLDB 起動方法

```
lldb -f ./$(TARGET)
```


##実行

lldbプロンプトにて

```
(lldb)r
```

'r'の一文字だけでリセット＆RUN


##break


```関数break
(lldb)br set -n SomeFunc()
```

関数名などは途中入力でも[TAB]補完が効きます.

```c++メンバメソッドbreak
(lldb)br set -n CSome::UpdateView()
```

```File名/行番号指定break
(lldb)br set -f some.c -l 113
```

some.cpp の113行目にbreakを打ちます.
113行目に有効なコードが存在しない場合でも、
付近の有効なコードにbreakを打ち込んでもらえます。

##break-point 一覧表示

```breakpoint全て表示
(lldb)br li
```

フルスペル"break list" でも可だが、"br li" で短縮でも可。



```出力サンプル
Current breakpoints:

4: name = 'main', locations = 1, resolved = 1, hit count = 1
  4.1: where = gsh`main + 30 at gshell.cpp:545, address = 0x00000001000031ee, resolved, hit count = 1

5: name = 'Doc2Win::UpdateView()', locations = 1, resolved = 1, hit count = 0
  5.1: where = gsh`Doc2Win::UpdateView() + 12 at document2window.cpp:72, address = 0x000000010000991c, resolved, hit count = 0
```

## Step実行

```
(lldb)s
```

's' 1文字でOK


## Continue実行

```
(lldb)c
```

'c' 1文字でOK


## WATCH変数の追加

```
(lldb)watch set var 変数名
```

## WATCH変数の列挙

```
(lldb)watch list
```

```出力サンプル
Number of supported hardware watchpoints: 4
Current watchpoints:
Watchpoint 1: addr = 0x100046750 size = 4 state = disabled type = w
    watchpoint spec = 'pid_root'
    new value: 0
```


## 全スレッド列挙

```
(lldb)th list
```

```
Process 12205 stopped
* thread #1: tid = 0x46462, 0x00007fff8c76e306 libsystem_kernel.dylib`__read_nocancel + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  thread #2: tid = 0x46480, 0x00007fff8c76e486 libsystem_kernel.dylib`__semwait_signal + 10
  thread #3: tid = 0x46481, 0x00007fff8c76e486 libsystem_kernel.dylib`__semwait_signal + 10
  thread #4: tid = 0x46482, 0x00007fff8c76e486 libsystem_kernel.dylib`__semwait_signal + 10
```

## スレッド選択

th list で表示されている #n でカレントスレッドを選択します

```
(lldb)th sel 2　　　#2を選択したい場合は2だけ。'#'は不要
```

```出力サンプル
* thread #2: tid = 0x46480, 0x00007fff8c76e486 libsystem_kernel.dylib`__semwait_signal + 10
    frame #0: 0x00007fff8c76e486 libsystem_kernel.dylib`__semwait_signal + 10
libsystem_kernel.dylib`__semwait_signal + 10:
-> 0x7fff8c76e486:  jae    0x7fff8c76e490            ; __semwait_signal + 20
   0x7fff8c76e488:  movq   %rax, %rdi
   0x7fff8c76e48b:  jmp    0x7fff8c769cc8            ; cerror
   0x7fff8c76e490:  retq
```

## Frame情報出力

```
(lldb)fr info
```

```出力サンプル
frame #0: 0x00007fff8c76e306 libsystem_kernel.dylib`__read_nocancel + 10
```

## Frame選択
```
(lldb)fr sel 6
```

```出力サンプル
frame #6: 0x0000000100004344 gsh`PromptRunLoop() + 820 at gshell.cpp:235
   232 				StrReplaceCmdLine.clear();
   233 			}
   234
-> 235 			int ch = GSHELL_Getc();
   236 			if( EOF == (s8)ch )				continue;
   237 			if( IsCR(ch) )
   238 			{
```

### Frame内のローカル変数を全て表示

```
(lldb)fr va
```

```出力サンプル
(int) ch = 1
```

### 任意のクラス・インスタンスのメンバ変数などを参照したい場合
```
frame #1: 0x0000000100059a8d ish.debug`mrb_print_error(mrb=0x0000000100411560) + 45 at print.c:55
   52  	  mrb_value s;
   53  	
   54  	  mrb_print_backtrace(mrb);
-> 55  	  s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
   56  	  if (mrb_string_p(s)) {
   57  	    fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stderr);
   58  	    putc('\n', stderr);
```

mrb->exc の中身を参照したい場合

```
print mrb->exc
```
または

```
p mrb->exc
```

グローバル変数などもprintで参照できます。

### バイナリダンプ
ポインタ変数 **mrb** が指し示す先をダンプしたい場合

```
memory read mrb
```

省略形は

```
m r mrb
```


```
0x100411560: 00 00 00 00 00 00 00 00 50 c2 05 00 01 00 00 00  ........P?......
0x100411570: 00 00 00 00 00 00 00 00 00 1a 41 00 01 00 00 00  ..........A.....
```

デフォで32Byte出力されます。
任意の長さを指定するには

```
m r -c 256 mrb
```

```
0x100411560: 00 00 00 00 00 00 00 00 50 c2 05 00 01 00 00 00  ........P?......
0x100411570: 00 00 00 00 00 00 00 00 00 1a 41 00 01 00 00 00  ..........A.....
0x100411580: 00 1a 41 00 01 00 00 00 00 00 00 00 00 00 00 00  ..A.............
0x100411590: 00 00 00 00 00 00 00 00 60 68 04 01 01 00 00 00  ........`h......
0x1004115a0: d0 af 04 01 01 00 00 00 70 af 04 01 01 00 00 00  Я......p?......
0x1004115b0: a0 af 04 01 01 00 00 00 80 ae 04 01 01 00 00 00  ??.......?......
0x1004115c0: 40 91 04 01 01 00 00 00 90 89 04 01 01 00 00 00  @...............
0x1004115d0: f0 83 04 01 01 00 00 00 a0 79 04 01 01 00 00 00  ?.......?y......
0x1004115e0: 30 7d 04 01 01 00 00 00 00 a4 04 01 01 00 00 00  0}.......?......
0x1004115f0: b0 a2 04 01 01 00 00 00 80 a5 04 01 01 00 00 00  ??.......?......
0x100411600: d0 97 04 01 01 00 00 00 60 a1 04 01 01 00 00 00  ?.......`?......
0x100411610: 00 d4 00 04 01 00 00 00 00 00 00 00 00 00 00 00  .?..............
0x100411620: 00 f0 03 01 01 00 00 00 85 03 00 00 00 00 00 00  .?..............
0x100411630: e0 16 41 00 01 00 00 00 64 00 00 00 0b 00 00 00  ?.A.....d.......
0x100411640: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  ................
0x100411650: 00 00 00 00 00 00 00 00 1a 03 00 00 00 00 00 00  ................
```



## バックトレース

```
(lldb)bt
```
これはgdbと同じです。

```出力サンプル
* thread #1: tid = 0x43bf0, 0x000000010002dba6 gsh`Logger::Logger(this=0x0000000100200000, fname_log=0x0000000100042af2, bNoHeader=false, bDump=true) + 38 at logger.cpp:148, queue = 'com.apple.main-thread', stop reason = step in
  * frame #0: 0x000000010002dba6 gsh`Logger::Logger(this=0x0000000100200000, fname_log=0x0000000100042af2, bNoHeader=false, bDump=true) + 38 at logger.cpp:148
    frame #1: 0x000000010000321e gsh`main(argc=1, argv=0x00007fff5fbff988) + 78 at gshell.cpp:545
    frame #2: 0x00007fff88abd5c9 libdyld.dylib`start + 1
    frame #3: 0x00007fff88abd5c9 libdyld.dylib`start + 1
```

## 全てのスレッドのバックトレース

```
(lldb)bt all
```
 


## デバッグ対象プログラムの一時中断

```
CTRL-C
```
^Cで中断させると、デバッガのプロンプトに戻ります。


## 終了

```
(lldb)quit
```