今天在开发中对数据包的格式进行了gige header的封装,所以需要在网络接收到数据流后不再提出gige header信息了。直接进行数据包对象的构造和process流程。但是发现在内存copy的时候出现的堆被破坏的情况。
1、内存数据错乱
直接上图
//
//
void CGpMsgGigeReadRegAck::process(void *pInfo, void* pData)
{
CHECK(pInfo);
CGpNetUdpClient* pNet = (CGpNetUdpClient*)pInfo;
CHECK(pNet);
CGpDeviceManager* pDevMgr = dynamic_cast<CGpDeviceManager*>(deviceManager(pNet->getProcessId()));
CHECK(pDevMgr);
// 字节序转换
NET_SWITCH_DWORD(m_pInfo->unRegisterValue);
// 构造cmdInfo
int nAddSize = 0;
int nCmdType = DEV_MGR_CMD_ACT_NONE;
void* pActInfo = NULL;
// 成功
if (m_pInfo->header.usStatus == ACK_SUCESS)
{
// sdk内部用到的命令,额外处理
switch (m_pInfo->header.unAckId)
{
...
case COMMAND_RW_MULTI_REGISTERS_COMMAND:
{
// 填充命令和值的信息
StuMultiCommandsInfo info;
memset(&info, 0, sizeof(StuMultiCommandsInfo));
safeMemCopy(info.szDeviceCode, GP_MAX_CODE, pNet->getNetCode(), GP_MAX_CODE);
info.unStatus = ACK_STATUS_SUCESS;
info.unCmdsId = m_pInfo->header.unAckId;
// 第1~n个寄存器
int nLength = GP_MIN(m_pInfo->header.usLen, GP_MAX_COMMAND * sizeof(INT32));
/*
* 注意:此处的m_pInfo是堆上的内存空间,需要偏移的时候+,堆属性向上增长
* | |
* 长| |
* 生| |
* 上| 栈:高地址 |
* 向| |
* + | |
* ^ | |
* | | 堆:低地址 |
* | |
* p->| |
* | |
*/
memcpy(info.szValues, (void*)((char*)m_pInfo - _GIGE_GVCP_PACKET_HEADER_SIZE), nLength); //m_pInfo 是在堆中申请的空间,注意此处使用的是想低地址空间延伸!!!
info.unCount = nLength / sizeof(UINT32);
for (UINT32 index = 1; index < info.unCount; ++index)
{
NET_SWITCH_DWORD(info.szValues[index]);
}
StuCmdInfo* pCmdInfo = (StuCmdInfo*)malloc(sizeof(StuCmdInfo) + sizeof(StuMultiCommandsInfo));
CHECK(pCmdInfo);
pCmdInfo->nCmdType = DEV_MGR_CMD_ACT_READ_COMMANDS;
memcpy(pCmdInfo->pData, (void*)&info, sizeof(StuMultiCommandsInfo));
pDevMgr->pushCmdCache(pCmdInfo);
LOGMSG("CGpMsgGigeReadRegAck::process is suc ack_id=[%u] nValue=[%u]", m_pInfo->header.unAckId, m_pInfo->unRegisterValue);
}
break;
default:
{
LOGERROR("m_pInfo->header.ack_id is error. status=[%u] cmd=[%u] len=[%u] ack_id=[%u] nValue=[%u]", m_pInfo->header.usStatus, m_pInfo->header.usCmd, m_pInfo->header.usLen, m_pInfo->header.unAckId, m_pInfo->unRegisterValue);
return;
}
break;
}
}
// push cmd devMgr
if (nAddSize > 0 && nCmdType > DEV_MGR_CMD_ACT_NONE && pActInfo)
{
StuCmdInfo* pCmdInfo = (StuCmdInfo*)malloc(sizeof(StuCmdInfo) + nAddSize);
CHECK(pCmdInfo);
pCmdInfo->nCmdType = nCmdType;
memcpy(pCmdInfo->pData, (void*)pActInfo, nAddSize);
pDevMgr->pushCmdCache(pCmdInfo);
}
}
查看m_pInfo信息:
查看szbuff中内容
(void*)((char*)m_pInfo - 8)地址内容:
当时没有注意m_pInfo是堆上的空间(把这个事情给忘记了 !!),一运行发现内存结果不对。
2、堆信息被破坏导致内存崩溃
因为内存copy越界导致堆栈信息被破坏,在函数返回值,栈SP内容已经被破坏,导致RET失败。