gdbを使ってrubyのプログラム中のC言語で書かれた箇所をデバッグした際の作業ログ

個人用メモです。


## 経緯

諸事情により、puts関数の中で関数の実行を止め、変数の中身を見たくなった。
[puts関数](https://github.com/ruby/ruby/blob/0ca00e2cb74f9d07d27844d97c29c208caab95a7/io.c#L8349-L8380) はC言語で書かれている。

https://techlife.cookpad.com/entry/2015/12/09/163746

に書いてある方法でデバッグしてみる。


## 手順

### 1. debug可能なrubyコマンドを生成する

```sh
$ git clone https://github.com/ruby/ruby
$ cd ruby
# ./configureを(再)生成
$ autoreconf
# -O0で最適化を無効にする。debugflagsはデフォルトで "-ggdb3" になっています。
$ ./configure optflags="-O0"
$ make
$ make install
```

これでrubyディレクトリ内に、debug可能なrubyコマンドが生成される。


### 2. puts関数を走らせるスクリプトを用意する。

以下のような`hello.rb`ファイルを ./ruby ディレクトリ内に生成する。

```rb
puts 'xxx'
```


### 3. gdbコマンドを実行する

```sh
$ sudo gdb --args ./ruby ./hello.rb
 
GNU gdb (GDB) 11.1
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin21.1.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./ruby...
Reading symbols from /Users/daiki-kudo/repos/ruby-debug/ruby/ruby.dSYM/Contents/Resources/DWARF/ruby...
```

⏫sudoをつけないと、後に`(gdb) run`した時に、エラーが出て実行できなかった。


<details><summary>詳細</summary><div>

```
(gdb) run
Starting program: /Users/daiki-kudo/repos/ruby-debug/ruby/ruby ./hello.rb
Unable to find Mach task port for process-id 37617: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))
```

</div></details>



```
(gdb) break rb_io_puts
Breakpoint 1 at 0x100105e64: file io.c, line 8356. 
```

⏫期待通りio.c内にbreakpointが設定された！！！

```
(gdb) run
Starting program: /Users/daiki-kudo/repos/ruby-debug/ruby/ruby ./hello.rb
Unable to find Mach task port for process-id 37008: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))
```

runすると、breakpointで、、、、止まらない！！！
(以下を吐き出してプログラムが停止。)

```
(gdb) run
Starting program: /Users/daiki-kudo/repos/ruby-debug/ruby/ruby 
[New Thread 0x2503 of process 56926]

```

### 4. libthread_dbをインストールしようと試みる

https://techlife.cookpad.com/entry/2015/12/09/163746 を読むと、run時のログは以下。


<details><summary>クックパッドブログのログ(引用)</summary><div>

```
(gdb) run
Starting program: /home/vagrant/ruby/ruby ./hello.rb
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
[New Thread 0xb7ae5b40 (LWP 2272)]
```

</div></details>





これと比較し、どうやら`libthread_db`たるものがOFFになっておらず、実行中のスレッド上でのデバッグがうまくいっていないことが原因ではないかと予測した。

確かに手元のdbgコンソールの出力を見ても、`libthread-db:  Auto-loading of inferior specific libthread_db is on.`の一行が存在しない。(c.f. https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading.html)


```
(gdb) show auto-load
auto-load gdb-scripts:  Auto-loading of canned sequences of commands scripts is on.
auto-load local-gdbinit:  Auto-loading of .gdbinit script from current directory is on.
auto-load python-scripts:  Auto-loading of Python scripts is on.
auto-load safe-path:  List of directories from which it is safe to auto-load files is :${prefix}/share/auto-load.
auto-load scripts-directory:  List of directories from which to load auto-loaded scripts is :${prefix}/share/auto-load.

```

結局色々調べたが、

- そもそもlibthread_dbがローカル(Debian)に入っているのかわからん
- どうやってインストールしてくるのかもようわからん(あんまドキュメントが見つからん)

と言うことで、linuxコンテナをdockerで立てることにした。

### 4. Linuxコンテナでデバッグする

以下参照。

https://github.com/kudojp/ruby-c-extention-debug-on-linux

無事デバッグできるようになった👏


```sh
(gdb) break rb_io_puts
Breakpoint 1 at 0x55c8eec73f4e: file io.c, line 8351.
(gdb) run
Starting program: /ruby/ruby ./hello.rb
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, rb_io_puts (argc=1, argv=0x7f7c44bdc048, out=140171705695520) at io.c:8351
8351    {
```