ibmdb / python-ibmdb

Automatically exported from code.google.com/p/ibm-db
Apache License 2.0
304 stars 191 forks source link

intermittent segmentation fault in ibm_db.execute python3 3.5.2 #271

Closed imavo closed 6 years ago

imavo commented 7 years ago

Getting intermittent segmentation fault running ibm_db.execute(stmt) for a prepared statement. Running ubuntu 16.04 LTS on x64 with python 3.5.2 and ibm_db 2.0.7, with locally installed DB2 v11.1.1.1. The fault always happens on the same line, but if I run my script 10 times in a row then the fault will only happen on average 3 times in 10. I ran gdb to get stack trace and it reported:

gdb python3
(gdb) run /home/user1/py/test_conn.py
...
2017-08-08 19:20:33,733 - DEBUG 0 About to execute the prepared statement

Program received signal SIGSEGV, Segmentation fault.
0x000000000055c230 in PyType_IsSubtype ()
(gdb) backtrace
#0  0x000000000055c230 in PyType_IsSubtype ()
#1  0x00007ffff67b61f3 in _python_get_variable_type (variable_value=0x7fffee0416c0) at ibm_db.c:10906
#2  0x00007ffff67b9075 in _python_ibm_db_bind_data (curr=curr@entry=0xc4ac10, bind_data=0x7fffee0416c0, stmt_res=0x7fffee022168) at ibm_db.c:5290
#3  0x00007ffff67bae90 in _python_ibm_db_execute_helper2 (data=<optimised out>, bind_cmp_list=<optimised out>, bind_params=<optimised out>, stmt_res=<optimised out>)
    at ibm_db.c:5788
#4  _python_ibm_db_execute_helper1 (stmt_res=0x7fffee022168, parameters_tuple=<optimised out>) at ibm_db.c:5955
#5  0x00007ffff67bbaf8 in ibm_db_execute (self=<optimised out>, args=<optimised out>) at ibm_db.c:6118
#6  0x00000000004e9b9f in PyCFunction_Call ()
#7  0x0000000000524414 in PyEval_EvalFrameEx ()
#8  0x000000000052d2e3 in ?? ()
#9  0x000000000052dfdf in PyEval_EvalCode ()
#10 0x00000000005fd2c2 in ?? ()
#11 0x00000000005ff76a in PyRun_FileExFlags ()
#12 0x00000000005ff95c in PyRun_SimpleFileExFlags ()
#13 0x000000000063e7d6 in Py_Main ()
#14 0x00000000004cfe41 in main ()
(gdb) 

The problem only happens if I use a method on an argument to ibm_db.bind_param. For example ibm_db.bind_param(stmt,1, db_uid.upper() )

If I change this to:

upr_uid=db_uid.upper()
ibm_db.bind_param(stmt,1,upr_uid)

then I do not get the segmentation fault.

It would be more useful if I was not forced to have such workarounds. Is this a bug or a feature ?

SabaKauser commented 7 years ago

Can you share your repro?

imavo commented 7 years ago

Sample script below, please change the credentials to suit your databasename, user, password. Need to run it multiple times in succession to get the fault. Each run takes a second. I could not get the attach function working on this page for .zip file or .txt file so pasted inline below.

