[unixODBC-dev] Fw: Unixodbc crashing on ubuntu-8.04, under static linkage

Jon Pounder jonp at inline.net
Tue Dec 2 05:38:33 GMT 2008


Michael Smolsky wrote:
> Jon,
>
> I thought strdup(..) will work only if the types SQLCHAR and char are identical. I admit, that my code doesn't do the perfect char->SQLCHAR conversion as well (what should it be?), but I thought the compiler will at least bark if the types happen to be different...
>
>   
char and sqlchar should be pretty much the same thing for your purposes 
- you've used strlen on it so that pretty much limits you to what strdup 
is going to do anyway.

- you might get a signed/unsigned mismatch on the char type, but not to 
worry, strdup only cares about the 0 on the end, same as strlen.

I'd be more concerned about loop limits being off by one in the counts, 
than I would about typecasting what amounts to a byte no matter what you 
name it.




> Mike.
>
>
>   
>> ----- Original Message -----
>> From: "Jon Pounder" <jonp at inline.net>
>> To: "Development issues and topics for unixODBC" <unixodbc-dev at mailman.unixodbc.org>
>> Subject: Re: [unixODBC-dev] Fw: Unixodbc crashing on ubuntu-8.04, under static linkage
>> Date: Mon, 01 Dec 2008 23:27:52 -0500
>>
>>
>> Michael Smolsky wrote:
>>
>> I'd start by simplifying some of your string stuff.
>>
>> usually
>>
>> newptr = strdup("some string");
>> if !newptr ....
>>
>> is about as simple as it gets, then there is no question your 
>> trailing ; remains in the connect string.
>> I have had trouble in past if that goes missing.
>>
>>
>>
>>
>>     
>>> Hello,
>>>
>>> Peter Harvey asked me to cross-post the message to the dev 
>>> mailing list. The original is on the support mailing list.
>>>
>>> I would appreciate your suggestions.
>>>
>>> Thank you,
>>>
>>> Mike.
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> Subject:
>>> Unixodbc crashing on ubuntu-8.04, under static linkage
>>> From:
>>> "Michael Smolsky" <sitrash at email.com>
>>> Date:
>>> Mon, 1 Dec 2008 17:03:29 -0500
>>> To:
>>> unixodbc-support at mailman.unixodbc.org
>>>
>>> To:
>>> unixodbc-support at mailman.unixodbc.org
>>>
>>>
>>> Hello,
>>>
>>> First of all, thank you for supporting a very useful product.
>>>
>>> I'm using unix-odbc on Ubuntu 8.04, x86_64, that is in the fully 
>>> updated state. I have the following unixodbc packages installed:
>>>
>>> unixodbc        2.2.11-16build1
>>> unixodbc-dev    2.2.11-16build1
>>> odbc-postgresql 1:08.01.0200-2.1
>>>
>>> Gcc's version is 4.2.4 (Ubuntu 4.2.4-1ubuntu3).
>>>
>>> I'm using postgres 8.3.5 for my database server. The server runs locally.
>>>
>>> I have a problem with my app, that is built around unixodbc. When 
>>> the app is linked dynamically against unixodbc (besides other 
>>> libs), it works fine. However, when my app is linked statically, 
>>> it crashes.
>>>
>>> I've isolated the problem and wrote up a fairly simple app, that 
>>> illustrates the issue. The contents of the file odbc_connect.c is 
>>> included in this message. To compile, I use the following command 
>>> lines (there is no makefile in this directory):
>>>
>>> To build the app statically (and observe the crash):
>>>
>>> rm -f ./odbc_connect; make CFLAGS="-Wall" LDFLAGS="-static" 
>>> LOADLIBES="-lodbc -lltdl -ldl -lpthread" ./odbc_connect && 
>>> ./odbc_connect
>>>
>>> To build the same app dynamically (and see no crash), use the 
>>> same command line, but eliminate LDFLAGS="-static" string from it.
>>>
>>> When not crashing (under dynamic linkage), the app produces the 
>>> following output:
>>>
>>> $ rm -f odbc_connect; make CFLAGS="-Wall" LOADLIBES="-lodbc 
>>> -lltdl -ldl -lpthread" odbc_connect && ./odbc_connect
>>> cc -Wall    odbc_connect.c -lodbc -lltdl -ldl -lpthread  -o odbc_connect
>>> INFO: Allocated handle for the environment.
>>> INFO: Set ODBC environment's version attribute.
>>> INFO: Allocated handle for the connection.
>>> INFO: Connected to the data source.
>>> INFO: Disconnected from data source.
>>> INFO: Freed handle for the connection.
>>> INFO: Freed handle for the environment.
>>> INFO: Exiting with success.
>>>
>>> When crashing, the app produces the following output:
>>>
>>> $ rm -f odbc_connect; make CFLAGS="-Wall" LDFLAGS="-static" 
>>> LOADLIBES="-lodbc -lltdl -ldl -lpthread" odbc_connect && 
>>> ./odbc_connect
>>> cc -Wall  -static  odbc_connect.c -lodbc -lltdl -ldl -lpthread  
>>> -o odbc_connect
>>> /usr/lib/gcc/x86_64-linux-gnu/4.2.4/../../../../lib/libltdl.a(ltdl.o): In 
>>> function `sys_dl_open':
>>> (.text+0x3687): warning: Using 'dlopen' in statically linked 
>>> applications requires at runtime the shared libraries from the 
>>> glibc version used for linking
>>> /usr/lib/gcc/x86_64-linux-gnu/4.2.4/../../../../lib/libodbc.a(_odbcinst_UserINI.o): In function 
>>> `_odbcinst_UserINI':
>>> (.text+0x3c): warning: Using 'getpwuid' in statically linked 
>>> applications requires at runtime the shared libraries from the 
>>> glibc version used for linking
>>> INFO: Allocated handle for the environment.
>>> INFO: Set ODBC environment's version attribute.
>>> INFO: Allocated handle for the connection.
>>> Segmentation fault
>>>
>>> Obviously, one can see, that the linker is also not quite happy, 
>>> when linking statically.
>>>
>>> Here's the backtrace of the crash:
>>>
>>> (gdb) r
>>> Starting program: /bla/bla/bla/odbc_connect
>>> [Thread debugging using libthread_db enabled]
>>> INFO: Allocated handle for the environment.
>>> INFO: Set ODBC environment's version attribute.
>>> INFO: Allocated handle for the connection.
>>> [New Thread 0x6fa860 (LWP 15533)]
>>>
>>> Program received signal SIGSEGV, Segmentation fault.
>>> [Switching to Thread 0x6fa860 (LWP 15533)]
>>> 0x0000000000000000 in ?? ()
>>> (gdb) bt
>>> #0  0x0000000000000000 in ?? ()
>>> #1  0x00007f8b3d7696c2 in __pthread_initialize_minimal_internal ()
>>>    from /lib/libpthread.so.0
>>> #2  0x00007f8b3d768e19 in _init () from /lib/libpthread.so.0
>>> #3  0x000000000071a820 in ?? ()
>>> #4  0x000000000049dad6 in call_init ()
>>> #5  0x000000000049dc56 in _dl_init ()
>>> #6  0x000000000047dbac in dl_open_worker ()
>>> #7  0x000000000047bfc6 in _dl_catch_error ()
>>> #8  0x000000000047d430 in _dl_open ()
>>> #9  0x000000000046480c in dlopen_doit ()
>>> #10 0x000000000047bfc6 in _dl_catch_error ()
>>> #11 0x0000000000464c01 in _dlerror_run ()
>>> #12 0x000000000046478e in __dlopen ()
>>> #13 0x0000000000441c7b in sys_dl_open ()
>>> #14 0x000000000043f9c5 in tryall_dlopen ()
>>> #15 0x0000000000441154 in try_dlopen ()
>>> #16 0x00000000004419bd in lt_dlopen ()
>>> #17 0x0000000000402b45 in odbc_dlopen ()
>>> #18 0x00000000004037fb in __connect_part_one ()
>>> #19 0x0000000000407954 in SQLDriverConnect ()
>>> #20 0x00000000004004c5 in main ()
>>> (gdb)
>>>
>>> I believe, I had the same issue with Fedora Core 7, but I am not 
>>> running this OS any more and cannot reproduce the issue.
>>>
>>> I would appreciate it, if you could advise me what I'm doing wrong.
>>>
>>> Thank you in advance,
>>>
>>> Mike.
>>>
>>> PS: Here's my app:
>>>
>>> -------------BEGIN odbc_connect.c-------------
>>>
>>> #include <stdio.h>
>>> #include <stdlib.h>
>>> #include <string.h>
>>>
>>> #include <sql.h>
>>> #include <sqlext.h>
>>>
>>> int isOk(SQLRETURN ret) {
>>>
>>>   return SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret;
>>>
>>> } /* of isOk(..) */
>>>
>>> int main() {
>>>
>>>   char DATA_SOURCE[] = "DSN=testdb;UID=siguc;";
>>>   SQLCHAR* sqlDataSource = 0;
>>>
>>>   SQLHENV env = SQL_NULL_HENV;
>>>
>>>   SQLHDBC dbc = SQL_NULL_HDBC;
>>>
>>>   SQLCHAR completeConnectionString[SQL_MAX_OPTION_STRING_LENGTH];
>>>
>>>   SQLSMALLINT completeConnectionStringLen;
>>>
>>>   SQLRETURN ret;
>>>
>>>   int i;
>>>
>>>   ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to allocate handle for the environment, 
>>> exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Allocated handle for the environment.\n");
>>>   }
>>>
>>>   ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
>>>
>>>   if (!isOk(ret)) {
>>>     printf
>>>       ("ERROR: Failed to set ODBC environment's version 
>>> attribute, exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Set ODBC environment's version attribute.\n");
>>>   }
>>>
>>>   ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to allocate handle for the connection, 
>>> exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Allocated handle for the connection.\n");
>>>   }
>>>
>>>   sqlDataSource = (SQLCHAR*) malloc(sizeof(SQLCHAR) * 
>>> (strlen(DATA_SOURCE) + 1));
>>>
>>>   if (!sqlDataSource) {
>>>     printf("Failed to allocate memory for storing SQL data source.\n");
>>>     exit(1);
>>>   }
>>>
>>>   for (i = 0; i < strlen(DATA_SOURCE); ++ i)
>>>     sqlDataSource[i] = DATA_SOURCE[i];
>>>
>>>   sqlDataSource[strlen(DATA_SOURCE)] = 0;
>>>
>>>   ret = SQLDriverConnect
>>>     (dbc,                       /* Connection handle. */
>>>      NULL,                      /* Always null. Not used. */
>>>      &sqlDataSource[0],         /* Connection string. */
>>>      SQL_NTS,                   /* The connection string is 
>>> null-terminated.. */
>>>      completeConnectionString,  /* The complete connection string 
>>> (returned). */
>>>      sizeof(completeConnectionString) / sizeof(completeConnectionString[0]),
>>>      &completeConnectionStringLen,   /* Returned. */
>>>      SQL_DRIVER_COMPLETE             /* What the hell is this? */
>>>      );
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to connect to the data source, exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Connected to the data source.\n");
>>>   }
>>>
>>>   free(sqlDataSource);
>>>   sqlDataSource = 0;
>>>
>>>   ret = SQLDisconnect(dbc);
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to connect from the data source, exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Disconnected from data source.\n");
>>>   }
>>>
>>>   ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc);
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to free handle for the connection, exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Freed handle for the connection.\n");
>>>   }
>>>
>>>   dbc = SQL_NULL_HDBC;
>>>
>>>   ret = SQLFreeHandle(SQL_HANDLE_ENV, env);
>>>
>>>   if (!isOk(ret)) {
>>>     printf("ERROR: Failed to free handle for the environment, exiting.\n");
>>>     exit(1);
>>>   } else {
>>>     printf("INFO: Freed handle for the environment.\n");
>>>   }
>>>
>>>   env = SQL_NULL_HENV;
>>>
>>>   printf("INFO: Exiting with success.\n");
>>>
>>>   return 0;
>>>
>>> } /* of main(..) */
>>>
>>> -------------END odbc_connect.c-------------
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> unixODBC-dev mailing list
>>> unixODBC-dev at mailman.unixodbc.org
>>> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>>>
>>>       
>> _______________________________________________
>> unixODBC-dev mailing list
>> unixODBC-dev at mailman.unixodbc.org
>> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>>     
>
>   
>
>
>   



More information about the unixODBC-dev mailing list