Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Critical
-
Resolution: Unresolved
-
10.11.5
Description
If SP CALLhas been prepared and executed, and then the SP is changed(DROPped and CREATEd) by someone, the second execution of that CALL statement will reliably crash the server. The C API code to repeat
MYSQL *ma;
|
MYSQL_STMT *stmt;
|
MYSQL_BIND bind[3], paramBind[3]; |
MARIADB_CHARSET_INFO *cs;
|
my_bool is_null= 0, error= 0; |
unsigned int i= 0, j= 0, res[3]={30,20,50}, param[3]= {30,20,50}; |
|
ma = mysql_init(NULL);
|
mysql_optionsv(ma, MYSQL_SET_CHARSET_NAME, "latin1"); |
|
if (!mysql_real_connect(ma, "localhost", "root", "root", "test", 3306, NULL, CLIENT_MULTI_RESULTS | CLIENT_MULTI_STATEMENTS)) |
{
|
printf("Could not connect: %s\n", mysql_error(ma)); |
exit(1); |
}
|
else |
{
|
printf("Server info %s\nClient info: %s\n", |
mysql_get_server_info(ma), mysql_get_client_info());
|
}
|
|
stmt= mysql_stmt_init(ma);
|
|
mysql_query(ma, "DROP PROCEDURE IF EXISTS t_outparams"); |
mysql_query(ma, "CREATE PROCEDURE t_outparams(" |
" IN p_in INT, " |
" OUT p_out INT, " |
" INOUT p_inout INT) " |
"BEGIN " |
" SET p_in = p_in*10, p_out = (p_in+p_inout)*10, p_inout = p_inout*10; " |
"END"); |
mysql_stmt_prepare(stmt, "CALL t_outparams(?,?,?)", -1); |
|
memset(&bind, 0, sizeof(bind)); |
memset(&bind, 0, sizeof(paramBind)); |
|
bind[0].buffer_type= MYSQL_TYPE_LONG; |
bind[0].buffer= (void *)res; |
bind[0].buffer_length= sizeof(int); |
bind[0].is_null= NULL; |
bind[0].error= NULL; |
|
bind[1].buffer_type= MYSQL_TYPE_LONG; |
bind[1].buffer= (void *)(res + 1); |
bind[1].buffer_length= sizeof(int); |
bind[1].is_null= NULL; |
bind[1].error= NULL; |
|
bind[2].buffer_type= MYSQL_TYPE_LONG; |
bind[2].buffer= (void *)(res + 2); |
bind[2].buffer_length= sizeof(int); |
bind[2].is_null= NULL; |
bind[2].error= NULL; |
|
mysql_stmt_bind_param(stmt, bind);
|
mysql_stmt_execute(stmt);
|
mysql_stmt_store_result(stmt);
|
mysql_stmt_bind_result(stmt, bind);
|
|
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
{
|
printf("-- Values= %d %d %d\n", res[0], res[1], res[2]); |
}
|
printf("---------------------------------------------------\n"); |
mysql_stmt_next_result(stmt);
|
if (mysql_stmt_field_count(stmt) == 0) |
{
|
printf("SP returned: %lld", mysql_stmt_affected_rows(stmt)); |
}
|
|
mysql_query(ma, "DROP PROCEDURE t_outparams"); |
|
mysql_query(ma, "CREATE PROCEDURE t_outparams(" |
" OUT p_out VARCHAR(19), " |
" IN p_in INT, " |
" INOUT p_inout INT) " |
"BEGIN " |
" SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; " |
" SELECT p_inout, p_in, substring(p_out, 9);" |
"END"); |
|
mysql_stmt_bind_param(stmt, bind);
|
mysql_stmt_execute(stmt);
|
mysql_stmt_store_result(stmt);
|
mysql_stmt_bind_result(stmt, bind);
|
|
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
{
|
printf("-- Values= %d %d %d\n", res[0], res[1], res[2]); |
}
|
printf("---------------------------------------------------\n"); |
mysql_stmt_next_result(stmt);
|
mysql_stmt_close(stmt);
|
|
mysql_query(ma, "DROP PROCEDURE t_outparams"); |
mysql_close(ma);
|
I don't have latest versions for all branches, but this crashes all supported server release series
Server info 10.11.5-MariaDB |
Client info: 3.3.8 |
-- Values= 3500 500 50 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 10.5.20-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 10.6.11-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 10.4.31-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 10.10.2-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 10.9.4-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Could not connect: Can't connect to server on 'localhost' (10061) |
Server info 11.0.2-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Server info 11.1.2-MariaDB |
Client info: 3.3.8 |
-- Values= 20000 0 0 |
---------------------------------------------------
|
SP returned: 0 |
-- Values= 200 300 0 |
---------------------------------------------------
|
Call mysql_stmt_next_result unexpectedly returned !0 because of Lost connection to server during query (errno: 2013) |
===================================================
|
Unlikely this matters, but I am testing on Windows. The backtrace from the log:
Server version: 10.11.5-MariaDB source revision: 7875294b6b74b53dd3aaa723e6cc103d2bb47b2c |
key_buffer_size=134217728 |
read_buffer_size=131072 |
max_used_connections=1 |
max_threads=65537 |
thread_count=1 |
It is possible that mysqld could use up to
|
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 142742958 K bytes of memory |
Hope that's ok; if not, decrease some variables in the equation. |
|
Thread pointer: 0x1a98daccf98 |
Attempting backtrace. You can use the following information to find out
|
where mysqld died. If you see no messages after this, something went |
terribly wrong...
|
server.dll!my_convert()[ctype.c:1267] |
server.dll!String::copy()[sql_string.cc:476] |
server.dll!Protocol::net_store_data_cs()[protocol.cc:104] |
server.dll!Protocol_text::store_field_metadata()[protocol.cc:854] |
server.dll!Protocol::send_result_set_metadata()[protocol.cc:1213] |
server.dll!Protocol_binary::send_out_parameters()[protocol.cc:1965] |
server.dll!Prepared_statement::execute()[sql_prepare.cc:5335] |
server.dll!Prepared_statement::execute_loop()[sql_prepare.cc:4646] |
server.dll!mysql_stmt_execute_common()[sql_prepare.cc:3578] |
server.dll!mysqld_stmt_execute()[sql_prepare.cc:3352] |
server.dll!dispatch_command()[sql_parse.cc:1826] |
server.dll!do_command()[sql_parse.cc:1407] |
server.dll!tp_callback()[threadpool_common.cc:245] |
KERNEL32.DLL!TermsrvSetKeySecurity()
|
ntdll.dll!RtlEqualUnicodeString()
|
ntdll.dll!TpReleaseCleanupGroupMembers()
|
KERNEL32.DLL!BaseThreadInitThunk()
|
ntdll.dll!RtlUserThreadStart()
|
|
Trying to get some variables.
|
Some pointers may be invalid and cause the dump to abort.
|
Query (0x1a98db75090): CALL t_outparams(?,?,?) |
Connection ID (thread ID): 12 |
Status: NOT_KILLED
|
|
Optimizer switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off |
I did not dig much, but looks like the order of in/out parameters is what matters here - in original test the first change of procedure did not change that, but added a resultset, and it did not crash the server.
Not sure if it's critical - unlikely something that people do on production systems, but it's still a crash.