Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
デバッガで mysqlクライアントを実行してみよう。
r(run) コマンドが実行で、後にmysqlクライアントを起動するときに指定する オプションを入れる。
たとえば、
shell$ mysql -u root
というのをgdbで行なうときには、 r の引数として、 -u root だけを入力する。
(gdb) r -u root Starting program: /usr/local/mysql/bin/mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 to server version: 5.0.10-beta-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
すると、mysqlが動きだし、mysql> というmysqlのコマンドプロンプトが 表示され、入力待ち状態になっている。
mysql> SELECT '漢字'; +------+ | 漢字 | +------+ | 漢字 | +------+ 1 row in set (0.00 sec) mysql>
確かに動作している。
mysqlを抜けてgdbに戻るには、
mysql> quit Bye Program exited normally. (gdb)
が普通のやり方だが、CTRL-C により無理矢理中断することもできる。
mysql> Program received signal SIGINT, Interrupt. 0xffffe002 in ?? () (gdb)
強引だが、目的が達成すればよしとしよう。
動作が変になって暴走しちゃったときには、 CTRL-Cで止めるしかなくなるので、これは重要な止め方で憶えておかねばならない。
ブレイクポイントの設定
注目している関数は、print_table_data()である。 さっそく、この関数が呼び出されると、 入口で止まるようにブレークポイントを設定してみよう。
breakpoint の設定は、b コマンドである。 引数として、関数名を指定する。
(gdb) b print_table_data Breakpoint 1 at 0x8054c8d: file sql_string.h, line 47. (gdb)
なんか、メッセージが変なファイルと行数を示しているのが気になる。 mysql.cc ではなく、sql_string.h の中になってしまった。
とにかくmysqlを起動して、SELECT文を実行してみよう。
(gdb) r -u root
Starting program: /usr/local/mysql/bin/mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15 to server version: 5.0.10-beta-debug-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> SELECT '漢字';
Breakpoint 1, print_table_data (result=0x809a3a0) at sql_string.h:47
47 {
(gdb)
やはり指定した関数とは違うところだけれど、取り敢えず n(next) で1行ずつ実行してみよう。
(gdb) n 48 alloced=0; Alloced_length=0; (void) real_alloc(length_arg); (gdb) n 49 str_charset= &my_charset_bin; (gdb) n 2176 num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result)); (gdb) n (gdb) n 2177 if (info_flag) (gdb)
やっと目的の場所(テーブル表示関数の入口)に辿り着いたようなので、 where コマンドで、どこに居るかを調べてみよう。
(gdb) where
#0 print_table_data (result=0x809a3c0) at mysql.cc:2177
#1 0x08054507 in com_go (buffer=0x8076b30, line=0x0) at mysql.cc:1957
#2 0x08052ef7 in add_line (buffer=@0x8076b30, line=0x809a320 "SELECT '漢字';",
in_string=0xbfffe07e "", ml_comment=0xbfffe07f) at mysql.cc:1216
#3 0x08052956 in read_lines (execute_commands=true) at mysql.cc:1057
#4 0x08051e04 in main (argc=6, argv=0x807d018) at mysql.cc:471
#5 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
l(list) コマンドで、文字幅調整をしているらしい場所までプログラムを表示 してみよう。
(gdb) l
2229 }
2230 else
2231 {
2232 uint currlength= (uint) lengths[off];
2233 uint numcells= charset_info->cset->numcells(charset_info,
2234 str, str + currlength);
2235 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
2236 maxlength + currlength - numcells, str);
2237 }
2238 }
この elseの中で文字幅調整しているようである。 入口にブレイクポイントを設けよう。
(gdb) b Breakpoint 3 at 0x8054d02: file mysql.cc, line 2184. (gdb)
色々設定しているうちに、どこにブレイクポイントを設定したか分からなくなる。 info という様々なデバッガの情報を表示するコマンドが用意されていて、 info break で現在設定されているブレイクポイントが示される。
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x08054c8d in print_table_data at sql_string.h:47
breakpoint already hit 1 time
2 breakpoint keep y 0x08054f62 in print_table_data at mysql.cc:2232
(gdb)
今日は、随分長くなったので、ここで中断しよう。
次へ:SET NAMESで変更してもcharset_infoはlatin1のままだ
フィードバック:
There is no comment.