因为内存问题,程序崩溃对于每一个c++程序员而言是很常见的问题,而段错误引起的宕机,恐怕是平时遇到的最多的情况,除了常见的指针未判空和野指针问题外,还有不少是比较头疼的情况,空指针因为定位很直接方便,这里就不说了,野指针因为它的异时异地特性,很难排查,这个以后我会详细说一下的,这里仅仅介绍一下其他也比较头疼的段错误宕机情况,这是之前自己总结的笔记,前段时间又看到了,感觉对很多人 应该是有用的,于是总结出来供大家参考。
1
/**
2 *\author peakflys
3 *\brief 堆栈崩溃问题
4 */ 5 #include <iostream>
6 using namespace std;
7
8 struct Temp
9 {
10 int a;
11 unsigned char b[4];
12 };
13
14 void fill(unsigned char *data)
15 {
16 for(int i=0;i<20;++i)
17 {
18 data[i] = i;
19 cout<<"data["<<i<<"]:\t"<<(void *)&data[i]<<endl;
20 }
21 }
22
23 int main()
24 {
25 static string names[] = {"a","b","c","d"};
26 static Temp tt;
27 cout<<"tt:\t"<<&tt<<endl;
28 for(int i=0;i<4;++i)
29 cout<<"names["<<i<<"]:\t"<<(void *)&names[i]<<endl;
30
31 cout<<"before"<<endl;
32 fill((unsigned char *)&tt);
33 cout<<"end"<<endl;
34
35 for(int i=0;i<4;++i)
36 cout<<"names["<<i<<"]:\t"<<(void *)&names[i]<<endl;
37 return 0;
38 }
运行结果:
tt: 0x601630
names[0]: 0x601640
names[1]: 0x601648
names[2]: 0x601650
names[3]: 0x601658
before
data[0]: 0x601630
data[1]: 0x601631
data[2]: 0x601632
data[3]: 0x601633
data[4]: 0x601634
data[5]: 0x601635
data[6]: 0x601636
data[7]: 0x601637
data[8]: 0x601638
data[9]: 0x601639
data[10]: 0x60163a
data[11]: 0x60163b
data[12]: 0x60163c
data[13]: 0x60163d
data[14]: 0x60163e
data[15]: 0x60163f
data[16]: 0x601640
data[17]: 0x601641
data[18]: 0x601642
data[19]: 0x601643
end
names[0]: 0x601640
names[1]: 0x601648
names[2]: 0x601650
names[3]: 0x601658
段错误 (core dumped)
core文件堆栈:
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
[New process 16428]
#0 0x0000003db00b7672 in __gnu_cxx::__exchange_and_add () from /usr/lib64/libstdc++.so.6
(gdb) bt
#0 0x0000003db00b7672 in __gnu_cxx::__exchange_and_add () from /usr/lib64/libstdc++.so.6
#1 0x0000003db009db59 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string ()
from /usr/lib64/libstdc++.so.6
#2 0x0000000000400b54 in __tcf_0 ()
#3 0x0000003d9da333a5 in exit () from /lib64/libc.so.6
#4 0x0000003d9da1d99b in __libc_start_main () from /lib64/libc.so.6
#5 0x0000000000400a79 in _start ()
评议:从上面core文件可以看出string结构被破坏,析构的时候直接挂掉了,被破坏的原因自然是周围(最大可能是之前的位置)数据写超了,写到了自己的一亩三分地来了,这种宕机的特点是比较难定位,宕机的位置一般是STL容器或者是自己定义的类结构析构的时候 出错,排查的一般方法就是找代码的周围行或者是相邻时刻执行的代码行,排查可能超出内存边界的写操作,预防的方法自然是加强临界地址的判定。
待续…… peakflys