Author Topic: Program works from commandline, but not from codeblocks  (Read 11053 times)

Offline resander

  • Multiple posting newcomer
  • *
  • Posts: 49
Program works from commandline, but not from codeblocks
« on: May 20, 2009, 02:25:53 pm »
For Ubuntu 8.10. using code::blocks rev 5607.

The program connects ok via ODBC to Oracle Express on the Ubuntu commandline:   

ken@ken-desktop:~/projects/lsken/bin/Debug$ ./lsken
After SQLConnect  << my tracemessage
ODBC connected OK << my tracemessage


but not from codeblocks Run in Build menu or Start on Debug menu.
I receive error:

Can't open lib /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib/libsqora.so.10.1

The so file is the Oracle ODBC driver and the unixODBC driver manager outputs the message.

The startup script bashrc sets LD_LIBRARY_PATH to:
/usr/lib:/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib.

When using Start on Debug menu I stopped after the error and checked the library path:

ken@ken-desktop:~/projects/lsken/bin/Debug$ echo $LD_LIBRARY_PATH
/usr/lib:/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib

which is still the same.

What may be the cause?

Offline resander

  • Multiple posting newcomer
  • *
  • Posts: 49
Re: Program works from commandline, but not from codeblocks
« Reply #1 on: May 23, 2009, 07:24:53 pm »
Problem is the same for Release mode, i.e. the program ran OK from commandline and failed from Run menu in codeblocks.

I have written a minimal test program in main.cpp that shows the problem. This (small as program, but a bit long as text in a post):


#include <stdio.h>
#include <string.h>
#include "sql.h"
#include "sqlext.h"

static void dspmessage ( const char * title , const char * msg )
   {
   printf ( "%s: %s " , title , msg ) ;
   printf ( "Press Return/Enter to continue\n" ) ;
   getchar ( ) ;  //to wait
   }

static void sqlerrinfo ( int handletp , int handle , const char * logstring )
   {
   char txt [ 4002 ] ;
   int maxlen = 4000 ;
   int ofs = sprintf ( txt , "%s\n" , logstring ) ;
   int recnbr = 1;
   long nerr ;
   short lenerrmsg ;
   int ln ;
   unsigned char state [ 12 ] = { 0 } ;
   unsigned char msg [ SQL_MAX_MESSAGE_LENGTH+1 ] = { 0 } ;
   char line [ 802 ] = { 0 } ;
   int rc = SQL_SUCCESS ;
   while ( rc != SQL_NO_DATA_FOUND)
      {
      rc = SQLGetDiagRec ( handletp , (SQLHANDLE)handle , recnbr ,
                           state, &nerr , msg , SQL_MAX_MESSAGE_LENGTH ,
                           &lenerrmsg ) ;
      ln = sprintf ( line , "%d: st=%s, nerr=%d, msg=\n%s\n" ,
                     recnbr , state , (int)nerr , msg ) ;
      if ( ln+ofs < maxlen )
         {
         strcpy ( txt+ofs , line ) ;
         ofs += ln ;
         }
      else
         {
         break ;
         } ;
      recnbr++; // for next diagnostic record.
      }
   dspmessage ( "usage error" , txt ) ;
   }

static bool success ( SQLRETURN rc )
   {
   return (rc == SQL_SUCCESS) || (rc == SQL_SUCCESS_WITH_INFO) ;
   }

static bool connectSrv ( const char * dsn , const char * uid , const char * pwd )
   {
   SQLHENV henv;
   SQLRETURN rc = SQLAllocHandle ( SQL_HANDLE_ENV , SQL_NULL_HANDLE , &henv ) ;
   if ( !success ( rc ) )
      {
      dspmessage ( "sqlapi" , "SQLAllocHandle Env failed" ) ;
      return false ;
      }

   rc = SQLSetEnvAttr ( henv, SQL_ATTR_ODBC_VERSION , (void*)SQL_OV_ODBC3 , 0 ) ;
   if ( !success ( rc ) )
      {
      sqlerrinfo ( SQL_HANDLE_ENV , (int)henv , "Set ODBC version fail" ) ;
      SQLFreeEnv ( henv ) ;
      return false ;
      } ;

   SQLHDBC hdbc;
   rc = SQLAllocHandle ( SQL_HANDLE_DBC , henv , &hdbc ) ;
   if ( !success ( rc ) )
      {
      sqlerrinfo ( SQL_HANDLE_ENV , (int)hdbc , "Alloc connection handle error" ) ;
      SQLFreeEnv ( henv ) ;
      return false ;
      } ;

   SQLSetConnectAttr ( hdbc , SQL_LOGIN_TIMEOUT , (void*)5 , 0 ) ;

   char msg [ 100 ] ;
   rc = SQLConnect ( hdbc , (SQLCHAR*)dsn , SQL_NTS,
                      (SQLCHAR*) uid , SQL_NTS,
                      (SQLCHAR*) pwd , SQL_NTS);
   if ( !success ( rc ) )
      {
      sprintf ( msg , "SQLConn: dsn=%s user=%s pwd=%s\n" , dsn , uid , pwd ) ;
      sqlerrinfo ( SQL_HANDLE_DBC , (int)hdbc , msg ) ;
      SQLFreeConnect ( hdbc ) ;
      SQLFreeEnv ( henv ) ;
      dspmessage ( "sqlapi" , "SQLConnect failed" ) ;
      return false ;
      } ;

   SQLHSTMT hstmt;
   rc = SQLAllocHandle ( SQL_HANDLE_STMT , hdbc , &hstmt);
   if ( !success ( rc ) )
      {
      sqlerrinfo ( SQL_HANDLE_DBC , (int)hdbc , "Alloc Stmt error" ) ;
      SQLDisconnect ( hdbc ) ;
      SQLFreeConnect ( hdbc ) ;
      SQLFreeEnv ( henv ) ;
      return false ;
      } ;
   return true ;
   }

