Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-17177

Crash in Item_func_in::cleanup() for SELECT executed via prepared statement

Details

    • Bug
    • Status: Closed (View Workflow)
    • Critical
    • Resolution: Fixed
    • 10.2(EOL), 10.3(EOL), 10.4(EOL)
    • 10.2.32, 10.3.23, 10.4.13, 10.5.3
    • Server
    • None
    • RHEL, 10.2.14 Build 20620

    Description

      Later update: A test case can be found in this comment.


      Complex SELECT crashes when executed as prepared statement, with the following crashing thread full backtrace:

      Thread 1 (Thread 0x7f864281e700 (LWP 3849)):
      #0 0x00007f8c31fba741 in pthread_kill () from /lib64/libpthread.so.0
      No symbol table info available.
      #1 0x00007f8c332539ab in my_write_core (sig=11) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/mysys/stacktrace.c:477
      No locals.
      #2 0x00007f8c32c8751b in handle_fatal_signal (sig=11) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/signal_handler.cc:305
      buff = "/mariadb/data/"
      curr_time = 1536635371
      tm = {tm_sec = 31, tm_min = 9, tm_hour = 11, tm_mday = 11, tm_mon = 8, tm_year = 118, tm_wday = 2, tm_yday = 253, tm_isdst = 0, tm_gmtoff = 28800, tm_zone = 0x7f8c350c4f50 "SGT"}
      thd = 0x7f85db7e4cb8
      print_invalid_query_pointer = false
      #3 <signal handler called>
      No symbol table info available.
      #4 0x00007f8c32dc7e1e in Item_func_in::cleanup (this=0x7f8584cb5170) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/item_cmpfunc.h:2355
      No locals.
      #5 0x00007f8c329d1603 in Item::delete_self (this=0x7f8584cb5170) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/item.h:1847
      No locals.
      #6 0x00007f8c329ca012 in Query_arena::free_items (this=0x7f85db7e4cd0) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_class.cc:3695
      next = 0x7f8584cb5060
      #7 0x00007f8c329c5835 in THD::cleanup_after_query (this=0x7f85db7e4cb8) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_class.cc:2226
      No locals.
      #8 0x00007f8c32a33921 in Prepared_statement::cleanup_stmt (this=0x7f8597d980d8) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_prepare.cc:3808
      No locals.
      #9 0x00007f8c32a35e1f in Prepared_statement::execute (this=0x7f8597d980d8, expanded_query=0x7f864281cef0, open_cursor=false)
      at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_prepare.cc:4769
      stmt_backup = {<ilink> = {_vptr.ilink = 0x7f8c339b9870 <vtable for Statement+16>, prev = 0x0, next = 0x0}, <Query_arena> = {_vptr.Query_arena = 0x7f8c339b98a0 <vtable for Statement+64>, free_list = 0x7f85dbf4fdc0,
      mem_root = 0x44281c8e0, state = 1261}, id = 0, mark_used_columns = MARK_COLUMNS_READ, name = {str = 0x7f8c32ab706e <String::append(char const*, unsigned long)+294> "H\213E\350\213P\b\213E\370\001\302H\213E\350\211P\b\270",
      length = 140214618147056}, lex = 0x7f85db7e8750, stmt_lex = 0x7f85db7e8750, query_string = {string = {
      str = 0x7f8584cb2330 "SELECT ... LEFT OUTER JOIN ( \t\t\t\t\t\tSELECT ... ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) RNUM ... ", length = 1261}, cs = 0x7f8c33c970e0 <my_charset_utf8_general_ci>}, base_query = {Ptr = 0x0, str_length = 0, Alloced_length = 0, extra_alloc = 0, alloced = false, thread_specific = false,
      str_charset = 0x7f8c33ae5060 <my_charset_bin>}, db = 0x7f864281c930 "\340ɁB\206\177", db_length = 140240120910893, query_cache_is_applicable = 95 '_'}
      old_stmt_arena = 0x7f85db7e4cd0
      saved_cur_db_name_buf = "\340ɁB\206\177"
      saved_cur_db_name = {str = 0x7f864281c930 "\340ɁB\206\177", length = 202}
      cur_db_changed = false
      error = false
      stmt_db_name = {str = 0x7f85da806d98 "cepdb", length = 5}
      #10 0x00007f8c32a34345 in Prepared_statement::execute_loop (this=0x7f8597d980d8, expanded_query=0x7f864281cef0, open_cursor=false, packet=0x7f85863e2962 "def\005cepdb\002T3\020rms_rule_dtls_at\aRULE_ID\aRULE_ID\f?",
      packet_end=0x7f85863e2a11 "E\024LAST_AUTHORIZED_DATE\f?") at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_prepare.cc:4172
      reprepare_observer = {m_invalidated = false}
      error = 91
      reprepare_attempt = 0
      #11 0x00007f8c32a3231e in mysql_stmt_execute_common (thd=0x7f85db7e4cb8, stmt_id=16, packet=0x7f85863e2962 "def\005cepdb\002T3\020rms_rule_dtls_at\aRULE_ID\aRULE_ID\f?", packet_end=0x7f85863e2a11 "E\024LAST_AUTHORIZED_DATE\f?",
      cursor_flags=0, bulk_op=false, read_types=false) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_prepare.cc:3170
      expanded_query = {
      Ptr = 0x7f85dbe01c58 "SELECT ... ", str_length = 1261, Alloced_length = 1944, extra_alloc = 896, alloced = true, thread_specific = false, str_charset = 0x7f8c33ae5060 <my_charset_bin>}
      stmt = 0x7f8597d980d8
      save_protocol = 0x7f85db7e51f0
      open_cursor = false
      #12 0x00007f8c32a320d0 in mysqld_stmt_execute (thd=0x7f85db7e4cb8, packet_arg=0x7f85863e2959 "", packet_length=184) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_prepare.cc:3068
      packet = 0x7f85863e2962 "def\005cepdb\002T3\020rms_rule_dtls_at\aRULE_ID\aRULE_ID\f?"
      stmt_id = 16
      flags = 0
      packet_end = 0x7f85863e2a11 "E\024LAST_AUTHORIZED_DATE\f?"
      #13 0x00007f8c32a0caaa in dispatch_command (command=COM_STMT_EXECUTE, thd=0x7f85db7e4cb8, packet=0x7f85863e2959 "", packet_length=184, is_com_multi=false, is_next_command=false)
      at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_parse.cc:1777
      net = 0x7f85db7e4f20
      do_end_of_statement = true
      __FUNCTION__ = "dispatch_command"
      error = false
      drop_more_results = false
      #14 0x00007f8c32a0ba79 in do_command (thd=0x7f85db7e4cb8) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_parse.cc:1383
      return_value = false
      packet = 0x7f85863e2958 "\001"
      packet_length = 185
      net = 0x7f85db7e4f20
      command = COM_STMT_EXECUTE
      #15 0x00007f8c32b34860 in do_handle_one_connection (connect=0x7f8c566bcc18) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_connect.cc:1335
      create_user = true
      thr_create_utime = 5924978319722
      thd = 0x7f85db7e4cb8
      #16 0x00007f8c32b345c0 in handle_one_connection (arg=0x7f8c566bcc18) at /home/buildbot/buildbot/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/mariadb-10.2.14/sql/sql_connect.cc:1241
      connect = 0x7f8c566bcc18
      #17 0x00007f8c31fb5dc5 in start_thread () from /lib64/libpthread.so.0
      No symbol table info available.
      #18 0x00007f8c3058d1cd in clone () from /lib64/libc.so.6
      

      Crash is repeatable in the related environment.

      Attachments

        Issue Links

          Activity

            It is problem of condition pushdown, Item IN copy delete array and then original IN item trys to delete it.

            sanja Oleksandr Byelkin added a comment - It is problem of condition pushdown, Item IN copy delete array and then original IN item trys to delete it.

            More precise the problem is that IN tries to make copy for pushdown, it make copy of IN but fail it for arguments so the copy of IN done as it was done by get_item_copy and then did not setup as it should. And so it has original Array and tries to delete it first in the copy then in the original Item.

            sanja Oleksandr Byelkin added a comment - More precise the problem is that IN tries to make copy for pushdown, it make copy of IN but fail it for arguments so the copy of IN done as it was done by get_item_copy and then did not setup as it should. And so it has original Array and tries to delete it first in the copy then in the original Item.

            This patch fix this bug problem but I have to check if there are more problem like this.

            diff --git a/sql/item.cc b/sql/item.cc
            index 4f8433c28c0..a1c8ef01b90 100644
            --- a/sql/item.cc
            +++ b/sql/item.cc
            @@ -2446,7 +2446,8 @@ Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root)
               Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
               if (!copy)
                 return 0;
            -  copy->ref= 
            +  DBUG_ASSERT(thd->is_runtime(mem_root));
            +  copy->ref=
                   (Item**) alloc_root(mem_root, sizeof(Item*));
               if (!copy->ref)
                   return 0;
            diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
            index a28daf36f05..4572beeca62 100644
            --- a/sql/item_cmpfunc.cc
            +++ b/sql/item_cmpfunc.cc
            @@ -4199,6 +4199,7 @@ bool Item_func_in::create_array(THD *thd)
               }
               if (!array || thd->is_fatal_error)          // OOM
                 return true;
            +  has_own_array= TRUE;
               uint j=0;
               for (uint i=1 ; i < arg_count ; i++)
               {
            @@ -4294,6 +4295,7 @@ bool Item_func_in::fix_length_and_dec()
                     array= new (thd->mem_root) in_row(thd, arg_count-1, 0);
                     if (!array)
                       return TRUE;
            +        has_own_array= TRUE;
                     cmp= &((in_row*)array)->tmp;
                   }
                   else
            @@ -4471,12 +4473,24 @@ longlong Item_func_in::val_int()
             }
             
             
            +Item *Item_func_in::get_copy(THD *thd, MEM_ROOT *mem_root)
            +{
            +  Item_func_in *clone= (Item_func_in *)
            +    get_item_copy<Item_func_in>(thd, mem_root, this);
            +  if (clone)
            +  {
            +    clone->has_own_array= FALSE;
            +    bzero(&clone->cmp_items, sizeof(cmp_items));
            +  }
            +  return clone;
            +}
            +
            +
             Item *Item_func_in::build_clone(THD *thd, MEM_ROOT *mem_root)
             {
               Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root);
               if (clone)
               {
            -    bzero(&clone->cmp_items, sizeof(cmp_items));
                 clone->fix_length_and_dec();
               }
               return clone;
            diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
            index 613fb75bcd6..f0fee0163c2 100644
            --- a/sql/item_cmpfunc.h
            +++ b/sql/item_cmpfunc.h
            @@ -1652,12 +1652,13 @@ class Item_func_in :public Item_func_opt_neg
                 and can be used safely as comparisons for key conditions
               */
               bool arg_types_compatible;
            +  bool has_own_array;
               Item_result left_cmp_type;
               cmp_item *cmp_items[6]; /* One cmp_item for each result type */
             
               Item_func_in(THD *thd, List<Item> &list):
                 Item_func_opt_neg(thd, list), array(0), have_null(0),
            -    arg_types_compatible(FALSE)
            +    arg_types_compatible(FALSE), has_own_array(TRUE)
               {
                 bzero(&cmp_items, sizeof(cmp_items));
                 allowed_arg_cols= 0;  // Fetch this value from first argument
            @@ -1671,7 +1672,8 @@ class Item_func_in :public Item_func_opt_neg
                 uint i;
                 DBUG_ENTER("Item_func_in::cleanup");
                 Item_int_func::cleanup();
            -    delete array;
            +    if (has_own_array)
            +      delete array;
                 array= 0;
                 for (i= 0; i <= (uint)TIME_RESULT; i++)
                 {
            @@ -1708,8 +1710,7 @@ class Item_func_in :public Item_func_opt_neg
               bool eval_not_null_tables(void *opt_arg);
               void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
               bool count_sargable_conds(void *arg);
            -  Item *get_copy(THD *thd, MEM_ROOT *mem_root)
            -  { return get_item_copy<Item_func_in>(thd, mem_root, this); }
            +  Item *get_copy(THD *thd, MEM_ROOT *mem_root);
               Item *build_clone(THD *thd, MEM_ROOT *mem_root);
             };
             
            diff --git a/sql/sql_class.h b/sql/sql_class.h
            index b35f9a93238..fa0285bf9ba 100644
            --- a/sql/sql_class.h
            +++ b/sql/sql_class.h
            @@ -4515,6 +4515,7 @@ class THD :public Statement,
                 current_linfo= 0;
                 mysql_mutex_unlock(&LOCK_thread_count);
               }
            +  bool is_runtime (MEM_ROOT *root) { return root == & main_mem_root; }
             };
             
             inline void add_to_active_threads(THD *thd)
            diff --git a/sql/table.cc b/sql/table.cc
            index d6d86d96016..5252ca46dde 100644
            --- a/sql/table.cc
            +++ b/sql/table.cc
            @@ -8432,6 +8432,7 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
               {
                 bool cond_and= false;
                 Item_cond *new_cond;
            +    DBUG_ASSERT(thd->is_runtime(thd->mem_root));
                 if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
                 {
                   cond_and= true;
            

            sanja Oleksandr Byelkin added a comment - This patch fix this bug problem but I have to check if there are more problem like this. diff --git a/sql/item.cc b/sql/item.cc index 4f8433c28c0..a1c8ef01b90 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2446,7 +2446,8 @@ Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root) Item_ref *copy= (Item_ref *) get_copy(thd, mem_root); if (!copy) return 0; - copy->ref= + DBUG_ASSERT(thd->is_runtime(mem_root)); + copy->ref= (Item**) alloc_root(mem_root, sizeof(Item*)); if (!copy->ref) return 0; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a28daf36f05..4572beeca62 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4199,6 +4199,7 @@ bool Item_func_in::create_array(THD *thd) } if (!array || thd->is_fatal_error) // OOM return true; + has_own_array= TRUE; uint j=0; for (uint i=1 ; i < arg_count ; i++) { @@ -4294,6 +4295,7 @@ bool Item_func_in::fix_length_and_dec() array= new (thd->mem_root) in_row(thd, arg_count-1, 0); if (!array) return TRUE; + has_own_array= TRUE; cmp= &((in_row*)array)->tmp; } else @@ -4471,12 +4473,24 @@ longlong Item_func_in::val_int() } +Item *Item_func_in::get_copy(THD *thd, MEM_ROOT *mem_root) +{ + Item_func_in *clone= (Item_func_in *) + get_item_copy<Item_func_in>(thd, mem_root, this); + if (clone) + { + clone->has_own_array= FALSE; + bzero(&clone->cmp_items, sizeof(cmp_items)); + } + return clone; +} + + Item *Item_func_in::build_clone(THD *thd, MEM_ROOT *mem_root) { Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root); if (clone) { - bzero(&clone->cmp_items, sizeof(cmp_items)); clone->fix_length_and_dec(); } return clone; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 613fb75bcd6..f0fee0163c2 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1652,12 +1652,13 @@ class Item_func_in :public Item_func_opt_neg and can be used safely as comparisons for key conditions */ bool arg_types_compatible; + bool has_own_array; Item_result left_cmp_type; cmp_item *cmp_items[6]; /* One cmp_item for each result type */ Item_func_in(THD *thd, List<Item> &list): Item_func_opt_neg(thd, list), array(0), have_null(0), - arg_types_compatible(FALSE) + arg_types_compatible(FALSE), has_own_array(TRUE) { bzero(&cmp_items, sizeof(cmp_items)); allowed_arg_cols= 0; // Fetch this value from first argument @@ -1671,7 +1672,8 @@ class Item_func_in :public Item_func_opt_neg uint i; DBUG_ENTER("Item_func_in::cleanup"); Item_int_func::cleanup(); - delete array; + if (has_own_array) + delete array; array= 0; for (i= 0; i <= (uint)TIME_RESULT; i++) { @@ -1708,8 +1710,7 @@ class Item_func_in :public Item_func_opt_neg bool eval_not_null_tables(void *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool count_sargable_conds(void *arg); - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy<Item_func_in>(thd, mem_root, this); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root); Item *build_clone(THD *thd, MEM_ROOT *mem_root); }; diff --git a/sql/sql_class.h b/sql/sql_class.h index b35f9a93238..fa0285bf9ba 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4515,6 +4515,7 @@ class THD :public Statement, current_linfo= 0; mysql_mutex_unlock(&LOCK_thread_count); } + bool is_runtime (MEM_ROOT *root) { return root == & main_mem_root; } }; inline void add_to_active_threads(THD *thd) diff --git a/sql/table.cc b/sql/table.cc index d6d86d96016..5252ca46dde 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8432,6 +8432,7 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond) { bool cond_and= false; Item_cond *new_cond; + DBUG_ASSERT(thd->is_runtime(thd->mem_root)); if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) { cond_and= true;

            OK to push, but please first use stage tree for testing on buildbot (or if you did use ":" after MDEV in comment to make it easy by our robot to attach the commit to MDEV (also possible that our robot which attach the commits is not working again)

            sanja Oleksandr Byelkin added a comment - OK to push, but please first use stage tree for testing on buildbot (or if you did use ":" after MDEV in comment to make it easy by our robot to attach the commit to MDEV (also possible that our robot which attach the commits is not working again)

            A fix for this bug was pushed into 10.2.

            igor Igor Babaev (Inactive) added a comment - A fix for this bug was pushed into 10.2.

            People

              igor Igor Babaev (Inactive)
              valerii Valerii Kravchuk
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.