Link to home
Start Free TrialLog in
Avatar of ronan_40060
ronan_40060Flag for United States of America

asked on

Junk Characters causing core dump in C++

In Our Application the Middleware is SOAP C++ Binary deployed on Systinet C++ Server and the BackEnd is in DCE technologies.
The Middleware serves as a channel bwetween the DCE backend and the Java Front End.
The Java FE calls the middleware SOAP method listening perticular port no , the SOAP method then  makes an RPC call to invoke a particular method on DCE which then fectches the data from Oracle using pro*c and sends back the various parameters to SOAP middleware and then to Java Front End.
Sometimes through a OUT parameters which are sent from DCE backend for a perticular RPC , some junk characters gets populated and due to which the SOAP C++ binary dumps the core.

Is there  any way to handle the junk characters that are coming from the DCE backend.
I have the following peice of code.

The two required Structures declaration as below
typedef struct prob_struct {
idl_char resolution_status[4];
idl_char problem_type[4];
idl_char problem_sub_type[4];
idl_char *narrative;
struct prob_struct *ptr_NextProb;
} SYS_LC_PROBLEM;


typedef struct  {
idl_char cod_Error[26];
idl_char txt_ErrKey1[26];
idl_char txt_ErrKey2[26];
idl_char txt_ErrKey3[26];
idl_long_int flg_WriteToDatabase;
idl_char ref_num[15];
idl_char seq_num[4];
SYS_LC_PROBLEM *ptr_StartProbList;
idl_ulong_int nbr_ErrorNum;
} SYS_ERROR_STRUCT;      
      
--------------------------------------------------------------------------------------------------
Memory allocation using malloc to the above structures as below

      SYS_ERROR_STRUCT *p_str_ErrorMsg = (SYS_ERROR_STRUCT *)malloc(sizeof(SYS_ERROR_STRUCT));
      memset(p_str_ErrorMsg,'\0',sizeof(SYS_ERROR_STRUCT));
      
      
      SYS_LC_PROBLEM *sys_lc_problem = (SYS_LC_PROBLEM *)malloc(sizeof(SYS_LC_PROBLEM));
      memset(sys_lc_problem,'\0',sizeof(SYS_LC_PROBLEM));
          p_str_ErrorMsg->ptr_StartProbList = sys_lc_problem;
      
      
      SYS_LC_PROBLEM_LIST * p_str_prob_list = (SYS_LC_PROBLEM_LIST*)malloc(sizeof(SYS_LC_PROBLEM_LIST));
      memset(p_str_prob_list,'\0',sizeof(SYS_LC_PROBLEM_LIST));

      SYS_ERR_MSG p_txt_ApplErrorMsg;
          memset(p_txt_ApplErrorMsg,'\0',SYS_LEN_ERROR_MSG);

      error_status_t p_cod_Error = 0;

      // Make a RPC
      long tResult = CC_SJGetChargeDesc(      hndlr,
                                                            p_str_ChargeParams,
                                                            p_nbr_ChargeParams,
                                                            p_str_txn_commn_copies,
                                                            p_nbr_NoOfTiers,
                                                            p_txt_ChargeTypeDesc,
                                                            &p_txt_ChargeDesc,
                                                            p_str_ErrorMsg,
                                                            p_txt_ApplErrorMsg,
                                                            (unsigned char *)user_id,
                                                            &p_cod_Error);

//Get the return object and store all the returned parameter values

