LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

strncmp error

I am receiving intermittent GPF errors using the function strncmp in a timer.  I am using ViWrite & ViRead to communicate with a serial device via RS232.  And I use this function to see that I am getting what I expect back from the device using this function.  See my snippet of code:

char *query_request[NUMBER_OF_SUPPLIES] = {"0DFM00QUE", "0DFM01QUE", "0DFM02QUE", "0DFM03QUE"};

viGetAttribute (handle_serial[t], VI_ATTR_ASRL_AVAIL_NUM, &t_bytes_ready);

        if  (t_bytes_ready == 48) //(TRUE)
                viRead (handle_serial[t], t_serial_buffer, t_bytes_ready, &t_bytes_transferred);
                temp_compare_buffer[0]=t_serial_buffer[0];//this is a
                temp_compare_buffer[1]=t_serial_buffer[1];//workaround
                temp_compare_buffer[2]=t_serial_buffer[2];//putting buffer in
                temp_compare_buffer[3]=t_serial_buffer[3];//strncmp brings
                temp_compare_buffer[4]=t_serial_buffer[4];//gpf faults.
                temp_compare_buffer[5]=t_serial_buffer[5];
                temp_compare_buffer[6]=t_serial_buffer[6];
                temp_compare_buffer[7]=t_serial_buffer[7];
                temp_compare_buffer[8]=t_serial_buffer[8];
                temp_compare_buffer[9]=0;
            //if(temp_compare_buffer==query_request[t])    
              if (strncmp (temp_compare_buffer, query_request[t], 9)==0)    
                {//then i do other stuff with the other buffer characters...

As you can see I used to just compare the t_serial_buffer to the query request but I thought that might be causing the problem if there was a NULL character in there or something.  But now I copying to a intermediate string (temp_compare_buffer) to avoid that potential problem.  Am I not doing something else to protect my self from unknown things happening on the serial port?  What else could this line complain about.  In CVI 8.1 in " no-run time checking" for other reasons but for my purposes I can't turn off the level of  debugging. The GPF error always highlights the if(strncmp( ... line. Any help/suggestions would be appreciated.  Thanks
               
0 Kudos
Message 1 of 17
(4,155 Views)
The most likely reason that I can think of for your function call to generate for a GPF would be using a t value of less than zero or greater than three.  This could easily cause the second pointer to be invalid.
0 Kudos
Message 2 of 17
(4,137 Views)
Are you sure that t_serial_buffer can hold t_bytes_ready bytes?  How are you declaring/allocating t_serial_buffer and temp_compare_buffer?  If you are writing past the end of your t_serial_buffer, you may be overwriting other pointers on the stack or in the data section, so that the next time you use those variables, you get a GPF.  Try adding some code that checks the number of the available bytes and only transfers as much as will fit in the buffer.  This may clear up your GPF.

As a side note, you cannot check that two strings are equal by using the '==' operator (as in "if(temp_compare_buffer==query_request[t])").  This will just determine if the two strings reside in the same memory address, which they never will.  As you found, you have to use strcmp or strncmp.

Mert A.
National Instruments
0 Kudos
Message 3 of 17
(4,117 Views)

Thanks for the responses.

Dave, Whenever it has crashed i have checked the t value and it is within range.  So I dont think that is the problem. 

Mert,  Here is how I declare the buffers,  I should have included it the first time:

unsigned char t_serial_buffer [50000];
char temp_compare_buffer [100];

AS you can see I am coding scared-  I have increased their values in order to avoid the problems i am still having.  I dont have to do a malloc or anything for these i dont think right?  Your suggestion of only transferring the exact number of bytes that I want, is what i thought i was doing with the temp_compare_buffer. I used to have the code say: 

if(t_serial_buffer==query_request[t])  

Also i think i was avoiding your other suggestion by doing the ViRead inside of the "if (t_bytes_ready == 48)"  statement. 

Thanks for the responses.

0 Kudos
Message 4 of 17
(4,111 Views)
Well, it looks like your temp_compare_buffer and t_serial_buffer should be fine.  You probably don't need the workaround (i.e. transferring to temp_compare_buffer).  It is likely query_request or the string at query_request[i] that is trashed, though from the code you posted, it's not clear where it might be happening.  When you GPF into the debugger, try to view the value of query_request[i] to see if it is still "0DFM0xQUE", as you would expect. If something's up, look for other places in your program where a function might be writing past the end of an array.  If you declare a variable immediately before the query_request declaration, take a look at where that's being written to, in case it's writing over the query_request pointer.

Mert A.
National Instruments
0 Kudos
Message 5 of 17
(4,099 Views)

Ok, you may have just not shown your exact code block but from what you wrote above you have an issue with strncmp() executing before you have filled the buffer.

if  (t_bytes_ready == 48) //(TRUE)
                viRead (handle_serial[t], t_serial_buffer, t_bytes_ready, &t_bytes_transferred);
Only the section above is part of the (t_bytes==48) if statement.  The rest of this will then execute even if the call to viRead has not happened yet:

                temp_compare_buffer[0]=t_serial_buffer[0];//this is a
                temp_compare_buffer[1]=t_serial_buffer[1];//workaround
                temp_compare_buffer[2]=t_serial_buffer[2];//putting buffer in
                temp_compare_buffer[3]=t_serial_buffer[3];//strncmp brings
                temp_compare_buffer[4]=t_serial_buffer[4];//gpf faults.
                temp_compare_buffer[5]=t_serial_buffer[5];
                temp_compare_buffer[6]=t_serial_buffer[6];
                temp_compare_buffer[7]=t_serial_buffer[7];
                temp_compare_buffer[8]=t_serial_buffer[8];
                temp_compare_buffer[9]=0;
            //if(temp_compare_buffer==query_request[t])    
              if (strncmp (temp_compare_buffer, query_request[t], 9)==0)    
                {//then i do other stuff with the other buffer characters...

When you get to strncmp() you will be executing on an unintialized array which could give you unexpected results.

Message 6 of 17
(4,098 Views)
Good catch.  I overlooked that completely. 😛
0 Kudos
Message 7 of 17
(4,095 Views)
The code snippet is actually how i have written it.  All the following code is written within the
if  (t_bytes_ready == 48) //(TRUE)
 
line i just forgot to put a '{'.  Therefore the array has to be initialized becuase i do it right before.  The GPF error is very intermittent; it happens not very often.

 
0 Kudos
Message 8 of 17
(4,094 Views)
So in your compiled code that GPFs, do you have the entire thing (viRead, buffer copy, strncmp, etc) enclosed in {  }, or not?  I'm not quite certain from your response.  Still having problems, or all fixed now?

Mert A.
National Instruments
0 Kudos
Message 9 of 17
(4,085 Views)

Sorry for being unclear.  All of the code is within the { }.  Here is a bigger sample of my code:

  

viGetAttribute (handle_serial[t], VI_ATTR_ASRL_AVAIL_NUM, &t_bytes_ready);
  if (t_bytes_ready > 48)  {
       MessagePopup ("Timer Error Message", "over 50 bytes/Will flush");
       viFlush (handle_serial[t], VI_READ_BUF_DISCARD);
  }
  if  (t_bytes_ready == 48) //(TRUE)
      {                  
      Assert(t_bytes_ready < 50);
      if (t_bytes_ready =! t_bytes_transferred)
                  MessagePopup("warning message", "ready is not same as transferred");  
      temp_compare_buffer[0]=t_serial_buffer[0];//this is a
      temp_compare_buffer[1]=t_serial_buffer[1];//workaround
      temp_compare_buffer[2]=t_serial_buffer[2];//putting buffer in
      temp_compare_buffer[3]=t_serial_buffer[3];//strncmp brings
      temp_compare_buffer[4]=t_serial_buffer[4];//gpf faults.
      temp_compare_buffer[5]=t_serial_buffer[5];
      temp_compare_buffer[6]=t_serial_buffer[6];
      temp_compare_buffer[7]=t_serial_buffer[7];
      temp_compare_buffer[8]=t_serial_buffer[8];
      temp_compare_buffer[9]=0;
      //if(temp_compare_buffer==query_request[t])  
     if (strncmp (temp_compare_buffer, query_request[t], 9)==0)    
         {

     //then do stuff with t_serial_buffer bytes 9 through 48..

}//end strncmp

} //end  if  (t_bytes_ready == 48)

 

0 Kudos
Message 10 of 17
(4,077 Views)