Solved

C++ Sybase embedded API issues against existing Solaris code on Linux

Posted on 2012-04-02
4
585 Views
Last Modified: 2012-04-03
I am having problems returning a correct result_type value from ct_results from the below code snippet. Stepping through the code, app appears to be good until the call to    retcode = ct_results(m_Cmd, &result_type); . This has been running for years on Solaris but is being migrated to Linux. Numerious small casting fixups were needed to get to this point, mostly casting differences with type int and Symase CS_XXX types. To simplify, I removed much unnecessary code from this example. Can anyone assist?

Running Sybase 15 with Linux kernel 2.6.18 and g++ 4.1
-------------------------------------------------------------------------------------
bool Sybase::Process(const char *pCmd, bool bReadText)
{
   #if !defined NO_SYBASE
      char          *tmpcmd = NULL;
      CS_RETCODE     retcode;
      CS_INT         result_type;
      CS_DATAFMT     datafmt;
      int            affected, commandLength;

        if ( !pCmd )
        {
              return false;
        }

        commandLength = strlen(pCmd);

      try
      {
         CleanupData(true);
         #if !defined NO_SYBASE
            if(ct_cmd_alloc(m_Connection->Connection(), &m_Cmd) != CS_SUCCEED)
            {
             }
         #endif
      }
      catch(...)
      {
       }

      try
      {
         tmpcmd = new char [ commandLength + 1 ];
         strcpy(tmpcmd, pCmd);
         // Send database uses
         retcode = ct_command(m_Cmd, CS_LANG_CMD, tmpcmd, CS_NULLTERM, CS_UNUSED);
         delete [] tmpcmd;

         if(retcode != CS_SUCCEED)
         {
            m_Code = -1;
            return false;
         }

      }
      catch(...)
      {
         DELETE_ARRAYPTR(tmpcmd);
         return false;
      }

      try
      {
         Sem_Lock SybLock(m_Connection->m_mLockSybase);

//#define CS_SUCCEED              (CS_RETCODE)1
//#define CS_FAIL                 (CS_RETCODE)0
//#define CS_MEM_ERROR            (CS_RETCODE)-1
//#define CS_PENDING              (CS_RETCODE)-2
//#define CS_QUIET                (CS_RETCODE)-3
//#define CS_BUSY                 (CS_RETCODE)-4
//#define CS_INTERRUPT            (CS_RETCODE)-5
//#define CS_BLK_HAS_TEXT         (CS_RETCODE)-6

         retcode = ct_send(m_Cmd);
         if(retcode != CS_SUCCEED)
         {
            m_Code = -2;
            return false;
         }

      }
      catch(...)
      {
         return false;
      }

      {
         SAPI_Sem_Lock SybLock(m_Connection->m_mLockSybase);

         // @@TODO - result_type returned here is wrong
       // @@PROBLEM here, result_type not of a CS_XXX form
       // retcode = 1
       // m_Cmd = CS_COMMAND *
       // result_type = 253403074511
               retcode = ct_results(m_Cmd, &result_type);     }

      while(retcode == CS_SUCCEED)
      {
         //@@ Result type switch here drops through to default, obviously!
         switch((CS_INT)result_type)
         {
         case CS_ROW_RESULT:
            if(!Bind())
            {
               m_Code = -3;
               return false;
            }

            if(!GetRows(bReadText))
            {
               m_Code = -4;
               return false;
            }

            m_CurrentSet++;
            break;

         case CS_CMD_SUCCEED:
         case CS_CMD_DONE:
            {
            if(ct_res_info(m_Cmd, CS_ROW_COUNT, &affected, CS_UNUSED, NULL) != CS_SUCCEED) return false;
               m_vResult[(m_CurrentSet > 0 ? m_CurrentSet-1 : 0)]->m_RowsAffected = affected;
            }
            break;

         case CS_CMD_FAIL:
               m_Code = -5;
            break;

         case CS_PARAM_RESULT:
            if(!Bind())
            {
               m_Code = -6;
               return false;
            }

            if(!GetRows(bReadText))
            {
               m_Code = -7;
               return false;
            }

            m_CurrentSet++;
            break;

         case CS_STATUS_RESULT:
            if(!Bind(true))
            {
               m_Code = -8;
               return false;
            }

            if(!GetRows(bReadText))
            {
               m_Code = -10;
               return false;
            }

            m_Code = Item(m_CurrentSet, 0, "Return_Status")->GetInt();

            m_CurrentSet++;
            break;

         case CS_COMPUTE_RESULT:
            break;

         default:
            m_Code = -11;
            return false;
         };

         {
            retcode = ct_results(m_Cmd, &result_type);
         }
      }

      if(retcode == CS_END_RESULTS)
      {
      }
      else return false;
   #else
      m_Code = -9;
      return false;
   #endif
}
0
Comment
Question by:1240
  • 3
4 Comments
 
LVL 33

Accepted Solution

by:
sarabande earned 500 total points
ID: 37802670
the value 253,403,074,511 is far off 32-bit integer size. can you check what sizeof(CS_INT) is on your system and how CS_INT is defined?

can you also post the definitions of the valid return types?

also pCmd and commandLength after strlen would be of interest.

i also would initialize all local variables and would not delete the temporary buffer before end.

note, as ct_results returns with success, the return_type must have a valid value beside the stack memory was corrupted. from my experience with database routines, corruption could happen if you provide a buffer for an asynchronous fetch and free the buffer before the database fetch ended. as the return_type was defined on stack, it would be stack memory that was corrupted. that is likely to happen if you used or passed pointers to local variables to asynchronously running functions. then the stack memory could be reused after the local variable run out-of-scope.

Sara

Sara
0
 

Author Comment

by:1240
ID: 37802696
Ok, thanks. Let me look into all the tips you provided and post info later.
0
 

Author Comment

by:1240
ID: 37802705
Also, this is a 64 bit compile on a 64 bit server.
0
 

Author Closing Comment

by:1240
ID: 37803105
You Rock!!! The problem was the local variables needed initializing. The returned code is now 4046  which is CS_CMD_DONE. I am still having issues futher in the result process but this problem is resolved.

Thanks for all!!!!!!!!!!!!!!!!!1
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C++ Language error 28 189
is twain_32.dll cmpatible with windows 10 ? 10 125
Better understanding on C++ Class serialization and formats 9 60
Beginner to Unreal Engine 4 5 60
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now