mkleehammer / pyodbc

Python ODBC bridge
https://github.com/mkleehammer/pyodbc/wiki
MIT No Attribution
2.93k stars 561 forks source link

Segmentation Fault when trying to open a connection in a Thread on AmazonLinux #1037

Closed raptorworks closed 2 years ago

raptorworks commented 2 years ago

I get a seg fault when trying to open a connection in a thread in amazonlinux2 - i know amazon linux is based off centos7 but havent been able to check if the issue exists there also. The behaviour only occurs when trying to create a new connection inside a new python thread.

Environment

Issue

Running on WSL ubuntu-20 this code works fine. Running on amazonlinux2 in EC2 I get Segmentation Fault.

import pyodbc
from threading import Thread

def foo():
    cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass')
    print(f'Got connection object: {cnxn}')

if __name__ == '__main__':
    Thread(target = foo).start()
v-chojas commented 2 years ago

Where is it crashing? Can you post an ODBC trace, or even better, a stack trace?

raptorworks commented 2 years ago

@v-chojas It just seg faults immediately whilst trying to run the pyodbc.connect() method. There is no stack trace when you get a seg fault. Can you provide details on how i would capture odbc trace?

v-chojas commented 2 years ago

Run it under gdb, when it crashes it will say exactly where, and then bt command will show the stack trace. For ODBC trace, see instructions here: https://github.com/mkleehammer/pyodbc/wiki/Troubleshooting-%E2%80%93-Generating-an-ODBC-trace-log

raptorworks commented 2 years ago

@v-chojas

obdb trace log:

[ODBC][209][1646734374.783351][__handles.c][460]
                Exit:[SQL_SUCCESS]
                        Environment = 0x7f19a400e6b0
[ODBC][209][1646734374.783374][SQLSetEnvAttr.c][189]
                Entry:
                        Environment = 0x7f19a400e6b0
                        Attribute = SQL_ATTR_ODBC_VERSION
                        Value = 0x3
                        StrLen = 4
[ODBC][209][1646734374.783383][SQLSetEnvAttr.c][363]
                Exit:[SQL_SUCCESS]
[ODBC][209][1646734374.783399][SQLAllocHandle.c][375]
                Entry:
                        Handle Type = 2
                        Input Handle = 0x7f19a400e6b0
[ODBC][209][1646734374.783409][SQLAllocHandle.c][493]
                Exit:[SQL_SUCCESS]
                        Output Handle = 0x7f19a40107f0
[ODBC][209][1646734374.783474][SQLSetConnectAttr.c][396]
                Entry:
                        Connection = 0x7f19a40107f0
                        Attribute = 1256
                        Value = 0x7f19a400fcb0
                        StrLen = -4
[ODBC][209][1646734374.783483][SQLSetConnectAttr.c][681]
                Exit:[SQL_SUCCESS]
[ODBC][209][1646734374.783864][SQLDriverConnectW.c][290]
                Entry:
                        Connection = 0x7f19a40107f0
                        Window Hdl = (nil)
                        Str In = [driver=ODBC Driver 17 for SQL Server;server=******************;database=mydb;trusted_connection=no;][length = 127 (SQL_NTS)]
                        Str Out = (nil)
                        Str Out Max = 0
                        Str Out Ptr = (nil)
                        Completion = 0
                UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

i have sanitised my dbserver name. I am working on getting gdb installed, but is not super easy in this environment.

raptorworks commented 2 years ago

I think it might be related to this issue, as we're using AD auth to connect to the mssql database: https://github.com/mkleehammer/pyodbc/issues/228

We do not get the seg fault when just running in the main thread, so maybe python is doing something strange with the token struct when its in a thread?

v-chojas commented 2 years ago

What version of unixODBC are you using? You can check by running odbcinst -j .

raptorworks commented 2 years ago

@v-chojas

bash-4.2# odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
v-chojas commented 2 years ago

2.3.1 is very buggy. I suspect you are running into this bug which was fixed in unixODBC 2.3.5: "Custom pre-connect pointer attributes are truncated to 32 bits "

http://www.unixodbc.org/

Please try >= 2.3.5.

raptorworks commented 2 years ago

fixed by installing 2.3.7. its because amazon linux installs odbc 2.3.1. for anyone else who gets this problem will need to use the following to install >= 2.3.1

ACCEPT_EULA=Y yum install -y mssql-tools unixODBC-devel --disablerepo=amzn*

source: https://github.com/microsoft/msphpsql/issues/496#issuecomment-483062639