Solved

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

Posted on 2012-04-02
4
579 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 32

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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

746 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

10 Experts available now in Live!

Get 1:1 Help Now