前に作成した df_make.c を以下のようにコンパイルする
$ MAKEFLAGS="CFLAGS=-g" R CMD SHLIB df_make.c
Windowsの場合
> R CMD SHLIB -d df_make.c
コマンドラインなら R -d gdb あるいは Emacs なら C-u M-x R として引数を -d gdb で指定
(gdb) run
> dyn.load("df_make.so")
> .Call("dfmake", as.character("石田"),as.character("山田"),as.character("加藤"))
Term Freq
1 石田 10
2 山田 20
3 加藤 30
>
とりあえず動くのは確認
> C-c C-c Program received signal SIGINT, Interrupt. 0x00007ffff716cfd3 in select () from /lib/libc.so.6 (gdb) (gdb) b dfmake Breakpoint 1 at 0x7fffef994b11: file df_make.c, line 12. (gdb) signal 0 Continuing with no signal. >
関数 dfmake にブレークポイントを挿入した
> .Call("dfmake", as.character("石田"),as.character("山田"),as.character("加藤"))
Breakpoint 1, dfmake (x=0x1653b78, y=0x1653ba8, z=0x1653bd8) at df_make.c:12
12 int pc=0;
(gdb) where
#0 dfmake (x=0x1653b78, y=0x1653ba8, z=0x1653bd8) at df_make.c:12
#1 0x00007ffff78e34dc in do_dotcall (call=0x14b4ab0, op=<value optimized out>, args=0x607918,
env=<value optimized out>) at dotcode.c:846
#2 0x00007ffff7914c93 in Rf_eval (e=<value optimized out>, rho=<value optimized out>) at eval.c:508
#3 0x00007ffff794a66a in Rf_ReplIteration (rho=0x64e8b0, savestack=0, browselevel=<value optimized out>,
state=0x7fffffffd550) at main.c:257
#4 0x00007ffff794a8f9 in R_ReplConsole (rho=0x64e8b0, savestack=0, browselevel=0) at main.c:306
#5 0x00007ffff794ae30 in run_Rmainloop () at main.c:1009
#6 0x000000000040092b in main (ac=<value optimized out>, av=<value optimized out>) at Rmain.c:32
#7 0x00007ffff70acc4d in __libc_start_main () from /lib/libc.so.6
#8 0x0000000000400819 in _start ()
(gdb) n
15 const char* xx = CHAR(STRING_ELT(x, 0));//解析対象文字列
(gdb) n
16 const char* yy = CHAR(STRING_ELT(y, 0));//解析対象文字列
(gdb) n
17 const char* zz = CHAR(STRING_ELT(z, 0));//解析対象文字列
(gdb) p R_inspect(x)
@1ae7698 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
@1ae7518 09 CHARSXP g0c1 [gp=0x28] "石田"
$3 = (struct SEXPREC *) 0x1ae7698
(gdb) p xx
$1 = 0x1ae7540 "石田"
(gdb) n
19 PROTECT(df = allocVector(VECSXP, 2));// ベクトル要素を二つ持つ data.frame
(gdb) info locals
pc = 0
df = 0x14b4ab0
varlabels = 0x7ffff7ddbbe8
tmp = 0x607918
row_names = 0xaefabc970ca4e100
xx = 0x1ae7540 "石田"
yy = 0x1ae75a0 "山田"
zz = 0x1ae7660 "加藤"
(gdb) set var zz ="さとう" // 値を変更
(gdb) info locals
pc = 0
df = 0x14b4ab0
varlabels = 0x7ffff7ddbbe8
tmp = 0x607918
row_names = 0xaefabc970ca4e100
xx = 0x1ae7540 "石田"
yy = 0x1ae75a0 "山田"
zz = 0xa63ad0 "さとう"
(gdb) n
20 pc++;
(gdb) b 54 // ブレークポイントを 54 行目に
Breakpoint 2 at 0x7fffef994ec2: file df_make.c, line 54.
(gdb) c
Continuing.
Breakpoint 2, dfmake (x=0x1653b78, y=0x1653ba8, z=0x1653bd8) at df_make.c:54
54 UNPROTECT(pc);
(gdb) p df
$2 = (SEXP) 0x164f160
(gdb) p R_PV(df)
Term Freq
1 石田 10
2 山田 20
3 さとう 30
$3 = void
(gdb) p Rf_PrintValue(df)
Term Freq
1 石田 10
2 山田 20
3 さとう 30
$4 = void
(gdb) p Rf_PrintValue(df->attrib)
$class
[1] "data.frame"
$names
[1] "Term" "Freq"
$row.names
[1] "1" "2" "3"
$5 = void
(gdb) p df
$6 = (SEXP) 0xe83098
(gdb) p *df //素の構造
$7 = {sxpinfo = {type = 19, obj = 1, named = 0, gp = 0, mark = 0, debug = 0, trace = 0, spare = 0,
gcgen = 0, gccls = 2}, attrib = 0xda3818, gengc_next_node = 0xe830d0, gengc_prev_node = 0xe83060, u = {
primsxp = {offset = 2}, symsxp = {pname = 0x2, value = 0x1a067b0, internal = 0xe830d0}, listsxp = {
carval = 0x2, cdrval = 0x1a067b0, tagval = 0xe830d0}, envsxp = {frame = 0x2, enclos = 0x1a067b0,
hashtab = 0xe830d0}, closxp = {formals = 0x2, body = 0x1a067b0, env = 0xe830d0}, promsxp = {
value = 0x2, expr = 0x1a067b0, env = 0xe830d0}}}
(gdb) c // あるいは signal 0
Continuing.
Term Freq
1 石田 10
2 山田 20
3 さとう 30
>