前に作成した 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 >