Open Source WEB

デバッガで 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)

今日は、随分長くなったので、ここで中断しよう。


戻る:gdbからmysqlクライアントを起動してみよう

次へ:SET NAMESで変更してもcharset_infoはlatin1のままだ


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us