任何人寫程序都會出錯,正如《C++編程規範》所說,真正可怕的錯誤不是編譯時的錯誤,而是運行時錯誤。linux
有的程序能夠經過編譯, 但在運行時會出現Segment fault(段錯誤)ios
這一般都是指針錯誤(通常就是空指針)引發的,或者訪問了不能訪問的內存(數組越界,系統保護)編程
咱們不可能用GDB一句一句的去找,真正的英雄都善於使用手中的武器。這就是core fileubuntu
所謂core,就是當程序down掉的時候,操做系統把程序的內存內容dump下來,這個動做就是core dump,動做的結果就是core文件數組
產生:bash
1.程序掛了,操做系統產生app
2.經過gcore $pid命令直接導出相應進程的core文件,此命令運行後, 會恢復程序的執行, 不影響程序的運行dom
3.經過另外一個進程發送SIGABRT信號給當前進程, 雖然也能產生core文件,可是程序隨着一塊兒終止掉學習
1.終端級別測試
怎麼樣才能讓程序down掉的時候,自動core dump呢?能夠經過 ulimit查看和設置
#查看core文件的信息 ulimit -a
ju@musicoder:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited ju@musicoder:~$
能夠看到,core file size 是0,那就是說程序down了的時候,不會生成core文件,這個功能是關閉的。
可使用 ulimit -c unlimited 設置容許當前生成沒有大小限制的core file
ju@musicoder:~$ ulimit -c unlimited
只能對當前終端有效,退出就無效。
這樣作,是由於只想臨時生成core file,不須要每次crash時都自動生成。
2.用戶級別
用戶在本身的~/.bash_profile中加入
ulimit -S -c unlimited > /dev/null 2>&1
這樣設置後容許當前用戶生成沒有大小限制的core dump文件
3.系統級別
(1)對全部用戶
修改/etc/profile,加入或者修改
ulimit -S -c unlimited > /dev/null 2>&1
這樣設置後容許全部用戶生成沒有大小限制的core dump文件。
優勢:不須要重起系統
缺點:沒法控制只讓某些用戶生成core dump文件
(2)上面這種方法也是有缺點的,那就是Tom用會產生core,Jerry也會產生,實行上咱們只要Tom產生
修改/etc/security/limits.conf 可作到
ps.不少系統上限均可以經過修改這個文件改變,如最大子進程個數,最大打開文件數等等。這個文件開頭有詳細的註釋,對如何修改這個文件作了說明。
ju@musicoder:/etc/security$ cat limits.conf # /etc/security/limits.conf #<domain> <type> <item> <value> #* soft core 0 #root hard core 100000 # End of file ju@musicoder:/etc/security$
咱們看到了 * soft core 0 這一行,他表示對全部用戶生產dump,但默認是註釋了的
若是隻想對某些用戶或用戶組打開core dump,能夠加入
Tom soft core 0
@TomGroup soft core 0
#0是大小
優勢:能夠針對特定用戶或特定組打開core dump文件
缺點:須要重起系統
1.pid信息
在/proc/sys/kernel/core_uses_pid中配置是否core帶pid的擴展
文件內容爲1,表示添加pid做爲擴展名,生成的core文件格式爲core.xxxxx;(xxxxx如12345爲pid)
爲0則表示生成的core文件統一命名爲core
ju@musicoder:~$ cat /proc/sys/kernel/core_uses_pid 0
可經過如下命令修改此文件(root)
root@musicoder:/home/ju# echo "1" > /proc/sys/kernel/core_uses_pid
2.保存位置和文件名格式
/proc/sys/kernel/core_pattern 中配置生成文件的文件名和保存位置
ju@musicoder:~$ cat /proc/sys/kernel/core_pattern core #可經過如下命令修改此文件: root@musicoder:/home/ju# echo "/tmp/core-%e-%p-%t" > /proc/sys/kernel/core_pattern #固然也能夠是 sysctl -w kernel.core_pattern=/tmp/core-%e-%p-%t
能夠將core文件統一輩子成到/tmp目錄下,產生的文件名爲 core-命令名-pid-時間戳
如下是參數列表:
%p - insert pid into filename 添加pid
%u - insert current uid into filename 添加當前uid
%g - insert current gid into filename 添加當前gid
%s - insert signal that caused the coredump into the filename 添加致使產生core的信號
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成時的unix時間
%h - insert hostname where the coredump happened into filename 添加主機名
%e - insert coredumping executable name into filename 添加命令名
#我是生成到本身的當前目錄下方便使用
echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern
Ø 在rc.local中加入如下一行,這將使程序崩潰時生成的coredump文件位於/data/coredump/目錄下:
echo 」/data/coredump/core-%e-%p-%t「 > /proc/sys/kernel/core_pattern
用gdb進行查看core文件的內容
gdb [exec file] [core file]
以後基本上只用bt就能夠找到信息了,固然還有where, frame, up, down, print等活用。
實踐出真知
1.代碼
1: //a test file 2: 3: #include<iostream> 4: using namespace std; 5: 6: void test_fun() 7: { 8: char* szTmp = 0x00; 9: 10: //null ptr 11: *szTmp = 0x11; 12: } 13: 14: int main() 15: { 16: test_fun(); 17: return 0; 18: } 19:
2.編譯
#編譯時加 -g 參數獲得符號
ju@musicoder:~/study/dump$ g++ -g -o dump dump.cpp ju@musicoder:~/study/dump$ ls -l 總用量 40 -rwxr-xr-x 1 ju ju 34437 2012-04-10 00:06 dump -rw-r--r-- 1 ju ju 154 2012-04-10 00:05 dump.cpp ju@musicoder:~/study/dump$
3.運行
運行出錯,出現了core文件(會比較大)
ju@musicoder:~/study/dump$ ./dump 段錯誤 (core dumped) ju@musicoder:~/study/dump$ ls -l 總用量 160 -rw------- 1 ju ju 221184 2012-04-10 00:06 core-dump-17044-1333987618 -rwxr-xr-x 1 ju ju 34437 2012-04-10 00:06 dump -rw-r--r-- 1 ju ju 154 2012-04-10 00:05 dump.cpp ju@musicoder:~/study/dump$
4.調試
ju@musicoder:~/study/dump$ gdb ./dump core-dump-17044-1333987618 GNU gdb (GDB) 7.1-ubuntu Copyright (C) 2010 Free Software Foundation, Inc. #好多xxx #最後能夠看到 Loaded symbols for /lib/ld-linux.so.2 Core was generated by `./dump'. Program terminated with signal 11, Segmentation fault. #0 0x080485a4 in test_fun () at dump.cpp:9 9 *szTmp = 0x11; (gdb) #很容易就定位了,通常指針出錯都會有完整的堆棧信息,而數組越界則堆棧信息不完整顯示
1.不對文章正確性作保證,只爲本人學習之用。
2.本文參考了好多其它做者的文章,也引用了一些文字,對他們的知識共享精神表示感謝。
3.本文連接:
(1)好像加了這個就會被網易屏蔽
(2)http://pppboy.blog.163.com/blog/static/30203796201231011715932/
4.本文能夠任意轉載修改使用,但請保證文章完整性,不要誤導他人。
5.注意身體,早點休息,不作就別作,作就作好。