| Bug #73404 | mysl_errno() returns 0 for socket errors in debug builds | ||
|---|---|---|---|
| Submitted: | 26 Jul 2014 4:07 | Modified: | 29 Jul 2014 18:06 |
| Reporter: | Matt Fagan | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
| Version: | 6.1.5 | OS: | Windows |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | Connection errors mysql_errno debug | ||
[29 Jul 2014 18:06]
MySQL Verification Team
Thank you for the bug report. C:\tmp\bug_code_client\x64\Debug>net stop mysql56 The MySQL56 service is stopping. The MySQL56 service was stopped successfully. C:\tmp\bug_code_client\x64\Debug>bug_code_client.exe Error 2003 Can't connect to MySQL server on '127.0.0.1' (0) C:\tmp\bug_code_client\x64\Debug>cd.. C:\tmp\bug_code_client\x64>cd Release C:\tmp\bug_code_client\x64\Release>bug_code_client.exe Error 2003 Can't connect to MySQL server on '127.0.0.1' (10061)

Description: The debug build loses socket error codes, meaning that mysql_errno() returns 0 instead of 2003 on connection error. How to repeat: Create a project in vs2010 that links to the "debug" library. Make sure the mysql server is NOT running on the server (in order to produce a connection error). Run the following code: #include<mysql.h> MYSQL* pHandle; pHandle = mysql_init(NULL); if (mysql_real_connect(pHandle, NULL, "username", "password", NULL, 0, NULL, 0) == NULL) { printf("Error %d %s\n", mysql_errno(pHandle), mysql_error(pHandle)); } Suggested fix: The easy fix is to link even debug builds of client projects against the release version of the mysql client library. This just needs to be noted in the release notes. Perhaps the builder of the Connector/C for Windows library could simply remove the debug builds, or else add a warning file in the debug build directories. As a more permanent fix, I stepped through the code, and found that the problem is the _db_return_ function in the dbug.c file. When a connection is create, the function vio_socket_connect in viosocket.c is called. This function internally calls the Windows connect() function, which then sets the error code (which will be accessed later via WSAGetLastError()). However, when this function returns, it calls _db_return_ as part of the return. The _db_return_ function does a whole pile of processing, and overwrites the WSAGetLastError() with 0 during this process. When the function that called vio_socket_connect() then calls WSAGetLastError() to find out the error code, it gets the 0 instead of the actual error code. So, a possible fix is remove DBUG_RETURN macro from within vio_socket_connect to stop it from crunching the error code (or perhaps conditionally use it only if no error).