int main ( int argc , char * argv[] )
   {
   if ( connectSrv ( "TestDBDSN"  , "hr" , "hr" ) )
      {
      dspmessage ( "sqlapi" , "ODBC Connect OK\n" ) ;
      }
   return 0 ;
   }


I am using unixODBC 2.2.11-16build2 available via Synaptic package Manager in Ubuntu 8.10. The sql header files are from the Include directory of the installed unixODBC. The unixODBC is in usr/lib/libodbc.so.1 and is linked using local linker settings section in codeblocks. There are no global linker settings.
The oracle ODBC driver is in /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib/libsqora.so.10.1

I have added the following to the Ubuntu startup script:
#  Added by ken for oracle

ODBCINI=/etc/odbc.ini
export ODBCINI
ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export ORACLE_HOME
TNS_ADMIN=$ORACLE_HOME/network/admin
export TNS_ADMIN
LD_LIBRARY_PATH=/usr/lib:/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/lib
export LD_LIBRARY_PATH

Earlier on I had exactly the same error when I had set the LD_LIBRARY_PATH incorrectly, but it is correct now. Is there any possibility of codeblocks disturbing the LD_LIBRARY_PATH value? OR is there anything that I may have done wrong when setting up the project that might cause this?

To summarise:

 THISAPP + unixODBC in Debug mode OK on commandline
 THISAPP + unixODBC in Release mode OK on commandline
 THISAPP + unixODBC + CodeBlocks Start in Debug mode fails to load the Oracle ODBC driver
   APP + unixODBC + CodeBlocks Run in Release mode fails to load the Oracle ODBC driver

What else can I do to try to pinpoint the problem?
 

Offline Jenna

  • Administrator
  • Lives here!
  • *****
  • Posts: 7255
Re: Program works from commandline, but not from codeblocks
« Reply #2 on: May 23, 2009, 08:15:21 pm »
Did you try to start C::B from a console, where your variables and LD_LIBRARY_PATH are definitely visible ?

Maybe it runs in a context, where they are not set (correctly).

Offline resander

  • Multiple posting newcomer
  • *
  • Posts: 49
Re: Program works from commandline, but not from codeblocks
« Reply #3 on: May 23, 2009, 09:51:17 pm »
Thanks Jens,

I always start from the Applications->Programming->Codeblocks on the Ubuntu menu (don't know any other way). The project opens OK and behaves as in all other projects I have been using before for codeblocks.

This seems to be a codeblocks problem from the perspective of a naive beginner like myself. But of course I dont' know. I cannot solve this.

Offline resander

  • Multiple posting newcomer
  • *
  • Posts: 49
Re: Program works from commandline, but not from codeblocks
« Reply #4 on: May 24, 2009, 01:55:25 pm »
Jens,
I misread your previous post and have just started codeblocks from my home directory from the command line by ken@ken-desktop:~$ /usr/bin/codeblocks

I completely rebuilt Debug and Release versions, but result is still same.

I also defined LD_LIBRARY_PATH via Settings->Environment->Environment-variables and rebuilt, but still the same.

Offline resander

  • Multiple posting newcomer
  • *
  • Posts: 49
Re: Program works from commandline, but not from codeblocks
« Reply #5 on: May 27, 2009, 11:19:37 am »
I inserted the following three calls at the start of connectSrv routine (see a previous post on this thread):

char * odbcini = getenv ( "ODBCINI" ) ;
char * oraclehome = getenv ( "ORACLE_HOME" ) ;
char * ldlibrarypath = getenv ( "LD_LIBRARY_PATH" ) ;
 
char * getenv (const char *name)
returns a string that is the value of the environment variable name.
If the environment variable name is not defined, the value is a null pointer.


Starting codeblocks from Application menu

The odbcini and oraclehome variables are NULL after the getenv calls. This means they are not available for my program, which fails finding the ODBC driver and other library dependencies. The ldlibrarypath variable is .:, which is wrong.


Starting codeblocks from my HOME /home/ken and commandline as /usr/bin/codeblocks

Works.


Wikipedia says this about environment:

'In all Unix and Unix-like systems, each process has its own private set of environment variables. By default, when a process is created it inherits a duplicate environment of its parent process, except for explicit changes made by the parent when it creates the child. At API level, these changes must be done between fork and exec.'

When I start codeblocks from the commandline my environment is inherited by codeblocks. Then if codeblocks starts my-prog by exec/fork the environment would be passed on again, which is what my-prog needs.

There is a predefined program variable extern char ** environ; which is an array of property strings in the environment. When starting codeblocks from the Application menu I put these to the screen with printf and could see the environment was different from mine.

- there are fewer properties, especially the important ODBCINI,
  ORACLE_HOME are missing

- LD_LIBRARY_PATH is .: which is different from my ldlibpath

- PWD is set to /home/ken/Projects/lsken2      my PWD is /home/ken

- HOME is /home/ken for both (can be used to chdir $HOME before starting
  codeblocks from menu)