Kouhei Sutou
kou****@clear*****
2015年 1月 16日 (金) 22:53:09 JST
須藤です。 In <54AFE****@gmail*****> "[groonga-dev,03061] Re: MariaDBバンドル版Mroonga 4.09でMroongaがインストール出来ない問題について" on Fri, 09 Jan 2015 23:41:35 +0900, hiroshi hatake <cosmo****@gmail*****> wrote: >>> Visual Studio のデバッガで追って確認してみました。 >>> >>> 手順) >>> 1. Visual Studioのデバッガでmysqldをアタッチ >>> 2. mysqlクライアントにshare\mroonga\install.sqlを食べさせる。 >>> >>> すると、 >>> >>>> 3964 ((o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT | >>>> 3965 PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR)) もう一度ソースを見たんですけど、これMariaDBのバグですねぇ。 MariaDB 10.0.15もそうですし、5.5.41もバグっています。 詳細を↓で説明するのでMariaDBに報告してもらえませんか? ↑のo->flagsにはinclude/mysql/plugin.hの↓をORで合わせて指定 します。 #define PLUGIN_VAR_BOOL 0x0001 #define PLUGIN_VAR_INT 0x0002 #define PLUGIN_VAR_LONG 0x0003 #define PLUGIN_VAR_LONGLONG 0x0004 #define PLUGIN_VAR_STR 0x0005 #define PLUGIN_VAR_ENUM 0x0006 #define PLUGIN_VAR_SET 0x0007 #define PLUGIN_VAR_DOUBLE 0x0008 #define PLUGIN_VAR_UNSIGNED 0x0080 #define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */ #define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */ #define PLUGIN_VAR_NOSYSVAR 0x0400 /* Not a server variable */ #define PLUGIN_VAR_NOCMDOPT 0x0800 /* Not a command line option */ #define PLUGIN_VAR_NOCMDARG 0x1000 /* No argument for cmd line */ #define PLUGIN_VAR_RQCMDARG 0x0000 /* Argument required for cmd line */ #define PLUGIN_VAR_OPCMDARG 0x2000 /* Argument optional for cmd line */ #define PLUGIN_VAR_MEMALLOC 0x8000 /* String needs memory allocated */ で、これの罠なのが、PLUGIN_VAR_BOOLからPLUGIN_VAR_DOUBLEは フラグじゃない使いかたで、PLUGIN_VAR_UNSIGNED以降はフラグな 使い方なんです。 なので、 (o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR という条件の o->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC) みたいにビット単位でORをしてそれをANDしたら0になるかどうかで フラグが立っているかを確認するのはOKです。 しかし、 (o->flags & PLUGIN_VAR_STR) == PLUGIN_VAR_STR という使い方はNGです。 #define PLUGIN_VAR_STR 0x0005 #define PLUGIN_VAR_SET 0x0007 という定義になっているんですが、o->flagsが PLUGIN_VAR_SETのときは↑の式は成り立ちます。 (PLUGIN_VAR_SET & PLUGIN_VAR_STR) == PLUGIN_VAR_STR がtrueになるということです。 これは、0x0007と0x0005をANDすると0x0005になるからです。 で、Mroonga 4.0.9から追加した mroonga_boolean_mode_syntax_flagsは PLUGIN_VAR_SETなんですよ。 https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L965 static MYSQL_THDVAR_SET(boolean_mode_syntax_flags, 前述の通りPLUGIN_VAR_SETがPLUGIN_VAR_STRとして扱われてしまい ます。しかし、PLUGIN_VAR_SET用の準備しかしていないので、 PLUGIN_VAR_STRとして扱われると変なところにアクセスしてしまい ます。 ということで、MariaDBのこのバグを踏んでしまったというわけで す。 ちなみに、この処理はMySQLにはなくてMariaDBにだけある処理なの で、MySQLではクラッシュしません。 MariaDB 5.5.40用なんですが、参考までにパッチを張っておきます。 0x000fのところがダサいんですが、MariaDBの人ならもっとキレイ にしてくれそうな気がします。 --- mariadb-5.5.40.orig/sql/sql_plugin.cc 2014-10-08 22:19:52.000000000 +0900 +++ mariadb-5.5.40/sql/sql_plugin.cc 2015-01-16 22:51:32.957073875 +0900 @@ -3916,8 +3916,8 @@ we copy string values to a plugin's memroot. */ if (mysqld_server_started && - ((o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT | - PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR)) + ((o->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC)) == 0) && + ((o->flags & 0x000f) == PLUGIN_VAR_STR)) { sysvar_str_t* str= (sysvar_str_t *)o; if (*str->value) と、こういうことなんですが、MariaDBに報告してもらえないでしょ うか? -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/ コードリーダー育成支援 - 自然とリーダブルコードを書くチームへ: http://www.clear-code.com/services/code-reader/