らんだむな記憶

blogというものを体験してみようか!的なー

CRuby (2)

CRuby - らんだむな記憶 の続き。

[test.rb]

# -*- coding: utf-8 -*-

system("ls")
puts "Hello, ruby! (こんにちは、ruby!)"

などとして、

cgdb --args ./ruby test.rb 

とする。素の gdb よりは幾らか辛さが薄まる。
文字列の生成については https://github.com/ruby/ruby/blob/v3_0_1/string.c#L815 と思われるので、

(gdb) b string.c:815
Breakpoint 1 at 0x19393c: string.c:815. (46 locations)
(gdb) r

ブレークポイントまで進める。が・・・この関数はかなりの回数呼ばれているようでもの凄い回数ここでブレークしてしまう・・・。このアプローチは良くないのでやめる。CPython と同様に分かりやすいところで一旦ブレークさせて踏み台にする。

https://github.com/ruby/ruby/blob/v3_0_1/process.c#L4739 が組み込み関数の system に対応するはずなので、まずは

(gdb) b process.c:4739
Breakpoint 1 at 0x129b4a: file process.c, line 4739.
(gdb) r

して、ブレークさせる。因みにこれは当たりっぽい。引数は VALUE *argv で来ているようなのだが、https://github.com/ruby/ruby/blob/v3_0_1/include/ruby/internal/value.h#L28

typedef uintptr_t VALUE;

VALUE の正体だと思うので、大変につらい。

(gdb) p ((char**)argv)[1]
$1 = 0x5567e6a86288 "\032`\036"

してみてもよくは分からない。この時点で

(gdb) b string.c:815
Breakpoint 1 at 0x19393c: string.c:815. (46 locations)

して、ここでブレークさせると、

(gdb) c
Continuing.

Breakpoint 2, str_new (len=2, ptr=0x55f460352970 "ls", klass=94508071954480) at string.c:815
815         return str_new0(klass, ptr, len, 1);

となる。おっと、system 関数に渡した文字列 "ls" か・・・。なるほど。