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掉,不然后内存泄漏的。我个人也在考虑这两种方式有何不同,经过百度查阅,了解到使用栈比使用堆的读取效率要高,考虑到性能问题此处还是使用的栈。

  至此,该问题处理完毕,若有不完善的地方,还请各位大佬指正!谢谢

posted @ 2020-05-26 16:55  Come0nBaby  阅读(526)  评论(0)    收藏  举报