Solved

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

Posted on 2012-04-02
4
590 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 34

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
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…
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 opening and reading files in the C programming language.

690 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