简体   繁体   English

free()导致堆栈溢出

[英]free() causing stack overflow

I am trying to develop an application with Visual Studio C++ using some communication DLLs . 我正在尝试使用一些通信DLLs使用Visual Studio C ++开发应用程序。 In one of the DLLs, I have a stack overflow exception. 在其中一个DLL中,我有一个堆栈溢出异常。

I have two functions, one receives packet, and another function which do some operations on the packets. 我有两个功能,一个接收数据包,另一个函数对数据包执行一些操作。

static EEcpError RxMessage(unsigned char SrcAddr, unsigned char SrcPort, unsigned char DestAddr, unsigned char DestPort, unsigned char* pMessage, unsigned long MessageLength)
{
    EEcpError Error = ERROR_MAX;
    TEcpChannel* Ch = NULL;
    TDevlinkMessage* RxMsg = NULL;

    // Check the packet is sent to an existing port
    if (DestPort < UC_ECP_CHANNEL_NB)
    {
        Ch = &tEcpChannel[DestPort];
        RxMsg = &Ch->tRxMsgFifo.tDevlinkMessage[Ch->tRxMsgFifo.ucWrIdx];

        // Check the packet is not empty
        if ((0UL != MessageLength)
            && (NULL != pMessage))
        {
            if (NULL == RxMsg->pucDataBuffer)
            {
                // Copy the packet
                RxMsg->SrcAddr = SrcAddr;
                RxMsg->SrcPort = SrcPort;
                RxMsg->DestAddr =DestAddr;
                RxMsg->DestPort = DestPort;
                RxMsg->ulDataBufferSize = MessageLength;
                RxMsg->pucDataBuffer = (unsigned char*)malloc(RxMsg->ulDataBufferSize);
                if (NULL != RxMsg->pucDataBuffer)
                {
                    memcpy(RxMsg->pucDataBuffer, pMessage, RxMsg->ulDataBufferSize);

                    // Prepare for next message
                    if ((UC_ECP_FIFO_DEPTH - 1) <= Ch->tRxMsgFifo.ucWrIdx)
                    {
                        Ch->tRxMsgFifo.ucWrIdx = 0U;
                    }
                    else
                    {
                        Ch->tRxMsgFifo.ucWrIdx += 1U;
                    }

                    // Synchronize the application
                    if (0 != OS_MbxPost(Ch->hEcpMbx))
                    {
                        Error = ERROR_NONE;
                    }
                    else
                    {
                        Error = ERROR_WINDOWS;
                    }
                }
                else
                {
                    Error = ERROR_WINDOWS;
                }
            }
            else
            {
                // That should never happen. In case it happens, that means the FIFO
                // is full. Either the FIFO size should be increased, or the listening thread 
                // does no more process the messages.
                // In that case, the last received message is lost (until the messages are processed, or forever...)
                Error = ERROR_FIFO_FULL;
            }
        }
        else
        {
            Error = ERROR_INVALID_PARAMETER;
        }
    }
    else
    {
        // Trash the packet, nothing else to do
        Error = ERROR_NONE;
    }

    return Error;
}

static EEcpError ProcessNextRxMsg(unsigned char Port, unsigned char* SrcAddr, unsigned char* SrcPort, unsigned char* DestAddr, unsigned char* Packet, unsigned long* PacketSize)
{
    EEcpError Error = ERROR_MAX;
    TEcpChannel* Ch = &tEcpChannel[Port];
    TDevlinkMessage* RxMsg = &Ch->tRxMsgFifo.tDevlinkMessage[Ch->tRxMsgFifo.ucRdIdx];

    if (NULL != RxMsg->pucDataBuffer)
    {
        *SrcAddr = RxMsg->ucSrcAddr;
        *SrcPort = RxMsg->ucSrcPort;
        *DestAddr = RxMsg->ucDestAddr;
        *PacketSize = RxMsg->ulDataBufferSize;
        memcpy(Packet, RxMsg->pucDataBuffer, RxMsg->ulDataBufferSize);

        // Cleanup the processed message
        free(RxMsg->pucDataBuffer);   // <= Exception stack overflow after 40 min
        RxMsg->pucDataBuffer = NULL;
        RxMsg->ulDataBufferSize = 0UL;
        RxMsg->ucSrcAddr = 0U;
        RxMsg->ucSrcPort = 0U;
        RxMsg->ucDestAddr = 0U;
        RxMsg->ucDestPort = 0U;

        // Prepare for next message
        if ((UC_ECP_FIFO_DEPTH - 1) <= Ch->tRxMsgFifo.ucRdIdx)
        {
            Ch->tRxMsgFifo.ucRdIdx = 0U;
        }
        else
        {
            Ch->tRxMsgFifo.ucRdIdx += 1U;
        }

        Error =ERROR_NONE;
    }
    else
    {
        Error = ERROR_NULL_POINTER;
    }

    return Error;
}

The problem occur after 40 min, during all this time I receive a lot of packets, and everything is going well. 问题在40分钟后发生,在这段时间内,我收到了很多数据包,并且一切进展顺利。 After 40 min, the stack overflow exception occur on the free. 40分钟后,堆栈溢出异常立即发生。 I don't know what is going wrong. 我不知道怎么了。

Can anyone help me please ? 有人可以帮我吗?

Thank you. 谢谢。

A few suggestions: 一些建议:

  1. The line 线

      memcpy(Packet, RxMsg->pucDataBuffer, RxMsg->ulDataBufferSize); 

    is slightly suspect as it occurs just before the free() call which crashes. 有点怀疑,因为它发生在free()调用崩溃之前。 How is Packet allocated and how are you making sure a buffer overflow does not occur here? 如何分配Packet ,如何确保此处不会发生缓冲区溢出?

  2. If this is an asynchronous / multi-threaded program do you have the necessary locks to prevent data from being written/read at the same time? 如果这是一个异步/多线程程序,您是否具有必要的锁以防止同时写入/读取数据?
  3. Best bet if you still need to find the issue is to run a tool like Valgrind to help diagnose and narrow down memory issues more precisely. 如果您仍然需要查找问题,最好的选择是运行类似Valgrind的工具,以帮助更准确地诊断和缩小内存问题。 As dasblinklight mentions in the comments the issue most likely originates somewhere else and merely happens to show up at the free() call. 正如dasblinklight在评论中提到的那样,问题很可能起源于其他地方,并且恰好出现在free()调用中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM