| Bug #98177 | CR_CONN_HOST_ERROR never returned by async client | ||
|---|---|---|---|
| Submitted: | 10 Jan 2020 3:14 | Modified: | 20 Jul 2020 8:43 |
| Reporter: | Manuel Ung | Email Updates: | |
| Status: | Can't repeat | Impact on me: | |
| Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
| Version: | 8.0.18 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[10 Jan 2020 3:14]
Manuel Ung
[10 Jan 2020 5:43]
MySQL Verification Team
Hello Manuel Ung, Thank you for the bug report and feedback. regards, Umesh
[25 Mar 2020 18:40]
Jay Edgar
In addition, once #98574 and #98980 are fixed, you may need to add a check in cli_advanced_command_nonblocking() to make sure that net_async is not null. This is because with this check added, it is possible to never get net_async assigned (via my_net_init). If that happens then when mysql_close() is called, it will call cli_advanced_command_nonblocking() with net_async (via NET_ASYNC_DATA(mysql)) having never been initialized:
diff --git a/sql-common/client.cc b/sql-common/client.cc
index a44e9f4ec17..8d66cbdbb0c 100644
--- a/sql-common/client.cc
+++ b/sql-common/client.cc
@@ -1445,7 +1445,7 @@ net_async_status cli_advanced_command_nonblocking(
DBUG_DUMP("sending arg", arg, arg_length);
}
- if (mysql->net.vio == 0) {
+ if (mysql->net.vio == 0 || !net_async) {
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
goto end;
}
I was able to reproduce the problem by attempting to connect to an invalid IP address, fail (because mysql_real_connect_nonblocking will always return NET_ASYNC_NOT_READY) and the call mysql_close():
diff --git a/testclients/mysql_client_test.cc b/testclients/mysql_client_test.cc
index 9e558664abf..c36b79b03db 100644
--- a/testclients/mysql_client_test.cc
+++ b/testclients/mysql_client_test.cc
@@ -20165,6 +20165,26 @@ static void test_bug27443252() {
void perform_arithmatic() { fprintf(stdout, "\n Do some other stuff."); }
+static void test_crash() {
+ MYSQL *mysql_local;
+ net_async_status status;
+
+ /*make new non blocking connection to do asynchronous operations */
+ if (!(mysql_local = mysql_client_init(NULL))) {
+ myerror("mysql_client_init() failed");
+ exit(1);
+ }
+
+ status = mysql_real_connect_nonblocking(mysql_local, "0100::", opt_user, opt_password, current_db, opt_port, opt_unix_socket, CLIENT_MULTI_STATEMENTS);
+ if (status != NET_ASYNC_NOT_READY) {
+ myerror("Unexpected result from mysql_real_connect_nonblocking()");
+ exit(1);
+ }
+
+ // See if we can close without crashing
+ mysql_close(mysql_local);
+}
+
static void test_wl11381() {
MYSQL *mysql_local;
MYSQL_RES *result;
@@ -20874,6 +20894,7 @@ static struct my_tests_st my_tests[] = {
{"test_wl11772", test_wl11772},
{"test_wl12475", test_wl12475},
{"test_bug30032302", test_bug30032302},
+ {"test_crash", test_crash},
{0, 0}};
static struct my_tests_st *get_my_tests() { return my_tests; }
[20 Jul 2020 8:43]
Erlend Dahl
We can't repeat this any more on 8.0.21.
