问题描述
自己编写的MQTT报文解析程序运行过程中,运行几分钟后,进程报
Error in ‘./test_lora': malloc(): memory corruption (fast): 0x0000007fa4000a90 Aborted
偶尔也会有
Error in ’./test_lora': free(): invalid next size (fast): 0x0000007f74000ab0 Aborted
然后异常退出。刚开始以为malloc后内存没释放导致,认真走查了代码,加打印,没有发现此问题。
在网上搜了下资料
https://www.jianshu.com/p/a849ed11be68
应该是这些问题中的一种,所以围绕程序的malloc加打印进行调试。
问题代码
//主应用程序
#include <string.h>
#include <unistd.h>
#include "powerdevice.h"
void SensorDataCallBack(const char* devicename, SPM_REQ_DATA* packet)
{
int i = 0;
SDATA_NODE *ptNode = NULL;
printf("device=%s\n",devicename);
printf("Rcv Sensor Data:ID=%02X%02X%02X%02X%02X%02X\n",packet->sensorId[0],packet->sensorId[1],
packet->sensorId[2],packet->sensorId[3],packet->sensorId[4],packet->sensorId[5]);
printf("Param Cnt=%d,Pkt Type=%d\n",packet->dataLength,packet->packetType);
for(i = 0;i < packet->dataLength;i++)
{
ptNode = &(packet->dataList[i]);
//printf("index=%d Param ID=%d,Param Len=%d,Param Type=%d\n",i,ptNode->dataId,ptNode->dataLength,ptNode->dataType);
switch(ptNode->dataType)
{
case UNSIGNED_INT_8:
printf("Param ID=%d,Param Value=%d\n",ptNode->dataId,ptNode->dataValue.uint8Value);
break;
case UNSIGNED_INT_16:
printf("Param ID=%d,Param Value=%d\n",ptNode->dataId,ptNode->dataValue.uint16Value);
break;
case UNSIGNED_INT_24:
case UNSIGNED_INT_32:
printf("Param ID=%d,Param Value=%d\n",ptNode->dataId,ptNode->dataValue.uint32Value);
break;
case FLOAT_32:
printf("Param ID=%d,Param Value=%f\n",ptNode->dataId,ptNode->dataValue.floatValue);
break;
default:
break;
}
}
printf("sensor data call back finish\n");
}
int main()
{
SOPEN_PARAM tOpenParam;
SDEVICE *ptDevice = NULL;
memset(&tOpenParam, 0, sizeof(SOPEN_PARAM));
tOpenParam.deviceName = g_szBroker;
tOpenParam.timeout = 15;
ptDevice = openDevice(tOpenParam, SensorDataCallBack);
if(NULL == ptDevice)
{
printf("open device failed\n");
return -1;
}
while(1)
{
sleep(30);
}
return 0;
}
//openDevice接口所在库部分代码(增加过调试打印)
SDEVICE *openDevice(SOPEN_PARAM openParam,SensorDataCB callBack)
{
memset(&g_tDeviceMgr,0,sizeof(T_DeviceMgr));
g_tDeviceMgr.ptCallBack = callBack;
g_tDeviceMgr.iTimeOut = openParam.timeout;
if(!ESP_QueueMgrInit(&g_tDeviceMgr.tProcQueueMgr,ESP_QUEUE_MAX_NUM))
{
printf("module init send queue failed.\n");
return false;
}
if(!espMqttClientInit(openParam.deviceName))
{
printf("MQTT Client Init Failed.\n");
return false;
}
if(!ESP_ThreadCreate(&g_tDeviceMgr.tProcThreadID,0xf0000,espDeviceMsgProcThread,NULL))
{
printf("Device Msg Proc Thread create failed.\n");
return false;
}
sem_init(&(g_tDeviceMgr.tCtrlReqWaitSem),0,0);
printf("open device success.\n");
return &g_tDevice;
}
static void *espDeviceMsgProcThread(void * arg)
{
//从接收队列里取数据串口发送给lP模组
T_QueueMsg tQueueMsg;
bool bRet = false;
T_QueueMgr *ptQueueMgr = &(g_tDeviceMgr.tProcQueueMgr);
printf("device Msg Proc Thread Start.\n");
while(1)
{
sem_wait(&ptQueueMgr->tSem);
if(g_tDeviceMgr.bExitFlag)
{
pthread_exit(NULL);
}
bRet = ESP_QueueMsgEx(ptQueueMgr,&tQueueMsg);
if(!bRet)
{
continue;
}
if(tQueueMsg.bMsgType == MSG_TYPE_MQTT_RCV)
{
espDeviceMsgRcvProc(tQueueMsg.szData);
}
else if(tQueueMsg.bMsgType == MSG_TYPE_MQTT_SEND)
{
espDeviceMsgSendProc(tQueueMsg.szData,tQueueMsg.iDataLen);
}
if(NULL != tQueueMsg.szData)
{
free(tQueueMsg.szData);
tQueueMsg.szData = NULL;
}
}
printf("device Msg Proc Thread exit.\n");
return NULL;
}
static bool espDeviceMsgRcvProc(char *szData)
{
if( NULL == szData )
{
printf("Input buffer is invaild.\n");
return false;
}
cJSON *ptRoot = NULL;
cJSON *ptNode = NULL;
UINT32 iDataLen = 0;
UINT8 *abData = NULL;
//UINT8 abData[256] = {0};
// 1解析json字符串
ptRoot = cJSON_Parse(szData);
if(NULL == ptRoot)
{
printf("can't trans json obj from buffer\n");
return false;
}
do
{
ptNode = cJSON_GetObjectItem(ptRoot,"length");
if((NULL == ptNode)||(0 == ptNode->valueint))
{
printf("Can't get data length from json.\n");
break;
}
iDataLen = ptNode->valueint;
ptNode = cJSON_GetObjectItem(ptRoot,"rawdata");
if((NULL == ptNode)||(NULL == ptNode->valuestring))
{
printf("Can't get raw data from json.\n");
break;
}
printf("--1.iDataLen:%lld\n", iDataLen);
abData = malloc(iDataLen);
printf("--1.25.\n");
if(NULL == abData)
{
printf("malloc error.\n");
break;
}
printf("--1.5.\n");
memset(abData, 0, iDataLen);
printf("--2.\n");
ESP_Base64Decode(ptNode->valuestring, abData);
printf("--2.1.\n");
// 3 解析报文
espLoraDataDecode(abData, iDataLen);
printf("--2.25.\n");
free(abData);
printf("--2.5.\n");
}while(0);
cJSON_Delete(ptRoot);
return true;
}
bool ESP_Base64Decode(const char *szBase64, UINT8 *abData)
{
int i = 0;
int j = 0;
int k = 0;
char temp[4] = "";
int iStrLen = strlen(szBase64);
for (i = 0; i < iStrLen; i += 4)
{
for (j = 0; j < 64 ; j++)
{
if (*(szBase64 + i) == base64char[j])
{
temp[0] = j;
}
}
for (j = 0; j < 64 ; j++)
{
if (*(szBase64 + i + 1) == base64char[j])
{
temp[1] = j;
}
}
for (j = 0; j < 64 ; j++)
{
if (*(szBase64 + i + 2) == base64char[j])
{
temp[2] = j;
}
}
for (j = 0; j < 64 ; j++)
{
if (*(szBase64 + i + 3) == base64char[j])
{
temp[3] = j;
}
}
*(abData + k++) = ((temp[0] << 2) & 0xFC) | ((temp[1]>>4) & 0x03);
//printf("k=%d\n", k);
if ( *(abData + i + 2) == '=' )
{
break;
}
*(abData + k++) = ((temp[1] << 4) & 0xF0) | ((temp[2]>>2) & 0x0F);
//printf("k=%d\n", k);
if ( *(abData + i + 3) == '=' )
{
break;
}
*(abData + k++) = ((temp[2] << 6) & 0xF0) | (temp[3] & 0x3F);
//printf("k=%d\n", k);
}
return true;
}
linux上使用 命令aarch64-linux-gnu-gcc -Wall test.c -o test_lora -DLORADATA_V1 ./libloradec.a -lpthread -lm 进行编译后,生成目标文件 test_lora。”./“运行后,打印如下:
root@tf:/home# ./test_lora
–9.
–10. Mqtt Client Connection success. mqtt init success. open device success. device Msg Proc Thread Start. mqtt connect Thread Start.
Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=77
message->payload:{
“cmdType”: 45062,
“length”: 17,
“rawdata”: “o08IIAehIDFgAQIZYAECkPo=” }
–11.
–12.
–1.iDataLen:17
–1.25.
–1.5.
–2.
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=6156,datalenflag=1 datalen=1 idex=1 param id=6150,datalenflag=1
datalen=1 device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=A34F082007A1
Param Cnt=2,Pkt Type=0 Param ID=6156,Param Value=2 Param ID=6150,Param
Value=2 sensor data call back finish Call Back Finished Rcv Sensor
Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=109 message->payload:{
“cmdType”: 45062,
“length”: 40,
“rawdata”: “C8EIIbGoUCAASF3VQSUAAj4ADADuRWlAYeoEosoAAGXqBAANJSCtCg==” }
–11.
–12.
–1.iDataLen:40
–1.25.
–1.5.
–2.
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=8,datalenflag=0 datalen=4 idex=1 param id=9,datalenflag=1 datalen=2 idex=2 param
id=3,datalenflag=0 datalen=4 idex=3 param id=15000,datalenflag=1
datalen=4 idex=4 param id=15001,datalenflag=1 datalen=4
device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=0BC10821B1A8 Param
Cnt=5,Pkt Type=0 Param ID=8,Param Value=26.670547 Param ID=9,Param
Value=62 Param ID=3,Param Value=3.644893 Param ID=15000,Param
Value=51874 Param ID=15001,Param Value=539299072 sensor data call back
finish Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=97 message->payload:{
“cmdType”: 45062,
“length”: 31,
“rawdata”: “qG4IwAAuQBgg7J7VQR0gAjwAeAAAAEBBdQACZADGFw==” }
–11.
–12.
–1.iDataLen:31
–1.25.
–1.5.
–2.
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=2054,datalenflag=0 datalen=4 idex=1 param id=2055,datalenflag=1
datalen=2 idex=2 param id=30,datalenflag=0 datalen=4 idex=3 param
id=29,datalenflag=1 datalen=2 device=tcp://127.0.0.1:1883 Rcv Sensor
Data:ID=A86E08C0002E Param Cnt=4,Pkt Type=0 Param ID=2054,Param
Value=26.702599 Param ID=2055,Param Value=60 Param ID=30,Param
Value=12.000000 Param ID=29,Param Value=100 sensor data call back
finish Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=77 message->payload:{
“cmdType”: 45062,
“length”: 17,
“rawdata”: “o08IIAehIDFgAQIZYAECkPo=” }
–11.
–12.
–1.iDataLen:17
*** Error in `./test_lora’: malloc(): memory corruption (fast): 0x0000007fa4000a90 *** Aborted
分析过程
根据打印发现进程每次异常退出都发生在espDeviceMsgRcvProc接口中为变量*UINT8 abData使用malloc申请内存时。修改局部变量变量空间申请方式为
UINT8 abData[256] = {0};
删除对变量的malloc和free。
//abData = malloc(iDataLen);
//free(abData);
再次编译运行目标文件,发现运行正常。
问题初步解决,但没有查到根因,继续分析,改回对变量abData 进行malloc方式申请内存空间。
检查malloc申请未发现问题,持续纠结,继续加打印。然后怀疑到可能是数组越界的问题导致。
检查变量abData的调用位置。
在base64解码的接口ESP_Base64Decode中增加打印,编译运行。
root@tf:/home# ./test_lora
–9.
–10. Mqtt Client Connection success. mqtt init success. open device success. mqtt connect Thread Start. device Msg Proc Thread Start.
Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=77
message->payload:{
“cmdType”: 45062,
“length”: 17,
“rawdata”: “o08IIAehIDFgAQIZYAECkPo=” }
–11.
–12.
–1.iDataLen:17
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=6156,datalenflag=1 datalen=1 idex=1 param id=6150,datalenflag=1
datalen=1 device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=A34F082007A1
Param Cnt=2,Pkt Type=0 Param ID=6156,Param Value=2 Param ID=6150,Param
Value=2 sensor data call back finish Call Back Finished Rcv Sensor
Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=89 message->payload:{
“cmdType”: 45062,
“length”: 25,
“rawdata”: “o08IwCOtMA1gAgIAeAAfhlhAdQACPwBVKg==” }
–11.
–12.
–1.iDataLen:25
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18 k=19 k=20 k=21 k=22 k=23 k=24 k=25
k=26 k=27
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=6147,datalenflag=1 datalen=2 idex=1 param id=30,datalenflag=0
datalen=4 idex=2 param id=29,datalenflag=1 datalen=2
device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=A34F08C023AD Param
Cnt=3,Pkt Type=0 Param ID=6147,Param Value=2 Param ID=30,Param
Value=3.383186 Param ID=29,Param Value=63 sensor data call back finish
Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=85 message->payload:{
“cmdType”: 45062,
“length”: 24,
“rawdata”: “qG4IxQBfMClgAQJ4AAAAQEF1AAJkALJI” }
–11.
–12.
–1.iDataLen:24
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18 k=19 k=20 k=21 k=22 k=23 k=24
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=6154,datalenflag=1 datalen=1 idex=1 param id=30,datalenflag=0
datalen=4 idex=2 param id=29,datalenflag=1 datalen=2
device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=A86E08C5005F Param
Cnt=3,Pkt Type=0 Param ID=6154,Param Value=2 Param ID=30,Param
Value=12.000000 Param ID=29,Param Value=100 sensor data call back
finish Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=77 message->payload:{
“cmdType”: 45062,
“length”: 17,
“rawdata”: “o08IIAehIDFgAQIZYAECkPo=” }
–11.
–12.
–1.iDataLen:17
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=6156,datalenflag=1 datalen=1 idex=1 param id=6150,datalenflag=1
datalen=1 device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=A34F082007A1
Param Cnt=2,Pkt Type=0 Param ID=6156,Param Value=2 Param ID=6150,Param
Value=2 sensor data call back finish Call Back Finished Rcv Sensor
Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=109 message->payload:{
“cmdType”: 45062,
“length”: 40,
“rawdata”: “C8EIIbGoUCAAdO/UQSUAAj4ADADuRWlAYeoEp8oAAGXqBAANJSAP7g==” }
–11.
–12.
–1.iDataLen:40
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18 k=19 k=20 k=21 k=22 k=23 k=24 k=25 k=26 k=27 k=28 k=29
k=30 k=31 k=32 k=33 k=34 k=35 k=36 k=37 k=38 k=39 k=40 k=41 k=42
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=8,datalenflag=0 datalen=4 idex=1 param id=9,datalenflag=1 datalen=2 idex=2 param
id=3,datalenflag=0 datalen=4 idex=3 param id=15000,datalenflag=1
datalen=4 idex=4 param id=15001,datalenflag=1 datalen=4
device=tcp://127.0.0.1:1883 Rcv Sensor Data:ID=0BC10821B1A8 Param
Cnt=5,Pkt Type=0 Param ID=8,Param Value=26.616920 Param ID=9,Param
Value=62 Param ID=3,Param Value=3.644893 Param ID=15000,Param
Value=51879 Param ID=15001,Param Value=539299072 sensor data call back
finish Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=97 message->payload:{
“cmdType”: 45062,
“length”: 31,
“rawdata”: “qG4IwAAuQBggnGTWQR0gAjsAeAAAAEBBdQACZAAyTw==” }
–11.
–12.
–1.iDataLen:31
–1.25.
–1.5.
–2. k=1 k=2 k=3 k=4 k=5 k=6 k=7 k=8 k=9 k=10 k=11 k=12 k=13 k=14 k=15 k=16 k=17 k=18 k=19 k=20 k=21 k=22 k=23 k=24 k=25 k=26 k=27 k=28 k=29
k=30 k=31 k=32 k=33
–2.1. Rcv Sensor Monitor Data Report idex=0 param id=2054,datalenflag=0 datalen=4 idex=1 param id=2055,datalenflag=1
datalen=2 idex=2 param id=30,datalenflag=0 datalen=4 idex=3 param
id=29,datalenflag=1 datalen=2 device=tcp://127.0.0.1:1883 Rcv Sensor
Data:ID=A86E08C0002E Param Cnt=4,Pkt Type=0 Param ID=2054,Param
Value=26.799126 Param ID=2055,Param Value=59 Param ID=30,Param
Value=12.000000 Param ID=29,Param Value=100 sensor data call back
finish Call Back Finished Rcv Sensor Data Decode finished
–2.25.
–2.5. Mqtt(loraMQTT) Message arrived:topic: /v1/lcm/data/upload.payloadle=77 message->payload:{
“cmdType”: 45062,
“length”: 17,
“rawdata”: “o08IIAehIDFgAQIZYAECkPo=” }
–11.
–12.
–1.iDataLen:17
*** Error in `./test_lora’: malloc(): memory corruption (fast): 0x0000007f8c000a90 *** Aborted
终于发现接口中对abData 进行了越界操作,修改问题代码(块注释内代码未问题代码)
*(abData + k++) = ((temp[0] << 2) & 0xFC) | ((temp[1]>>4) & 0x03);
printf("k=%d\n", k);
/*if ( *(abData + i + 2) == '=' )*/
if ( *(szBase64 + i + 2) == '=' )
{
break;
}
*(abData + k++) = ((temp[1] << 4) & 0xF0) | ((temp[2]>>2) & 0x0F);
printf("k=%d\n", k);
/*if ( *(abData + i + 3) == '=' )*/
if ( *(szBase64 + i + 3) == '=' )
{
break;
}
*(abData + k++) = ((temp[2] << 6) & 0xF0) | (temp[3] & 0x3F);
printf("k=%d\n", k);
编译运行,问题解决。
附录
库文件以及主程序源码
https://download.csdn.net/download/qqq1112345/85722646