From b0b54852514e5ae2d5816c3217d70f65384c9920 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Tue, 16 Jul 2019 00:38:53 +1000 Subject: [PATCH] MDEV-17005 add debug logs and set up deterministic test --- .../innodb/r/innodb-virtual-columns.result | 18 +++++++++++++ .../innodb/t/innodb-virtual-columns.test | 25 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 24 +++++++++++------- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result index de97d933ad9..4a510effd43 100644 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result @@ -345,3 +345,21 @@ SELECT * FROM t1; a b c 1 foo 1 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (),(); +connect con1,localhost,root,,test; +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +DELETE FROM t1; +connection default; +SET debug_sync= "now WAIT_FOR delete_open"; +SET debug_sync= "ib_open_after_dict_open SIGNAL another_open"; +SELECT a FROM t1; +a +NULL +NULL +connection con1; +disconnect con1; +connection default; +SET debug_sync= "RESET"; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns.test b/mysql-test/suite/innodb/t/innodb-virtual-columns.test index faf542645fb..39725b90cc6 100644 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns.test +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/have_debug_sync.inc # # MDEV-7367: Updating a virtual column corrupts table which crashes server @@ -317,3 +318,27 @@ INSERT INTO t1 (a,b) VALUES (1,'foo'); ALTER TABLE t1 ADD FULLTEXT KEY(b); SELECT * FROM t1; DROP TABLE t1; + +# +# MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value +# +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; + +INSERT INTO t1 () VALUES (),(); +--connect (con1,localhost,root,,test) +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +--send +DELETE FROM t1; +--connection default +SET debug_sync= "now WAIT_FOR delete_open"; +SET debug_sync= "ib_open_after_dict_open SIGNAL another_open"; +SELECT a FROM t1; +--connection con1 +--reap + +# Cleanup +--disconnect con1 +--connection default +SET debug_sync= "RESET"; +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7b4c06b6554..a598dbaefb9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5923,6 +5923,7 @@ innobase_build_v_templ( ulint n_v_col = ib_table->n_v_cols; bool marker[REC_MAX_N_FIELDS]; + DBUG_ENTER("innobase_build_v_templ"); ut_ad(ncol < REC_MAX_N_FIELDS); if (add_v != NULL) { @@ -5939,7 +5940,7 @@ innobase_build_v_templ( if (!locked) { mutex_exit(&dict_sys->mutex); } - return; + DBUG_VOID_RETURN; } memset(marker, 0, sizeof(bool) * ncol); @@ -6049,6 +6050,7 @@ innobase_build_v_templ( s_templ->db_name = table->s->db.str; s_templ->tb_name = table->s->table_name.str; + DBUG_VOID_RETURN; } /** Check consistency between .frm indexes and InnoDB indexes. @@ -6247,6 +6249,8 @@ ha_innobase::open(const char* name, int, uint) ib_table = open_dict_table(name, norm_name, is_part, ignore_err); + DEBUG_SYNC(thd, "ib_open_after_dict_open"); + if (NULL == ib_table) { if (is_part) { @@ -10678,13 +10682,13 @@ ha_innobase::wsrep_append_keys( if (!is_null) { rcode = wsrep_append_key( - thd, trx, table_share, table, keyval, + thd, trx, table_share, table, keyval, len, key_type); if (rcode) DBUG_RETURN(rcode); } else { - WSREP_DEBUG("NULL key skipped (proto 0): %s", + WSREP_DEBUG("NULL key skipped (proto 0): %s", wsrep_thd_query(thd)); } } else { @@ -19672,7 +19676,7 @@ wsrep_abort_transaction( my_bool signal) { DBUG_ENTER("wsrep_innobase_abort_thd"); - + trx_t* victim_trx = thd_to_trx(victim_thd); trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL; @@ -21614,6 +21618,7 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) if (table->vc_templ != NULL) { return NULL; } + DBUG_ENTER("innobase_init_vc_templ"); table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); @@ -21621,13 +21626,13 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) ut_ad(mysql_table); if (!mysql_table) { - return NULL; + DBUG_RETURN(NULL); } mutex_enter(&dict_sys->mutex); innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); mutex_exit(&dict_sys->mutex); - return mysql_table; + DBUG_RETURN(mysql_table); } /** Change dbname and table name in table->vc_templ. @@ -21829,6 +21834,7 @@ innobase_get_computed_value( ut_ad(thd != NULL); ut_ad(mysql_table); + DBUG_ENTER("innobase_get_computed_value"); const mysql_row_templ_t* vctempl = index->table->vc_templ->vtempl[ index->table->vc_templ->n_col + col->v_pos]; @@ -21917,7 +21923,7 @@ innobase_get_computed_value( stderr); dtuple_print(stderr, row); #endif /* INNODB_VIRTUAL_DEBUG */ - return(NULL); + DBUG_RETURN(NULL); } if (vctempl->mysql_null_bit_mask @@ -21925,7 +21931,7 @@ innobase_get_computed_value( & vctempl->mysql_null_bit_mask)) { dfield_set_null(field); field->type.prtype |= DATA_VIRTUAL; - return(field); + DBUG_RETURN(field); } row_mysql_store_col_in_innobase_format( @@ -21957,7 +21963,7 @@ innobase_get_computed_value( dfield_dup(field, heap); } - return(field); + DBUG_RETURN(field); }