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"
か・・・。なるほど。