Thread: Lame null append cause buffer to crash

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    5

    Talking Lame null append cause buffer to crash

    This is modem program but it is actually a simple C question so I will post it here.

    So I have a modem. I code a buffer and everytime I input a serial string (GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS), the buffer will be appended like this:
    Code:
    $GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
    $GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
    $GPZDG,POS_GPS,DD,MM,YYYY,AA.BB,V*CS
    .
    .
    My code:

    Code:
    buffer = memGet( 2000 * sizeof(ascii) ); 
    strcat ( ( ascii * ) buffer, ( ascii * ) Data); 
    strcat ( ( ascii * ) buffer, ( ascii * )"\x00");
    But everytime I appended a fourth string, the program crashes!

    So the modem forum adviced me:
    "As I told you before, all 'C' string functions rely upon there being a NUL termination - and 'Data' does not have a NUL termination! Therefore this line of code will cause the processor to "run off the end" of your valid data - which will cause your application to crash! You need to make use of the 'Length' parameter to ensure that you don't "run off the end" of 'Data'. Note also that you must not attempt to add a NUL directly at the end of 'Data', because it is just a pointer to some buffer that was allocated by some other part of the system - you cannot assume that it left room for you to add a NUL there! If you want to add a NUL and use it as a 'C' string, you will need to use something like memcpy to copy the data to your own local buffer - and add the NUL there. Again, this is standard 'C' stuff - nothing specific to Wavecom."

    So I tried this:
    Code:
    wm_memcpy ( ( ascii * ) tempBuffer, ( ascii * ) Data, Length );
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) tempBuffer);
    Didn't work, always crash after the 4 string append, I tried this:
    Code:
    wm_memcpy ( ( ascii * ) tempBuffer, ( ascii * ) Data, Length );
    wm_strcat ( ( ascii * ) buffer, ( ascii * ) tempBuffer); 
    wm_strcat ( ( ascii * ) buffer, "\x00")
    Didn't work.



    Did I missed something? Advance thanks!

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    this:
    Code:
    wm_strcat ( ( ascii * ) buffer, "\x00")
    should probably be:

    Code:
    wm_strcat ( ( ascii * ) buffer, '\0')
    Which will look like '\x0', in a C ide watch window, but that is an end of string char in C.

    What you have with the double quotes is a string, not a single char.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, see, the thing about strcat is -- it tacks the second string onto the end of the first one. If the whole point is that the first string doesn't have an end yet, well, oops.

    The modem forum people are exactly and completely correct; you need to set a \0 character in your buffer. You do that by setting the last character of your buffer to be '\0'. Assuming you have correctly gathered the length into the variable named Length, then all you have to do is
    Code:
    buffer[Length] = '\0';

  4. #4
    Registered User
    Join Date
    Dec 2008
    Posts
    5

    Thumbs down

    Guys thanks for the advice, but still having the same error messages though the code seems totally correct…killing me T0T

    I am using a call back function triggered whenever there is a serial input:
    Code:
    bool V24DataHandler ( u16 Length, u8 * Data )
    Length = Data length, Data = serial data


    The modem uses its own ported C functions (no c++ I think), there is no normal PC C functions in the modem.

    wm_ is tagged in front of usual c function names meaning wavecom module c function:
    wm_memcpy equal to memcpy
    wm_strcat equal to strcat

    adl_memGet() is a bit like malloc(), getting RAM memory.
    Trace() is somewhat equivalent to printf(). Just for debugging purpose.


    First I tried,"
    Code:
    buffer = adl_memGet( 2000 * sizeof(ascii) );	
    tempBuffer = adl_memGet( 2000 * sizeof(ascii) );  
    
    bool V24DataHandler ( u16 Length, u8 * Data )
    {
       TRACE (( 1, "Serial data event"));    
    
        wm_memcpy ( ( ascii * ) tempBuffer, ( ascii * ) Data, Length);    
        wm_strcat ( ( ascii * ) buffer, ( ascii * ) tempBuffer); 
        bufferLength += Length;
        bufferLength += 1;
        buffer[bufferLength] = '\0';    
       
        TRACE (( 1, buffer )); 	
        TRACE (( 1, "%d", bufferLength )); 	
        return TRUE;
    }
    Then I tried, no work:
    Code:
    buffer = adl_memGet( 2000 * sizeof(ascii) );	
     	tempBuffer = adl_memGet( 2000 * sizeof(ascii) );  
    
    
    bool V24DataHandler ( u16 Length, u8 * Data )
    {
        TRACE (( 1, "Serial data event"));   
        
        wm_memcpy ( ( ascii * ) (buffer + tempLength), ( ascii * ) Data, Length);
        tempLength += Length;
        wm_memcpy ( ( ascii * ) (buffer+tempLength), ( ascii * ) "\0", 1);
       // tempLength += 1;
            
        TRACE (( 1, buffer )); 	
        TRACE (( 1, "%d", tempLength )); 	
        return TRUE;	   
    }
    I traced the number of characters in the buffer. Then I input this string
    “1234567890123456789012345678901234567890123456789 0” line by line to the buffer. The buffer seems to crash consistently every time approximately at the 280th character.

    The trace of the modem as below, you can see the progression of characters inside the buffer.
    Code:
    
    
    Trace	ATI	1	Unable to find the string of the remote trace in the file (ID = 8842)
    Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
    Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
    Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
    Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
    Trace	DEV	1	Unable to find the string of the remote trace in the file (ID = 12654)
    Trace	CUS4	1	Embedded Application : Main
    Trace	RLU	1	Unable to find the string of the remote trace in the file (ID = 528)
    Trace	CUS4	1	fcm subscribe
    Trace	CUS4	1	timer subscribe
    Trace	CUS4	1	serial event 0
    Trace	CUS4	1	serial switch to datamode 0 
    Trace	CUS4	1	serial event 2
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	12345678901234567890123456789012345678901234567890
    Trace	CUS4	1	51
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    Trace	CUS4	1	102
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    Trace	CUS4	1	153
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    Trace	CUS4	1	204
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    Trace	CUS4	1	255
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	257
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	259
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	261
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	263
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	265
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	267
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	269
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	271
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	273
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	275
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	CUS4	1	277
    Trace	CUS4	1	Serial data event
    Trace	CUS4	1	1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ...
    Trace	RTK	1	Except RTK ....161 57a040 1
    The modem do have c functions (wm_ indicating wavecom module)

    Code:
    3.12.2 Standard C function set
    The available standard APIs are defined below:
    
    ascii * wm_strcpy ( ascii * dst, ascii * src );
    ascii * wm_strncpy ( ascii * dst, ascii * src, u32 n );
    ascii * wm_strcat ( ascii * dst, ascii * src );
    ascii * wm_strncat ( ascii * dst, ascii * src, u32 n );
    u32 wm_strlen ( ascii * str );
    s32 wm_strcmp ( ascii * s1, ascii * s2 );
    s32 wm_strncmp ( ascii * s1, ascii * s2, u32 n );
    s32 wm_stricmp ( ascii * s1, ascii * s2 );
    s32 wm_strnicmp ( ascii * s1, ascii * s2, u32 n );
    ascii * wm_memset ( ascii * dst, ascii c, u32 n );
    ascii * wm_memcpy ( ascii * dst, ascii * src, u32 n );
    s32 wm_memcmp ( ascii * dst, ascii * src, u32 n );
    ascii * wm_itoa ( s32 a, ascii * szBuffer );
    s32 wm_atoi ( ascii * p );
    u8 wm_sprintf ( ascii * buffer, ascii * fmt, ... );
    
    
    
    3.12.3 String processing function set
    
    ascii wm_isascii ( ascii c );
    Returns c if it is an ascii character ( ‘a’/’A’ to ‘z’/’Z’), 0 otherwise.
    
    ascii wm_isdigit ( ascii c );
    Returns c if it is a digit character ( ‘0’ to ‘9’), 0 otherwise.
    
    ascii wm_ishexa ( ascii c );
    Returns c if it is an hexadecimal character ( ‘0’ to ‘9’, ‘a’/’A’ to ‘f’/’F’), 0
    otherwise.
    
    bool wm_isnumstring ( ascii * string );
    Returns TRUE if string is a numeric one, FALSE otherwise.
    
    bool wm_ishexastring ( ascii * string );
    Returns TRUE if string is an hexadecimal one, FALSE otherwise.
    
    bool wm_isphonestring ( ascii * string );
    Returns TRUE if string is a valid phone number (national or international
    format), FALSE otherwise.
    
    u32 wm_hexatoi ( ascii * src, u16 iLen );
    If src is an hexadecimal string, converts it to a returned u32 of the given
    length, and 0 otherwise. As an example: wm_hexatoi (“1A”, 2) returns 26,
    wm_hexatoi (“1A”, 1) returns 1
    
    u8 * wm_hexatoibuf ( u8 * dst, ascii * src );
    If src is an hexadecimal string, converts it to an u8 * buffer and returns a
    pointer on dst, and NULL otherwise. As an example, wm_hexatoibuf (dst,
    “1F06”) returns a 2 bytes buffer: 0x1F and 0x06 )
    
    ascii * wm_itohexa ( ascii * dst, u32 nb, u8 len );
    Converts nb to an hexadecimal string of the given length and returns a
    pointer on dst. For example, wm_itohexa ( dst, 0xD3, 2 ) returns “D3”,
    
    wm_itohexa ( dst, 0xD3, 4 ) returns “00D3”.
    ascii * wm_ibuftohexa ( ascii * dst, u8 * src, u16 len );
    
    Converts the u8 buffer src to an hexadecimal string of the given length and
    returns a pointer on dst. Example with the src buffer filled with 3 bytes
    (0x1A, 0x2B and 0x3C), wm_ibuftohexa (dst, src, 3) returns “1A2B3C”).
    
    u16 wm_strSwitch ( const ascii * strTest, ... );
    This function must be called with a list of strings parameters, terminated by
    NULL. strTest is compared with each of these strings (on the length of each
    string, with no matter of the case), and returns the index (starting from 1) of
    the string which matches if any, 0 otherwise.
    Hmmm it is strange, now I am wondering about the limitation about the modem even though the modem forum told otherwise....advance thanks.
    Last edited by cmoo; 12-22-2008 at 02:42 AM.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't know anything about adl_memGet. Is that what receives your data from the serial line? If so, how do you know how much data you got? Or are those malloc-type functions? And what does that error code (the line with the RTK -- I'm assuming you're CUS4, so that this isn't your error message) mean?

  6. #6
    Registered User
    Join Date
    Dec 2008
    Posts
    5

    Talking

    O sorry about just throwing original modem codes without modifying them, yeah memGet is a bit like malloc.

    Code:
    3.3.2 The adl_memGet function
    This function allocates the memory for the requested into the client
    application RAM memory.
    • Prototype
    void * adl_memGet ( u16 size )
    • Parameters
    The size of memory requested (in bytes).
    The modem uses its own ported C functions (no c++ I think), there is no normal PC C functions in the modem.

    wm_ is tagged in front of usual c function names meaning wavecom module c function:
    wm_memcpy equal to memcpy
    wm_strcat equal to strcat

    Trace() is somewhat equivalent to printf().

    The error messages means buffer overflow.


    Yeah, thanks.
    Last edited by cmoo; 12-22-2008 at 01:50 AM.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Is that the trace from the second try you posted? The second try looks better than the first, or at least less prone to mistakes. I don't see anything greatly wrong with that second attempt. Do you need to remove things from the input buffer, once you've stored/processed them in your own buffer?

  8. #8
    Registered User
    Join Date
    Dec 2008
    Posts
    5

    Thumbs up

    OOO!!!! You are probably right!!! Wavecom has been telling this all along, it was right under my nose!!! Thank you!!!

    Let do some testing and get back!

  9. #9
    Registered User
    Join Date
    Dec 2008
    Posts
    5

    Talking

    O it is the TRACE() that overflowed! Data and Buffer doesn't required any /0 at all, wavecom forum is wrong.

    Anyway problem solved, a lot of it owed to isolating that the C functions is ok thanks to your help! THank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. New string functions
    By Elysia in forum C Programming
    Replies: 11
    Last Post: 03-28-2009, 05:03 AM
  2. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  3. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  5. BST/Red and Black Tree
    By ghettoman in forum C++ Programming
    Replies: 0
    Last Post: 10-24-2001, 10:45 PM