RetSJGetChargeDesc retObj;

      retObj->ApplRetStatus=tResult;
      TRACE(" tResult FROM DCE IS = "<<tResult<<"++++++");

      retObj->pTxtChargeDesc=(char*)p_txt_ChargeDesc;
      TRACE(" P Charge Description Text FROM DCE IS = "<<(char*)p_txt_ChargeDesc<<"++++++");
      
      retObj->pStrErrorMsg->codError = (char*)p_str_ErrorMsg->cod_Error;
      TRACE(" COD ERROR FROM DCE IS = "<<(char *)p_str_ErrorMsg->cod_Error<<"++++++");

      retObj->pStrErrorMsg->txtErrKey1 = (char*)p_str_ErrorMsg->txt_ErrKey1;
      TRACE(" ERRORKEY1 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey1<<"++++++");

      retObj->pStrErrorMsg->txtErrKey2 = (char*)p_str_ErrorMsg->txt_ErrKey2;
      TRACE(" ERRORKEY2 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey2<<"++++++");

      retObj->pStrErrorMsg->txtErrKey3 = (char*)p_str_ErrorMsg->txt_ErrKey3;
      TRACE(" ERRORKEY3 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey3<<"++++++");

      retObj->pStrErrorMsg->flgWriteToDatabase = p_str_ErrorMsg->flg_WriteToDatabase;
      TRACE(" Write To Database Flag  FROM DCE IS = "<<p_str_ErrorMsg->flg_WriteToDatabase<<"++++++");

      retObj->pStrErrorMsg->refNum = (char*)p_str_ErrorMsg->ref_num;
      TRACE(" REF NUMBER FROM DCE IS = "<<(char *)p_str_ErrorMsg->ref_num<<"++++++");

      retObj->pStrErrorMsg->seqNum = (char*)p_str_ErrorMsg->seq_num;
      TRACE(" SEQUENCE NUMBER FROM DCE IS = "<<(char *)p_str_ErrorMsg->seq_num<<"++++++");

      retObj->pStrErrorMsg->nbrErrorNum = p_str_ErrorMsg->nbr_ErrorNum;
      TRACE(" NBR ERROR NUMBER FROM DCE IS = "<<p_str_ErrorMsg->nbr_ErrorNum<<"++++++");

      retObj->pTxtApplErrorMsg=(char *)p_txt_ApplErrorMsg;
      TRACE(" P Application Error Message Text FROM DCE IS = "<<(char *)p_cod_Error<<"++++++");

      retObj->pCodError=p_cod_Error;
      TRACE(" P ERROR CODE FROM DCE IS = "<<p_cod_Error<<"++++++");

      //Memory De-allocation
      free(p_str_ChargeParams);  
      p_str_ChargeParams = NULL;
      free(p_str_txn_commn_copies);
      p_str_txn_commn_copies = NULL;
      free(sysLcProb);
      sysLcProb=NULL;
      free(p_str_ErrorMsg);
      p_str_ErrorMsg=NULL;
      free(user_id);
      user_id = NULL;
------------------------------------------------------------------------------------------------------------------------------------------

The log shows

18/10/2008 12:7:28>>After Calling the DCE MEthod CC_SJGetChargeDesc ...tResult = 5716
  TRACE_OUT==> tResult FROM DCE IS = 5716++++++
  TRACE_OUT==> P Charge Description Text FROM DCE IS = ++++++
  TRACE_OUT==> COD ERROR FROM DCE IS = CcyDecimalsNF++++++
  TRACE_OUT==> ERRORKEY1 FROM DCE IS = ®@DV0++++++
  TRACE_OUT==> ERRORKEY2 FROM DCE IS = ++++++
  TRACE_OUT==> ERRORKEY3 FROM DCE IS = ++++++
  TRACE_OUT==> Write To Database Flag  FROM DCE IS = 0++++++
  TRACE_OUT==> REF NUMBER FROM DCE IS = ++++++
  TRACE_OUT==> SEQUENCE NUMBER FROM DCE IS = ++++++
  TRACE_OUT==> NBR ERROR NUMBER FROM DCE IS = 5716++++++
  TRACE_OUT==> P Application Error Message Text FROM DCE IS = ++++++
  TRACE_OUT==> P ERROR CODE FROM DCE IS = 0++++++
Assertion failed: srcLen == 0, file ../../../../systinet-server-cpp-6.5/src/tools/STLSupport/STLSupport.cpp, line 188
Unhandled exception; exiting!
Exception kind is status,value is 6. Thread 25 .

As you can see the "RACE_OUT==> ERRORKEY1 FROM DCE IS = ®@DV0++++++"
Junk characters got populated from the DCE  to and then resulted into a core dump.

In spite of allocating a memory to retObj->pStrErrorMsg->txtErrKey1 = (char*)p_str_ErrorMsg->txt_ErrKey1;
which is a part of a structure

SYS_ERROR_STRUCT *p_str_ErrorMsg = (SYS_ERROR_STRUCT *)malloc(sizeof(SYS_ERROR_STRUCT));
memset(p_str_ErrorMsg,'\0',sizeof(SYS_ERROR_STRUCT));  

Is any any way to prevent a core dump in SOAP C++ Binary ?

many Thanks
Avatar of Infinity08
Infinity08
Flag of Belgium image

>> Junk characters got populated from the DCE  to and then resulted into a core dump.

Why do the junk characters cause a core dump ? What do you do with those junk characters ? Why are those junk characters there ?

What's this assertion about ?

>> Assertion failed: srcLen == 0
Avatar of ronan_40060

ASKER

We dont do anything with the Junk characters , those are there and cause a core dump in the Systinet C++ Server which holds the SOAP C++ binary.

Assertion failed : scrlen ==0 , gets executed in Sytinet C++ file for which we do have any access
This assertion failed condition appears only in the case of junk characters come populated from Backend.

we are not sure why only junk characters caused assertion failed and results in a core dump.
Is there any way to remove the junk characters from a C++  string after those are populated >?
The memory is allocated using malloc , would using a Smart pointer be more suited ?
>> We dont do anything with the Junk characters

Then how can they cause a core dump ? If nothing happens to them, then they shouldn't have an impact, and certainly not cause a core dump.
Or in other words : if those junk values are the cause of the core dump, then something must be happening to them.


>> This assertion failed condition appears only in the case of junk characters come populated from Backend.

Then what does srclen refer to ? What is it the length of ?


>> Is there any way to remove the junk characters from a C++  string

Removing junk characters is not difficult - just set the first to '\0'. More difficult is to determine which characters are junk characters, and which are normal characters. Can you do that ?


>> The memory is allocated using malloc , would using a Smart pointer be more suited ?

Do you have a memory leak problem too ?
Infinity
Thanks for ur inputs
The core dump happens only when Junk characters are populated .  Im not sure why those junk cause a core dump. Please find the attached gdb trace of a core dump

 we do not have a file in which assertion failed occurs i.e  srclen ==0 so its impossible to know what it refers to

Sure I will assign a NULL to the first .
I have no idea on determining which characters are junk and which  are normal
Its difficlut for me

Memory is released properly with free();

I initially thought it got something to do with memory hence had a question on it.

My main doubt is  how can i remove junk characters in case when they appear

retObj->pStrErrorMsg->codError = (char*)p_str_ErrorMsg->cod_Error;
retObj->pStrErrorMsg->codError  = '\0';

should resolve the problem




GDBFile.txt
>> I have no idea on determining which characters are junk and which  are normal

Then you have no way of reliably "fixing" the junk characters, since you don't know which ones to fix.


>> retObj->pStrErrorMsg->codError  = '\0';

'\0' is a char, not a char*. If you want to set the first character to '\0', you need to do :

        retObj->pStrErrorMsg->codError[0]  = '\0';

If you want to set the pointer to NULL, you need to do :

        retObj->pStrErrorMsg->codError  = NULL;


>> Please find the attached gdb trace of a core dump

The problem occurs in WASP_STLStringSerializer::valueToString. Do you have the source code for that method ?
What I have observed that only in the case of
TRACE_OUT==> COD ERROR FROM DCE IS = CcyDecimalsNF++++++
thats it "CcyDecimalsNF" is returned by the backend , junk characters are populated, so my fix would be if
while  (strcmp((char*)p_str_ErrorMsg->cod_Error ,"CcyDecimalsNF") !=0)
 retObj->pStrErrorMsg->codError  = NULL;

This should avoid junk characters being assigned.

>> The problem occurs in WASP_STLStringSerializer::valueToString. Do you have the source code for that method ?

Sorry We do not have the access to the above file

But from the GBD trace is it possible to avoid the code to fail in WASP_STLStringSerializer::valueToString ? by allocating a NULL ?


Many Thanks
 
>> But from the GBD trace is it possible to avoid the code to fail in WASP_STLStringSerializer::valueToString ? by allocating a NULL ?

Without seeing the code, I can't be sure. Do you have an API documentation for this method ?
Yes
I have got the API and fortunately I have got the source file STLSupport.cpp also
I have attached the both
The code where it is failing in STLSupport.cpp is

WASP_String *WASP_STLStringSerializer::valueToString (void *instance,EXCENV_DECL) {
    if (!transcoder) {
        transcoder = getUTF8Transcoder(EXCENV); CHECX_OUT_RV(NULL);
    }

    void *src = (void *)((WASP_STD_NS::string *)instance)->c_str();
    int srcLen = ((WASP_STD_NS::string *)instance)->length();
    // create string with reserved size
    WASP_String *result = WASP_String::create(srcLen);
    WASP_StringCleaner resultSC(result);

    WASP_Char *dest = result->getRawBuffer();
    int destLen = srcLen;
    WASP_Char *originalDest = dest;

    transcoder->decode(dest, destLen, src, srcLen, EXCENV); CHECX_OUT_RV(NULL);
    WASP_ASSERT(srcLen == 0); // something is wrong because conversion UTF-8 to WASP_Char cannot enlarge count of characters

    // update string length to true value;
    result->setLength(dest - originalDest);

    result->addRef(); //original will be destroyed by stringCleaner
    return result;
}

Its failing due to

WASP_ASSERT(srcLen == 0); // something is wrong because conversion UTF-8 to WASP_Char cannot enlarge count of characters

Now Since I know why it is failing
How do i resolve the error of UTF-8 to WASP_Char ?

many Thanks




WASP-STLStringSerializer-Class-R.doc
STLSupport.txt
This means I need to convert a UTF-8 to char before the code reaches valueToString function and fails there.
Is there any way from where I can convert UTF-8 to char ?
>> How do i resolve the error of UTF-8 to WASP_Char ?

That might indeed be due to the junk characters.

The next step would be to find out why those junk characters are there.
Junk Characters come from Backend and we can not verify or find out when it comes as Backend is not with us.
The only possible way is to handle the UTF-8 string in SOAP C++ code ?
Is there any function that can convert the (char*)p_str_ErrorMsg->cod_Error;  to a char * and then o/p ?
is w_char can be used ?
>> The only possible way is to handle the UTF-8 string in SOAP C++ code ?

I would think that the junk characters are actually invalid data, and converting it won't help you.

Finding the reason for those characters will provide you with a final solution. Can you show the code that retrieves those junk characters from the backend ?
Inifinty

Unfortuantely I do not have the code that retrieves those junk characters .
The only only option I have with me is to have the SOAP C++ server handle those junk characters and now only by converting to NULL or w_char.
>> is to have the SOAP C++ server handle those junk characters

The SOAP C++ server receives those junk characters, doesn't it ? You do have access to that code, I assume ? Can you show it ?
Infinity
Thanks for ur reply
yes I have the code

The two required Structures declaration as below
typedef struct prob_struct {
idl_char resolution_status[4];
idl_char problem_type[4];
idl_char problem_sub_type[4];
idl_char *narrative;
struct prob_struct *ptr_NextProb;
} SYS_LC_PROBLEM;


typedef struct  {
idl_char cod_Error[26];
idl_char txt_ErrKey1[26];
idl_char txt_ErrKey2[26];
idl_char txt_ErrKey3[26];
idl_long_int flg_WriteToDatabase;
idl_char ref_num[15];
idl_char seq_num[4];
SYS_LC_PROBLEM *ptr_StartProbList;
idl_ulong_int nbr_ErrorNum;
} SYS_ERROR_STRUCT;      
     
--------------------------------------------------------------------------------------------------
Memory allocation using malloc to the above structures as below

      SYS_ERROR_STRUCT *p_str_ErrorMsg = (SYS_ERROR_STRUCT *)malloc(sizeof(SYS_ERROR_STRUCT));
      memset(p_str_ErrorMsg,'\0',sizeof(SYS_ERROR_STRUCT));
     
     
      SYS_LC_PROBLEM *sys_lc_problem = (SYS_LC_PROBLEM *)malloc(sizeof(SYS_LC_PROBLEM));
      memset(sys_lc_problem,'\0',sizeof(SYS_LC_PROBLEM));
          p_str_ErrorMsg->ptr_StartProbList = sys_lc_problem;
     
     
      SYS_LC_PROBLEM_LIST * p_str_prob_list = (SYS_LC_PROBLEM_LIST*)malloc(sizeof(SYS_LC_PROBLEM_LIST));
      memset(p_str_prob_list,'\0',sizeof(SYS_LC_PROBLEM_LIST));

      SYS_ERR_MSG p_txt_ApplErrorMsg;
          memset(p_txt_ApplErrorMsg,'\0',SYS_LEN_ERROR_MSG);

      error_status_t p_cod_Error = 0;

      // Make a RPC
      long tResult = CC_SJGetChargeDesc(      hndlr,
                                                            p_str_ChargeParams,
                                                            p_nbr_ChargeParams,
                                                            p_str_txn_commn_copies,
                                                            p_nbr_NoOfTiers,
                                                            p_txt_ChargeTypeDesc,
                                                            &p_txt_ChargeDesc,
                                                            p_str_ErrorMsg,
                                                            p_txt_ApplErrorMsg,
                                                            (unsigned char *)user_id,
                                                            &p_cod_Error);

//Get the return object and store all the returned parameter values

RetSJGetChargeDesc retObj;

      retObj->ApplRetStatus=tResult;
      TRACE(" tResult FROM DCE IS = "<<tResult<<"++++++");

      retObj->pTxtChargeDesc=(char*)p_txt_ChargeDesc;
      TRACE(" P Charge Description Text FROM DCE IS = "<<(char*)p_txt_ChargeDesc<<"++++++");
     
      retObj->pStrErrorMsg->codError = (char*)p_str_ErrorMsg->cod_Error;
      TRACE(" COD ERROR FROM DCE IS = "<<(char *)p_str_ErrorMsg->cod_Error<<"++++++");

      retObj->pStrErrorMsg->txtErrKey1 = (char*)p_str_ErrorMsg->txt_ErrKey1;
      TRACE(" ERRORKEY1 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey1<<"++++++");

      retObj->pStrErrorMsg->txtErrKey2 = (char*)p_str_ErrorMsg->txt_ErrKey2;
      TRACE(" ERRORKEY2 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey2<<"++++++");

      retObj->pStrErrorMsg->txtErrKey3 = (char*)p_str_ErrorMsg->txt_ErrKey3;
      TRACE(" ERRORKEY3 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey3<<"++++++");

      retObj->pStrErrorMsg->flgWriteToDatabase = p_str_ErrorMsg->flg_WriteToDatabase;
      TRACE(" Write To Database Flag  FROM DCE IS = "<<p_str_ErrorMsg->flg_WriteToDatabase<<"++++++");

      retObj->pStrErrorMsg->refNum = (char*)p_str_ErrorMsg->ref_num;
      TRACE(" REF NUMBER FROM DCE IS = "<<(char *)p_str_ErrorMsg->ref_num<<"++++++");

      retObj->pStrErrorMsg->seqNum = (char*)p_str_ErrorMsg->seq_num;
      TRACE(" SEQUENCE NUMBER FROM DCE IS = "<<(char *)p_str_ErrorMsg->seq_num<<"++++++");

      retObj->pStrErrorMsg->nbrErrorNum = p_str_ErrorMsg->nbr_ErrorNum;
      TRACE(" NBR ERROR NUMBER FROM DCE IS = "<<p_str_ErrorMsg->nbr_ErrorNum<<"++++++");

      retObj->pTxtApplErrorMsg=(char *)p_txt_ApplErrorMsg;
      TRACE(" P Application Error Message Text FROM DCE IS = "<<(char *)p_cod_Error<<"++++++");

      retObj->pCodError=p_cod_Error;
      TRACE(" P ERROR CODE FROM DCE IS = "<<p_cod_Error<<"++++++");

      //Memory De-allocation
      free(p_str_ChargeParams);  
      p_str_ChargeParams = NULL;
      free(p_str_txn_commn_copies);
      p_str_txn_commn_copies = NULL;
      free(sysLcProb);
      sysLcProb=NULL;
      free(p_str_ErrorMsg);
      p_str_ErrorMsg=NULL;
      free(user_id);
      user_id = NULL;
------------------------------------------------------------------------------------------------------------------------------------------

The log shows

18/10/2008 12:7:28>>After Calling the DCE MEthod CC_SJGetChargeDesc ...tResult = 5716
  TRACE_OUT==> tResult FROM DCE IS = 5716++++++
  TRACE_OUT==> P Charge Description Text FROM DCE IS = ++++++
  TRACE_OUT==> COD ERROR FROM DCE IS = CcyDecimalsNF++++++
  TRACE_OUT==> ERRORKEY1 FROM DCE IS = ®@DV0++++++
  TRACE_OUT==> ERRORKEY2 FROM DCE IS = ++++++
  TRACE_OUT==> ERRORKEY3 FROM DCE IS = ++++++
  TRACE_OUT==> Write To Database Flag  FROM DCE IS = 0++++++
  TRACE_OUT==> REF NUMBER FROM DCE IS = ++++++
  TRACE_OUT==> SEQUENCE NUMBER FROM DCE IS = ++++++
  TRACE_OUT==> NBR ERROR NUMBER FROM DCE IS = 5716++++++
  TRACE_OUT==> P Application Error Message Text FROM DCE IS = ++++++
  TRACE_OUT==> P ERROR CODE FROM DCE IS = 0++++++
Assertion failed: srcLen == 0, file ../../../../systinet-server-cpp-6.5/src/tools/STLSupport/STLSupport.cpp, line 188
Unhandled exception; exiting!
Exception kind is status,value is 6. Thread 25 .
Can you show a memory dump of the data in p_str_ErrorMsg->txt_ErrKey1 ?
Here is my modified code

if(! strcmp((char *)p_str_ErrorMsg->cod_Error, "CcyDecimalsNF"))
      {

            char *local = (char*)malloc(sizeof((char*)p_str_ErrorMsg->txt_ErrKey1) +1);
            memset((char *)local,'\0',(sizeof((char*)p_str_ErrorMsg->txt_ErrKey1) +1));
            strcpy(local,(char*)p_str_ErrorMsg->txt_ErrKey1);
      

      int size = mbstowcs(NULL, local, 0) + 1;

      if (size  == 0)
            {
                  retObj->pstrErrorMsg->txtErrKey1 = NULL;

                  
            }
      else
            {

                  wchar_t *destString = (wchar_t *)malloc( size * sizeof(wchar_t) );
                  memset((char *)destString ,'\0',(sizeof(wchar_t)));

                  setlocale (LC_ALL,"");
                  mbstowcs(destString, local, size);
                  PRINT(" Convert to multibyte string:\n");
   
                  int newSize = wcstombs(NULL, destString, 0 ) +1;
                  wcstombs( local, destString , newSize );
   
                  retObj->pstrErrorMsg->txtErrKey2 = local ;
                  TRACE(" ERRORKEY1 FROM DCE IS = "<<local<<"++++++");
                  free(destString);
                  destString = NULL;
                  
            }
            
                  free(local);
                  local = NULL;
                  

      }

      else
      {
            retObj->pstrErrorMsg->txtErrKey2 = (char*)p_str_ErrorMsg->txt_ErrKey1;
            TRACE(" ERRORKEY1 FROM DCE IS = "<<(char *)p_str_ErrorMsg->txt_ErrKey1<<"++++++");
      }

The basic idea is to convert UTF-8 to wide char and then to char

Please let me know your views on it

Many Thanks
Does that solve your problem ?
yet to be tested
ANother simple alternative is        p_str_ErrorMsg.txt_ErrKey1[25]='\0';
retObj->pStrErrorMsg->txtErrKey1 = (char*)p_str_ErrorMsg.txt_ErrKey1;
assigning NULL to the last character will avoid the Assertion condition Assertion failed: srcLen == 0, file ../../../../systinet-server-cpp-6.5/src/tools/STLSupport/STLSupport.cpp,
but then  it will not print or send the Junk characters/Unicode characters to the Front end
Are you sure those junk characters are unicode ?

Do you need them in the frontend ?
Those Junk characters are not required in Froint End
My question is
How will I identify if a string has unicode characters ?
Is there any way to identify whether a string has unicode or Normal ASCII characters ?
If we can find it out then it will be of a great help
Thanks

ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
There are Unicode chartacters in the Backends in Oracle so a unicode string is bound to come up from a backend .
How to differentiate betweena  unicode String and a Normal ASCII string ?
is there any check that I can apply , that way I can reduce to burdon of applying NULL to all OUT parameters
>> so a unicode string is bound to come up from a backend .

Yes, but why just that one string, and not the others ?


>> How to differentiate betweena  unicode String and a Normal ASCII string ?

As I said : depends what kind of unicode we're talking about here.


>> that way I can reduce to burdon of applying NULL to all OUT parameters

All ? I thought you only had the problem for txt_ErrKey1 ?
The problem is with txt_ErrKey1 only
to be one a safer side , it would be required to apply it to all
Excellent
Inifinty

Allocating a NULL to the last BYTE i.e p_str_ErrorMsg.txt_ErrKey1[25]='\0';
does not help , the issue comes
You mentioned about setting  the first character to the '\0'
How different it is when you set last character to NULL and the first to NULL to avoid a JUNK  
If you set the first to '\0', then the string will be seen as empty ... You'll ignore any (junk) characters that might have been in it before.
If you set the last to '\0', you simply terminate the string, but the (junk) characters are still there.
But really, as I've said a few times : you should research WHY those junk characters are there, and find a solution for that problem.