Bug #15248 | Memory allocation bug in SQLDriverConnect | ||
---|---|---|---|
Submitted: | 25 Nov 2005 16:15 | Modified: | 8 Mar 2007 1:25 |
Reporter: | Stéphane Donzé | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / ODBC | Severity: | S2 (Serious) |
Version: | 3.51.12 | OS: | Linux (Linux (32 and 64)) |
Assigned to: | Bogdan Degtyariov | CPU Architecture: | Any |
[25 Nov 2005 16:15]
Stéphane Donzé
[25 Nov 2005 16:16]
Stéphane Donzé
First valgrind output
Attachment: exa.3log.652 (application/octet-stream, text), 11.48 KiB.
[25 Nov 2005 16:17]
Stéphane Donzé
Second valgrind output (after changing the login/password in the connection string)
Attachment: exa.3log.1431 (application/octet-stream, text), 11.67 KiB.
[25 Nov 2005 16:17]
Stéphane Donzé
valgrind: http://valgrind.org/
[26 Nov 2005 8:23]
Vasily Kishkin
Sorry...I was not able to reproduce the bug. Could you please build and run my test case ? My test case is attached.
[26 Nov 2005 8:23]
Vasily Kishkin
Test case
Attachment: test.c (text/plain), 5.28 KiB.
[28 Nov 2005 22:39]
Stéphane Donzé
I was able to reproduce the bug with your test case (slightly modified to make it compile and use an existing table on my side: cf file test2.c) I ran the test on a Linux 64 machine (Linux version 2.4.21-32.0.1.ELsmp (bhcompile@thor.perf.redhat.com) (gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)) #1 SMP Tue May 17 17:46:36 EDT 2005) The test case is working without any error with the 3.51.10 driver. When ran against the 3.51.12, it dumps a core at the second connection: [Thread debugging using libthread_db enabled] [New Thread 182906365120 (LWP 5246)] Connect.... Test.... Fetched... Disconnect.... Connect.... Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 182906365120 (LWP 5246)] 0x0000002a95f56160 in strcasecmp () from /lib64/tls/libc.so.6 (gdb) where #0 0x0000002a95f56160 in strcasecmp () from /lib64/tls/libc.so.6 #1 0x0000002a96574e4e in MYODBCUtilReadConnectStr () from /ng/lib/amd64-linux/libmyodbc3_r.3.51.12.so #2 0x0000002a9656a0db in my_SQLDriverConnect () from /ng/lib/amd64-linux/libmyodbc3_r.3.51.12.so #3 0x0000002a9656a504 in SQLDriverConnect () from /ng/lib/amd64-linux/libmyodbc3_r.3.51.12.so #4 0x0000002a95684996 in SQLDriverConnect (hdbc=0x2a98b02200, hwnd=0x0, conn_str_in=0x7fbffff8a5 "DSN=logs;User=logsuser;Password=xxxxxxx;Server=ng5;Database=logs", len_conn_str_in=-3, conn_str_out=0x5023c0 "DATABASE=logs;DESCRIPTION=Site logs;DSN=logs;OPTION=3;PWD=xxxxxxx;PORT=0;SERVER=ng5;UID=logsuser", conn_str_out_max=255, ptr_conn_str_out=0x5024c0, driver_completion=0) at SQLDriverConnect.c:1155 #5 0x0000000000401413 in main (argc=-1733211584, argv=0x2a9657a60f) at /ng/src/donze/ng/src/tmp/test.c:123 (gdb) quit I also attach the valgrind output corresponding to this test case.
[28 Nov 2005 22:40]
Stéphane Donzé
Test case producing a SEGV in strcasecmp
Attachment: test2.c (application/octet-stream, text), 5.21 KiB.
[28 Nov 2005 22:42]
Stéphane Donzé
valgrind output for the test case
Attachment: sqltest.3log.5294 (application/octet-stream, text), 5.57 KiB.
[7 Dec 2005 12:09]
Vasily Kishkin
I was able to reproduce the bug on Linux Suse 9.3. Thanks for correct test case. I would like to notice test case works fine on Windows.
[13 Mar 2006 10:51]
Bogdan Degtyariov
I was able to repeat this bug with MyODBC 3.51.06 (threadsafe library only). Both versions of MyODBC 3.51.12 worked well on SuSE 9.2 (unixODBC 2.1.11)
[31 Mar 2006 13:27]
Pierre MARC
Have the same trouble on linux RedHat entreprise 4. I cannot make the MyOdbc driver run correctly in a multithread environment. I wrote also a little test program. sometimes it runs, sometimes it fails with the "Character set 'latin1' ..." message, sometimes it fails with a segmentation fault. I used MySql 5.0.19, MyOdbc 3.51.12 and UnixOdbc 2.2.11. My ODBC DSN uses the /usr/lib/libmyodbc3_r.so. I also tried recompiling myodbc but the compilation failed with error telling that there are multiple definition of adler32. Is there any workarround to that blocking situation ? to reproduce the pb: testodbc -s sourcename -u user -p password -h numthreads Here is the source of my testodbc program: #include <pthread.h> #include <stdio.h> #include <sql.h> // core #include <sqlext.h> // extensions #include <string> using namespace std; // Thread mutex pthread_mutex_t m_mMutex; // End Thread flag int EndThread = 0; int NumErrors = 0; // Num threads int NumThreads = 1; SQLCHAR Source[255]; // Data source name SQLCHAR User[255]; // Data source user SQLCHAR Password[255]; // Data source password SQLCHAR Table[255]; // Data source table void DisplaySqlError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt); int DisplaySqlStringInfo(SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT InfoType); int DoConnect(bool WithInfo, bool WithSearch); void* ThreadMain(void *Value); int main(int argc, char* argv[]) { if(argc <=1) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } Source[0] = '\0'; User[0] = '\0'; Password[0] = '\0'; int i; for(i=1;i<argc;i++) { if(strcmp(argv[i], "-s") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Source, argv[i]); } else if(strcmp(argv[i], "-u") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) User, argv[i]); } else if(strcmp(argv[i], "-p") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Password, argv[i]); } else if(strcmp(argv[i], "-t") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Table, argv[i]); } else if(strcmp(argv[i], "-h") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; NumThreads = atoi(argv[i]); if(NumThreads <= 0) NumThreads = 1; if(NumThreads > 500) NumThreads = 500; } } if(!DoConnect(true, false)) return 0; pthread_mutex_init(&m_mMutex, NULL); EndThread = NumThreads; int EndThreadHere = EndThread; for(i=0;i<NumThreads;i++) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); // the unix thread has a system scope for best performances pthread_t thid; pthread_create(&thid, &attr, ThreadMain, NULL); pthread_attr_destroy(&attr); } while(EndThreadHere) { pthread_mutex_lock(&m_mMutex); EndThreadHere = EndThread; pthread_mutex_unlock(&m_mMutex); } if(NumErrors) printf("\nProgram terminated with %d errors\n", NumErrors); else printf("\nProgram terminated successfully\n"); pthread_mutex_unlock(&m_mMutex); pthread_mutex_destroy(&m_mMutex); return 0; } void* ThreadMain(void *Value) { int RetVal = DoConnect(false, true); pthread_mutex_lock(&m_mMutex); if(!RetVal) NumErrors++; EndThread--; pthread_mutex_unlock(&m_mMutex); pthread_detach(pthread_self()); pthread_exit(NULL); return (void *)(0); // end of thread (unix) } int DoConnect(bool WithInfo, bool WithSearch) { SQLHENV henv; /* environment handle */ SQLHDBC hdbc; /* connection handle */ SQLHSTMT hstmt; /* statement handle */ SQLRETURN retcode; /* return code */ SQLCHAR SQLStmt[255]; henv = NULL; hdbc = NULL; hstmt = NULL; retcode = SQLAllocEnv(&henv); retcode = SQLAllocConnect(henv, &hdbc); retcode = SQLConnect(hdbc, Source, SQL_NTS, User, SQL_NTS, Password, SQL_NTS); if (retcode != SQL_SUCCESS) { printf("*** Cannot connect data source\n"); DisplaySqlError(henv, hdbc, hstmt); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } if(WithInfo) { printf("Database name: "); DisplaySqlStringInfo(henv, hdbc,SQL_DBMS_NAME); printf("\nDatabase version: "); DisplaySqlStringInfo(henv, hdbc,SQL_DBMS_VER); printf("\nDriver name: "); DisplaySqlStringInfo(henv, hdbc,SQL_DRIVER_NAME); printf("\nDriver version: "); DisplaySqlStringInfo(henv, hdbc,SQL_DRIVER_VER); printf("\nDriver ODBC version: "); DisplaySqlStringInfo(henv, hdbc,SQL_ODBC_VER); printf("\n"); } if(WithSearch) { if(strlen((char *)Table)) { retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc,&hstmt); if (retcode == SQL_SUCCESS) { strcpy((char *)SQLStmt, "SELECT * FROM "); strcat((char *)SQLStmt, (char *)Table); retcode = SQLExecDirect(hstmt, SQLStmt, SQL_NTS); // Display The Results Of The SQL Query if (retcode == SQL_SUCCESS) printf("Database search successful\n"); else { printf("*** Error searching database\n"); DisplaySqlError(henv, hdbc, hstmt); SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } } // Free The SQL Statement Handle if(hstmt != NULL) SQLFreeHandle(SQL_HANDLE_STMT, hstmt); } } SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 1; } void DisplaySqlError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt) { SQLCHAR Message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR State[10]; SQLINTEGER NativeError; SQLSMALLINT TextLength; Message[0] = '\0'; SQLError(henv, hdbc, hstmt, State, &NativeError, Message, SQL_MAX_MESSAGE_LENGTH+1, &TextLength); printf("SQL error: %s\n", (const char *)Message); } int DisplaySqlStringInfo(SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT InfoType) { SQLRETURN retcode; /* return code */ SQLCHAR info[255]; /* info string for SQLGetInfo */ SQLSMALLINT cbInfoValue; info[0] = '\0'; retcode = SQLGetInfo(hdbc,InfoType, &info, sizeof(info),&cbInfoValue); if (retcode == SQL_SUCCESS) printf((const char *)info); else { printf("*** Cannot get info from data source\n"); DisplaySqlError(henv, hdbc, NULL); return 0; } return 1; } makefile: CXX = g++ CXXFLAGS = -I- -I./ -D_REENTRANT -D_GNU_SOURCE -DLINUX LDFLAGS = -L./ -lpthread -ldl -lodbc testodbc :: testodbc.o $(CXX) -o $@ $^ $(LDFLAGS) strip $@ testodbc.o : testodbc.cpp $(CXX) -c -o $@ $< $(CXXFLAGS)
[13 Apr 2006 19:29]
Mark Smith
I am 95% sure this is a duplicate of bug 11892 (I have been debugging this same problem for a day now).
[11 May 2006 16:50]
Paul DuBois
Not enough information is given to produce a changelog entry. What is the version number for the fix? Is the problem reported actually the bug that was fixed? Thanks.
[8 Mar 2007 1:25]
Jim Winstead
This is a duplicate of Bug #11892.