Solved

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

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to install SVN Command Line Client? 5 78
SQL Query Producing decimal places when it shouldn;t be 8 50
draw a Christmas tree by using a nested loop? 26 76
C++ Code Issue 4 24
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

840 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