diff --git a/CMakeLists.txt b/CMakeLists.txt index 4376def4580..8e9d0da5a4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,7 +342,13 @@ SET(WITH_SAFEMALLOC "AUTO" CACHE STRING "Use safemalloc memory debugger. Will re IF(WITH_SAFEMALLOC MATCHES "ON") ADD_DEFINITIONS( -DSAFEMALLOC) -ELSEIF(WITH_SAFEMALLOC MATCHES "AUTO" AND NOT WIN32 AND NOT WITH_VALGRIND) +ELSEIF(WITH_SAFEMALLOC MATCHES "AUTO" + AND NOT WIN32 + AND NOT WITH_VALGRIND + AND NOT WITH_ASAN + AND NOT WITH_UBSAN + AND NOT WITH_TSAN + AND NOT WITH_MSAN) SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC") ENDIF() diff --git a/mysql-test/main/json_debug_nonembedded_noasan.result b/mysql-test/main/json_debug_nonembedded.result similarity index 63% rename from mysql-test/main/json_debug_nonembedded_noasan.result rename to mysql-test/main/json_debug_nonembedded.result index e759cafa38b..953b633457b 100644 --- a/mysql-test/main/json_debug_nonembedded_noasan.result +++ b/mysql-test/main/json_debug_nonembedded.result @@ -3,6 +3,8 @@ # SET @saved_dbug = @@debug_dbug; SET debug_dbug='+d,json_check_min_stack_requirement'; +SELECT * from JSON_TABLE('[{"a": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}]', '$[*]' COLUMNS( a INT PATH '$.a')) as tt; +ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable. SET @json1= '{"key1":"val1"}'; SET @json2= '{"key1":"val1"}'; SELECT JSON_OVERLAPS(@json1, @json2); diff --git a/mysql-test/main/json_debug_nonembedded_noasan.test b/mysql-test/main/json_debug_nonembedded.test similarity index 66% rename from mysql-test/main/json_debug_nonembedded_noasan.test rename to mysql-test/main/json_debug_nonembedded.test index 4b961d222dd..8d8a9c5db04 100644 --- a/mysql-test/main/json_debug_nonembedded_noasan.test +++ b/mysql-test/main/json_debug_nonembedded.test @@ -1,6 +1,5 @@ -- source include/not_embedded.inc --source include/have_debug.inc ---source include/not_asan.inc --echo # --echo # MDEV-28762: recursive call of some json functions without stack control @@ -9,6 +8,10 @@ SET @saved_dbug = @@debug_dbug; SET debug_dbug='+d,json_check_min_stack_requirement'; +--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/ +--error ER_STACK_OVERRUN_NEED_MORE +SELECT * from JSON_TABLE('[{"a": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}]', '$[*]' COLUMNS( a INT PATH '$.a')) as tt; + SET @json1= '{"key1":"val1"}'; SET @json2= '{"key1":"val1"}'; diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 3c556d97cb2..e6f5da2bbe0 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -21,7 +21,7 @@ #include "sql_parse.h" // For check_stack_overrun #ifndef DBUG_OFF -static int dbug_json_check_min_stack_requirement() +int dbug_json_check_min_stack_requirement() { my_error(ER_STACK_OVERRUN_NEED_MORE, MYF(ME_FATAL), my_thread_stack_size, my_thread_stack_size, STACK_MIN_SIZE); diff --git a/sql/json_table.cc b/sql/json_table.cc index 4281a2add04..7087360bc3e 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -27,23 +27,11 @@ #include "create_tmp_table.h" #include "sql_parse.h" -#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1) +#ifndef DBUG_OFF +int dbug_json_check_min_stack_requirement(); +#endif -/* - Allocating memory and *also* using it (reading and - writing from it) because some build instructions cause - compiler to optimize out stack_used_up. Since alloca() - here depends on stack_used_up, it doesnt get executed - correctly and causes json_debug_nonembedded to fail - ( --error ER_STACK_OVERRUN_NEED_MORE does not occur). -*/ -#define ALLOCATE_MEM_ON_STACK(A) do \ - { \ - uchar *array= (uchar*)alloca(A); \ - array[0]= 1; \ - array[0]++; \ - array[0] ? array[0]++ : array[0]--; \ - } while(0) +#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1) class table_function_handlerton { @@ -119,13 +107,9 @@ int get_disallowed_table_deps_for_list(MEM_ROOT *mem_root, List_iterator li(*join_list); DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return -dbug_json_check_min_stack_requirement();); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) - return 1; + return -1; while ((table= li++)) { @@ -1351,21 +1335,20 @@ void Table_function_json_table::fix_after_pullout(TABLE_LIST *sql_table, /* @brief Recursively make all tables in the join_list also depend on deps. + + @return - boolean - true if error (out of memory). */ -static void add_extra_deps(List *join_list, table_map deps) +static bool add_extra_deps(List *join_list, table_map deps) { TABLE_LIST *table; List_iterator li(*join_list); DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + dbug_json_check_min_stack_requirement(); return true;); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) - return; + return true; + while ((table= li++)) { table->dep_tables |= deps; @@ -1373,9 +1356,11 @@ static void add_extra_deps(List *join_list, table_map deps) if ((nested_join= table->nested_join)) { // set the deps inside, too - add_extra_deps(&nested_join->join_list, deps); + if (add_extra_deps(&nested_join->join_list, deps)) + return true; } } + return false; } @@ -1444,7 +1429,8 @@ static void add_extra_deps(List *join_list, table_map deps) supply the JOIN's top-level table list. @param nest_tables Bitmap of all tables in the join list. - @return Bitmap of all outside references that tables in join_list have + @return Bitmap of all outside references that tables in join_list have, + or 0 on out of stack error. */ table_map add_table_function_dependencies(List *join_list, @@ -1455,11 +1441,7 @@ table_map add_table_function_dependencies(List *join_list, List_iterator li(*join_list); DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + if (dbug_json_check_min_stack_requirement()) return 0;); if ((res=check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL))) return res; @@ -1481,7 +1463,10 @@ table_map add_table_function_dependencies(List *join_list, res= res & ~nest_tables & ~PSEUDO_TABLE_BITS; // Then, make all "peers" have them: if (res) - add_extra_deps(join_list, res); + { + if (add_extra_deps(join_list, res)) + return 0; + } return res; }