linux c return后段错误
记录一次工作中遇到的段错误!
问题描述:
之前项目调试一个应用模块,实现短信存满自动删除最早短信的功能,客户测试时出现了问题,导致未自动删除短信,并且UI显示也异常。
调试:
开始以为是短信问题,所以从modem抓取qxdm的log开始分析,因为之前该项目由于3gpp1和3gpp2的问题导致过类似的问题,所以首先想到的也是这个方向去排查,但是经过modem同事的log分析后,却并未发现什么异常,然后从AP测再次入手,根据客户描述每次重启之后问题就会解决,但是还是会复现,所以考虑到可能是某个进程挂掉了,重启后进程重新启动,所以显示正常,因此,在复现问题后,后台ps查看,果然,短信响应的模块服务进程挂掉了,此时后台手动重启该进程,发现服务正常,再次复现问题时,手动启动的进程就挂掉了,并且报段错误。
段错误一般处理方法就是打印log查看哪行代码报错误了,进而进行修改,但是所有log打印完后发现其中一个调用一个函数return后报了段错误。下面贴出部分代码记录一下
1 static void auto_delete_sms(sms_mode_e_type mode, sms_storage_e_type storage, int delete_count) 2 { 3 uint8_t i; 4 uint8_t list_len; 5 uint8_t vm_count = 0; 6 uint8_t vm_count_valid = 0; 7 sms_raw_data_s_type raw_data; 8 sms_tuple_s_type list[SMS_TUPLE_MAX]; 9 sms_box_e_type box; 10 11 SMS_LIST_LOCK; 12 13 if(sms_qmi_get_msg_list(mode, storage, &list[0], &list_len)){ 14 sms_user_data_s_type user_data[list_len-1]; 15 sms_delete_info_e_type delete_data[list_len-1]; 16 17 for(i=0; i<list_len; i++){ 18 if( sms_qmi_read_msg(mode, storage, list[i].msg_index, &raw_data) && 19 sms_qmi_decode_msg(mode, list[i].tag_type, FALSE, &raw_data, &user_data[i], &vm_count, &vm_count_valid) ) 20 { 21 delete_data[i].ts = sms_ts_to_secs(user_data[i].ts); 22 memcpy(&delete_data[i].list, &list[i], sizeof(sms_tuple_s_type)); 23 } 24 } 25 26 quick_sort_sms_by_time(&delete_data[0], 0, list_len-1); 27 28 for(i=0; i<delete_count; i++){ 29 if(delete_data[i].list.tag_type == SMS_TAG_UNREAD || delete_data[i].list.tag_type == SMS_TAG_READ) 30 box = SMS_BOX_INCOM; 31 else if(delete_data[i].list.tag_type == SMS_TAG_SENT) 32 box = SMS_BOX_SENT; 33 else 34 box = SMS_BOX_DRAFT; 35 36 if( !sms_delete_one_msg(box, storage, 37 mode==SMS_MODE_CDMA?delete_data[i].list.msg_index+SMS_INDEX_CDMA: delete_data[i].list.msg_index) 38 || sms_qmi_delete_msg(mode, storage, delete_data[i].list.msg_index) ) 39 { 40 //printf("\nsuccess ----------------------------------------------------------\n"); 41 SMS_LOG_HIGH("auto delete sms mode 0x%x box 0x%x index %d success", mode, box, delete_data[i].list.msg_index); 42 }else{ 43 //printf("\nfialed -------------------------------------------------------------\n"); 44 SMS_LOG_ERROR("auto delete sms mode 0x%x box 0x%x index %d failed", mode, box, delete_data[i].list.msg_index); 45 } 46 } 47 }else 48 { 49 //printf("get sms list error ---------------------------------------------------------\n"); 50 SMS_LOG_ERROR(" get sms list error", 0, 0, 0); 51 } 52 53 SMS_LIST_UNLOCK; 54 }
分析解决:
问题就出在sms_qmi_decode_msg该函数中,return后程序就会报段错误,此时考虑到段错误的产生原因还是内存越界相关,所以猜想可能是上面定义的数组长度不够越界了,然后便将user_data和delete_data数据直接给了最大值(此处最大值为使用的数据的最大值,就是只要是这个值,肯定不会越界的值),重新编译,测试,发现问题解决!
测试问题解决后就要考虑此处为何越界,发现list_len应该为当前使用的数据的长度(当时写代码可能脑袋被门夹了才-1的),若直接使用最大值的话会导致此时占用过多的内存,而且也不会使用,所以重新修改为list_len,问题解决。
此处其实也可以使用malloc进程空间分配,同时要记得free掉,不然后内存泄漏的。我个人也在考虑这两种方式有何不同,经过百度查阅,了解到使用栈比使用堆的读取效率要高,考虑到性能问题此处还是使用的栈。
至此,该问题处理完毕,若有不完善的地方,还请各位大佬指正!谢谢

浙公网安备 33010602011771号