hiroshi hatake
cosmo****@gmail*****
2015年 1月 17日 (土) 22:11:25 JST
畑ケです。 >>>> 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のこのバグを踏んでしまったというわけで > す。 なるほど、詳細な解説ありがとうございます。 こちらでもJenkinsのログをあさってみた所、 12/21 〜 12/26の間のどこかでバグを踏むコードが入ったんだろうということが 分かりました。 で、実際にMariaDBのバグを踏んでいたコミットはこれみたいです: https://github.com/mroonga/mroonga/commit/dd097fe207836863b1264894247f11b67fa69d2d # もう少し頻繁にJenkinsを動かしていれば…と思いました。Windows用のCIを何 とかしたいですね。。。 > ちなみに、この処理は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に報告してもらえないでしょ > うか? > 報告しました! https://mariadb.atlassian.net/browse/MDEV-7475 # この問題でCentOS 6.5も引っかかっているという認識でいいんでしょうか。。。