Description:
Some sort of memory bug on the latest mysql-connector-odbc
Versions 8.0.21-28.
Using pyodbc when importing the protobuf first the driver responds with
pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib '/usr/lib64/unixODBC/libmyodbc8.so' : file not found (0) (SQLDriverConnect)")
However when not importing protobuf first it works fine.
if using the release protobuf version 4.0.0rc2 it will seg fault.
Valgrind output
==198== Block was alloc'd at
==198== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==198== by 0x590453: PyUnicode_New (in /usr/bin/python3.8)
==198== by 0x57B185: _PyUnicodeWriter_PrepareInternal (in /usr/bin/python3.8)
==198== by 0x57C155: ??? (in /usr/bin/python3.8)
==198== by 0x4F0CE3: ??? (in /usr/bin/python3.8)
==198== by 0x5FA50E: ??? (in /usr/bin/python3.8)
==198== by 0x50490D: ??? (in /usr/bin/python3.8)
==198== by 0x56B5DF: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198== by 0x5F6225: _PyFunction_Vectorcall (in /usr/bin/python3.8)
==198== by 0x56B5DF: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198== by 0x50AC5D: ??? (in /usr/bin/python3.8)
==198== by 0x5703E5: _PyEval_EvalFrameDefault (in /usr/bin/python3.8)
==198==
==198== Use of uninitialised value of size 8
==198== at 0x64816FE: void std::__once_call_impl<std::_Bind_simple<void (*(google::protobuf::internal::DescriptorTable const*, bool))(google::protobuf::internal::DescriptorTable const*, bool)> >() (in /usr/local/lib/python3.8/dist-packages/google/protobuf/pyext/_message.cpython-38-x86_64-linux-gnu.so)
==198== by 0x4A524CF: ??? (pthread_once.c:132)
==198== by 0x7960F8F: ??? (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198==
==198==
==198== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==198== Bad permissions for mapped region at address 0x6E63BC0
==198== at 0x6E63BC0: ???
==198== by 0x4A5247E: __pthread_once_slow (pthread_once.c:116)
==198== by 0x72587E5: void std::call_once<void (&)()>(std::once_flag&, void (&)()) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x7259782: my_charset_get_by_name(MY_CHARSET_LOADER*, char const*, unsigned int, int) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x725986E: get_charset_by_csname(char const*, unsigned int, int) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x720D0BB: myodbc_init() (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x7210F5F: my_SQLAllocEnv(void**) (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x7212303: SQLAllocHandle (in /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so)
==198== by 0x6DE6962: ??? (in /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0)
==198== by 0x6E07923: SQLDriverConnectW (in /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0)
==198== by 0x6DB9E25: Connect (connection.cpp:114)
==198== by 0x6DB9E25: Connection_New(_object*, bool, bool, long, bool, _object*, Object&) (connection.cpp:286)
==198== by 0x6DC3E2B: mod_connect(_object*, _object*, _object*) (pyodbcmodule.cpp:553)
How to repeat:
RUN apt -qyy update \
&& apt -qyy install python3 python3-pip wget unixodbc-dev \
&& wget https://cdn.mysql.com//Downloads/Connector-ODBC/8.0/mysql-connector-odbc_8.0.28-1ubuntu20.... \
&& wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client-plugins_8.0.28-1ubunt... \
&& dpkg -i mysql-community-client-plugins_8.0.28-1ubuntu20.04_amd64.deb mysql-connector-odbc_8.0.28-1ubuntu20.04_amd64.deb \
|| apt-get -qyy install -f \
&& pip install pyodbc protobuf
```
start with
`docker run -it --rm 5845c89c55ca bash`
Then run this
```
python3 -c '
from google.protobuf.pyext import _message
import pyodbc
cnxn = pyodbc.connect(
"DRIVER=MySQL ODBC 8.0 ANSI Driver;"
"SERVER=192.168.0.199;"
"UID=scott;PWD=tiger;"
"DATABASE=test;"
"charset=utf8mb4;"
)
print(f"Connected with driver version {cnxn.getinfo(pyodbc.SQL_DRIVER_VER)}")
'
```
Comment out the google.protobuf.pyext import and it works... :exploding_head:
Suggested fix:
Fix some malloc.