因?yàn)閮?nèi)存問題,程序崩潰對(duì)于每一個(gè)c++程序員而言是很常見的問題,而段錯(cuò)誤引起的宕機(jī),恐怕是平時(shí)遇到的最多的情況,除了常見的指針未判空和野指針問題外,還有不少是比較頭疼的情況,空指針因?yàn)槎ㄎ缓苤苯臃奖悖@里就不說了,野指針因?yàn)樗漠悤r(shí)異地特性,很難排查,這個(gè)以后我會(huì)詳細(xì)說一下的,這里僅僅介紹一下其他也比較頭疼的段錯(cuò)誤宕機(jī)情況,這是之前自己總結(jié)的筆記,前段時(shí)間又看到了,感覺對(duì)很多人 應(yīng)該是有用的,于是總結(jié)出來供大家參考。
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 }
運(yùn)行結(jié)果:
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
段錯(cuò)誤 (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 ()
評(píng)議:從上面core文件可以看出string結(jié)構(gòu)被破壞,析構(gòu)的時(shí)候直接掛掉了,被破壞的原因自然是周圍(最大可能是之前的位置)數(shù)據(jù)寫超了,寫到了自己的一畝三分地來了,這種宕機(jī)的特點(diǎn)是比較難定位,宕機(jī)的位置一般是STL容器或者是自己定義的類結(jié)構(gòu)析構(gòu)的時(shí)候 出錯(cuò),排查的一般方法就是找代碼的周圍行或者是相鄰時(shí)刻執(zhí)行的代碼行,排查可能超出內(nèi)存邊界的寫操作,預(yù)防的方法自然是加強(qiáng)臨界地址的判定。
待續(xù)…… peakflys