[unixODBC-support] Unixodbc crashing on ubuntu-8.04, under static linkage

Michael Smolsky sitrash at email.com
Mon Dec 1 22:03:29 GMT 2008


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-------------

-- 
Be Yourself @ mail.com!
Choose From 200+ Email Addresses
Get a Free Account at www.mail.com



More information about the unixODBC-support mailing list