`#!/usr/bin/python3 #

Python 3.5.2 with ibm_db 2.0.7 on Ubuntu 16.04LTS

Run 10 times this script (takes 1 second approx to complete each run)

Get segmentation fault (core dumped) on ibm_db.execute() if ibm_db.bind_param uses string.upper() in argument.

gdb shows location of fault is PyType_IsSubtype ()

# import ibm_db import os import sys import logging import pprint import faulthandler import getpass

faulthandler.enable()

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s 0 %(message)s')

logging.debug('Program start')

db_name = 'sample' db_uid = getpass.getuser()

pwd = getpass.getpass('Please enter the password for user ' + db_uid + ' :')

pwd='password' # PLEASE PUT YOUR PASSWORD HERE TO SPEEDUP RETRIES

try: conn = ibm_db.connect(db_name, db_uid, pwd) except: logging.error('Error: Failed to connect to database: %s', ibm_db.conn_errormsg()) sys.exit(1)

logging.debug('Successfully connected to DB2 database')

Dynamic-SQL with parameter markers , bind and prepare and execute

logging.info('Dynamic SQL with parameter markers, bind, prepare, execute')

sql = 'select * from syscat.tables where tabschema=? and type=? with ur' try: stmt = ibm_db.prepare(conn, sql) logging.debug('Successfully prepared SQL with parameter markers') except: logging.error('Exception from ibm_db.prepare: %s ', ibm_db.stmt_errormsg() ) sys.exit(1)

try: ibm_db.bind_param(stmt,1, db_uid.upper()) except: logging.error('Exception from ibm_db.prepare for parameter-1: %s',ibm_db.stmt.errormsg()) sys.exit(1)

logging.debug('Bound parameter 1 OK')

try: ibm_db.bind_param(stmt,2,'T') except: logging.error('Exception from ibm_db.prepare for parameter-2: %s',ibm_db.stmt.errormsg()) sys.exit(1)

logging.debug('Bound parameter 2 OK')

logging.debug('About to execute the prepared statement') try: ibm_db.execute(stmt) logging.debug('Successfully executed prepared statement') except: logging.error('Failed to execute prepared stmt with 2 parameter markers: %s',ibm_db.stmt_errormsg()) sys.exit(1)

try: logging.debug('Fetching result set via .fetch_both()') result_set_dict=ibm_db.fetch_both(stmt) logging.debug('Successfully Fetched first row') except: logging.error('Exception from ibm_db.fetch_both() %s ',ibm_db.stmt_errormsg()) sys.exit(1)

rownum=0 while result_set_dict == True: pprint.pprint(result_set_dict, width=-1) # pretty-print with one line per column of result-set try: result_set_dict=ibm_db.fetch_both(stmt) rownum += 1 except: logging.error('Failed to fetch row number %d of resultset: %s ',(rownum, ibm_db.stmt_errormsg())) sys.exit(1)

logging.info('End of result set')

Close down and exit

logging.debug('Closing database connection') try: ibm_db.close(conn)
except: logging.info('Failed to close the database connection, but ignoring this') sys.exit(1)

logging.debug('Closed database connection successfully')

sys.exit(0) `

SabaKauser commented 7 years ago

My first guess is that this is similar to https://github.com/ibmdb/python-ibmdb/issues/216.

Are you on the latest source code from git or from pypi. pypi does not contain this fix and currently it is available only in git source.

If you are not already on latest source code from git, can you try building the git source and let me know if your problem is gone.

Thanks, Saba.

SabaKauser commented 7 years ago

Tried on latest code, ran over 30 times and its success.

try and let me know.

imavo commented 7 years ago

I am running the following, which I installed with pip3, so I presume they come from pypi. pip3 list | grep ibm-db ibm-db (2.0.7) ibm-db-django (1.1.0.2) ibm-db-sa (0.3.3) When I look at the file for download in github the filename is ibm_db-2.0.7.tar.gz , so is that the same version 2.0.7 that is reported by pip3 list ? Please clarify.

SabaKauser commented 7 years ago

The fix is available in git and you need to clone the source and build it. you can do the following to build: git clone https://github.com/ibmdb/python-ibmdb.git

cd (e.g cd to python-ibmdb-master/IBM_DB/ibm_db) python setup.py build python setup.py install

we are also working on new release that should have this fix and available via pip(pypi), but the release work is in progress.

imavo commented 7 years ago

Is there any outlook for when the next release will be available via pip/pypi , i.e. will it be in 2017, or in 2018 ? I am not currently set up to build from 'C' source on this environment, so it may be easier to wait for next build and work-around the issue in the meanwhile.

SabaKauser commented 6 years ago

The release would happen in 2017. we will announce shortly.