Hightman 论坛

完整版: It crashes for MySQL 5.1.35, and solution
您当前正在浏览的是一个简化版本. 要观看完整版本, 请点这儿.
Environment:
CentOS 5.3 X86_64

To reproduce:

1. add a non-empty stopwords list and make sure the filename matches the rules like 'stops.utf8.txt' or 'stops.txt' so it can be loaded by the plugin.

2. start mysql server by 'service mysql start'

3. stop mysql server by 'service mysql stop'

you will see it crashes for trying to free memory at an incorrect address.


Reason:

the crash is because the pointer passed to function stop_word_free is not the one allocated at function stop_tree_load. For some reason, the one assumed to be freed still points to a valid and correct string. :-)

Solution:

Use mysql tree to manage the allocation / free of tree elements.

Attached is the result of 'diff -EbBu' for plugin_scws.c:

Discussion is welcomed.
thanks for your report, I have fixed it by modifing the code as following:

代码:
*** plugin_scws.c.orig        2009-06-11 09:26:11.000000000 +0800
--- plugin_scws.c       2009-06-11 09:25:26.000000000 +0800
***************
*** 107,121 ****
  };
  static FTSCWS_REC *scws_base = NULL;
  
! static int stop_word_cmp(void* cmp_arg __attribute__((unused)), char *w1, char *w2)
  {
!   return strcasecmp(w1, w2);
  }
  
! static void stop_word_free(char *w, TREE_FREE action, void *arg __attribute__((unused)))
  {
    if (action == free_free)
!     my_free(w, MYF(0));
  }
  
  static TREE *stop_tree_load(char *fpath)
--- 107,121 ----
  };
  static FTSCWS_REC *scws_base = NULL;
  
! static int stop_word_cmp(void* cmp_arg __attribute__((unused)), char **w1, char **w2)
  {
!   return strcasecmp(*w1, *w2);
  }
  
! static void stop_word_free(char **w, TREE_FREE action, void *arg __attribute__((unused)))
  {
    if (action == free_free)
!     my_free(*w, MYF(0));
  }
  
  static TREE *stop_tree_load(char *fpath)
***************
*** 157,163 ****
        if (ptr == str) continue;
        
        ptr = (uchar *)my_strndup((const char *)str, ptr - str, MYF(MY_WME));
!       if (!tree_insert(wtree, ptr, 0, NULL))
        {
          my_free(ptr, MYF(0));
          break;
--- 157,163 ----
        if (ptr == str) continue;
        
        ptr = (uchar *)my_strndup((const char *)str, ptr - str, MYF(MY_WME));
!       if (!tree_insert(wtree, &ptr, 0, NULL))
        {
          my_free(ptr, MYF(0));
          break;
哈哈,MySQL改动得很不地道啊。
不过为什么不干脆让MySQL去管理tree呢?谁知道哪天MySQL会不会又改回去了呢。 :-)
(2009-06-11 07:54 PM)新用户 提到: [ -> ]哈哈,MySQL改动得很不地道啊。
不过为什么不干脆让MySQL去管理tree呢?谁知道哪天MySQL会不会又改回去了呢。 :-)

我这个作法是直接照抄自 myisam/里自带的FT功能的ftp_stopwords管理办法, 呵呵, 那边是结构体, 所以在写的过程中写错了呵, 多谢指出 微笑
Reference URL's