因為內存問題,程序崩潰對于每一個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