| Bug #92112 | Memory leak when client APIs called after mysql_close | ||
|---|---|---|---|
| Submitted: | 21 Aug 2018 20:14 | Modified: | 5 Feb 2019 14:55 |
| Reporter: | Manuel Ung | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
| Version: | 8.0.11, 8.0.12, 5.7.23 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[22 Aug 2018 4:50]
MySQL Verification Team
Hello Manuel, Thank you for the report! regards, Umesh
[22 Aug 2018 4:54]
MySQL Verification Team
test results
Attachment: 92112_8.0.12.results (application/octet-stream, text), 273.53 KiB.
[23 Aug 2018 12:14]
MySQL Verification Team
5.7.23 - test results
Attachment: 92112_5.7.23.results (application/octet-stream, text), 7.78 KiB.
[28 Jan 2019 10:35]
Shishir Jaiswal
IMHO it's not a bug. https://dev.mysql.com/doc/refman/5.7/en/c-api-threaded-clients.html says, "When you call mysql_init(), MySQL creates a thread-specific variable for the thread that is used by the debug library (among other things). If you call a MySQL function before the thread has called mysql_init(), the thread does not have the necessary thread-specific variables in place and you are likely to end up with a core dump sooner or later."
[5 Feb 2019 14:55]
Paul DuBois
Posted by developer: After you call mysql_close() to close a connection handler, you're supposed to stop using it. Further use is bound to cause trouble. I'll add a note to that effect to the mysql_close() section.

Description: The client api leaks memory when the application calls mysql_next_result after mysql_close is called on the MYSQL handle. This is because MYSQL_TRACE_STAGE will allocate memory for the 'extensions' field: #define TRACE_DATA(M) (MYSQL_EXTENSION_PTR(M)->trace_data) #define MYSQL_EXTENSION_PTR(H) \ ((MYSQL_EXTENSION *)((H)->extension \ ? (H)->extension \ : ((H)->extension = mysql_extension_init(H)))) However, the application will likely receive an out of sync error, and will not call mysql_close again. The memory allocated for extension is then leaked. This is in theory bad behaviour from the application, since they shouldn't be doing this on a closed handle. However, the client library behaviour can probably be improved as well. How to repeat: Apply this diff on testclients/mysql_client_test.cc and run main.mysql_client_test with valgrind. diff --git a/testclients/mysql_client_test.cc b/testclients/mysql_client_test.cc index 10950e03273..2b6d5e35e0a 100644 --- a/testclients/mysql_client_test.cc +++ b/testclients/mysql_client_test.cc @@ -20152,7 +20152,21 @@ static void test_bug25701141() { myquery(mysql_query(mysql, "DROP TABLE t1")); } +static void test_leak() { + MYSQL *mysql_local; + myheader("test_leak"); + + if (!(mysql_local = mysql_client_init(NULL))) { + fprintf(stderr, "\n mysql_client_init() failed"); + exit(1); + } + + mysql_close(mysql_local); + mysql_next_result(mysql_local); +} + static struct my_tests_st my_tests[] = { + {"test_leak", test_leak}, {"disable_query_logs", disable_query_logs}, {"test_view_sp_list_fields", test_view_sp_list_fields}, {"client_query", client_query}, Check _build/mysql-test/var/log/mysql_client_test.out.log for valgrind output that shows leak (I don't think mtr Suggested fix: Best solution is probably to track whether a handle is closed or not, and avoid check that flag before allocating memory for extensions.