Error while trying to update array element

77 views Asked by At

I am working on an embedded platform which does not have debugging features. So it is hard to say what is the error source.

I have defined in header file:

typedef struct cm_packet {
  CM_Header Header; //header of packet 3 bytes
  uint8_t *Data; //packet data 64 bytes
  CM_Footer Footer; //footer of  packet 3 bytes
} CM_Packet;

typedef struct cm_inittypedef{
  uint8_t               DeviceId;
  CM_Packet             Packet;        
} CM_InitTypeDef;

extern CM_InitTypeDef cmHandler;
void CM_Init(CM_InitTypeDef *handler);    
CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier
                              , uint8_t *data, uint8_t length);

And somewhere in implementation I have:

uint8_t bufferIndex = 0;

void CM_Init(CM_InitTypeDef *cm_initer) { //init a handler
  cmHandler.DeviceId = cm_initer->DeviceId;  

  CM_Packet cmPacket;  
  cmPacket.Header.DeviceId = cm_initer->DeviceId;
  cmPacket.Header.PacketStart = CM_START;
  cmPacket.Footer.PacketEnd = CM_END;
  //initialize data array
  uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00}; 
  cmPacket.Data = emptyBuffer;

  cm_initer->Packet = cmPacket;
}

CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier
                              , uint8_t *data, uint8_t length){    
    //some check to see if new data does not make Data overflow             

    uint8_t i;

    /*** ERROR HAPPENS HERE!!!! ***/
    handler->Packet.Data[bufferIndex++] = identifier;

    //now add the data itself
    for(i = 0; i < length; i++) {
     handler->Packet.Data[bufferIndex++] = data[i];
    }

    //reset indexer
    if(bufferIndex > 64) {
       PacketReady(); //mark packet as ready
       bufferIndex = 0 
     };

    //return result
}

The idea is to update the Packet.Data from some other source codes which have access to the handler. For example some other sources can call that Append function to change Packet.Data. But as you see in the code, I have commented the place which causes the micro-controller to go in hard fault mode. I am not sure what is happening here. All I know is exactly at that line micro goes into hard fault mode and never recovers!

This might be a race condition but before anything else I want to know I have written correct c !!! code then I try to rule out other problems.

2

There are 2 answers

1
barak manos On BEST ANSWER

In function CM_Init, you are setting cmPacket.Data to point to a local array:

uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00};
cmPacket.Data = emptyBuffer;

Accessing this memory address outside the scope of the function yields undefined behavior.

2
Jouan On

As @barak manos mentioned, the buffer supplied to Data is allocated on the stack.

When you get to CM_AppendData, you are writing over memory that is no longer dedicated to the buffer.

You may want to use malloc so that the buffer is allocated on the heap instead of on the stack. Just remember to call free so that you are not leaking memory.

If you can't use dynamic allocation, it's possible to dedicate some scratch memory for all the Data uses. It just needs to be static.

Hope that helps :)