1.如果沒有產生core文件,可以查詢系統log
通過 sudo cat /var/log/messages |grep segfault 或者 sudo dmesg|grep segfault 獲得
這種信息一般都是由內存訪問越界造成的,不管是用戶態程序還是內核態程序訪問越界都會出core, 並在系統日志里面輸出一條這樣的信息。這條信息的前面分別是訪問越界的程序名,進程ID號,訪問越界的地址以及當時進程堆棧地址等信息,比較有用的信息是 最后的error number. 在上面的信息中,error number是4 ,下面詳細介紹一下error number的信息:
在上面的例子中,error number是6, 轉成二進制就是110, 即bit2=1, bit1=1, bit0=0, 按照上面的解釋,我們可以得出這條信息是由於用戶態程序讀操作訪問越界造成的。
error number是由三個字位組成的,從高到底分別為bit2 bit1和bit0,所以它的取值范圍是0~7.
bit2: 值為1表示是用戶態程序內存訪問越界,值為0表示是內核態程序內存訪問越界
bit1: 值為1表示是寫操作導致內存訪問越界,值為0表示是讀操作導致內存訪問越界
bit0: 值為1表示沒有足夠的權限訪問非法地址的內容,值為0表示訪問的非法地址根本沒有對應的頁面,也就是無效地址
2.Linux下打開core文件,定位segfault
source:http://blog.chinaunix.net/uid-24774106-id-344195.html
出現段錯誤,不容易定位到底是哪行代碼出現了問題,segfault多次折磨的筆者死去活來,
查資料發現了定位段錯誤的方法。
Linux下有核心轉儲文件即core文件,會把程序崩潰是的現場保存起來供gdb來調試。
打開的辦法是 ulimit -c unlimited 。
設置之前可以調用ulimit -c 查看當前的大小,如果是0,表示不生成core文件。unlimited 的含義是不論生成的core文件有多大,我都讓系統生成core 文件。
當時這個方法有個弊端是,在那個終端上設置的ulimit就在那個終端上生效,如果你在另一個終端上執行程序,你會發現,縱然有段錯誤,你也沒生成core文件
第二個辦法是修改 /root/.bash_profile 文件添加一行 ulimit -S -c unlimited 然后保存關閉文件。
有很多linux系統/root 目錄下並沒有.bash_profile 文件,比如SUSE,這沒有關系你自己vi 創建這個文件即可。
修改完這個文件之后,執行source /root/.bash_profile,你就可以查看你的修改生效了沒有。
查看方法是 ulimit -c.你會發現,終端打印出 unlimited,表示你的配置生效了,你可以新開終端 執行 ulimit -c,發現新開終端也是unlimited 。
好,打開開關之后,你就可以跑你的有segfault的代碼了。
一般core文件會生成在你的可執行文件所在的目錄下。當然可以設定。
設定的方法是 修改 /proc/sys/kernel/core_pattern
這個文件不支持vi的方式修改,可以使用echo
如echo “/corefile/core-%p-%e-%t” > /proc/sys/kernel/core_pattern
這個語句的含義是將core文件生成在 /corefile/這個目錄下
生成的文件名的格式是:“core”-“pid”-可執行程序名-段錯誤時間
%p ---------段錯誤進程的PID
%e-----------發生段錯誤的可執行文件名
%t------- 發生段錯誤的時間
還有其他配置選項。
生成了core文件,你就可以調試了,調試方法是:
gdb -c core test
或 gdb test core
注test是你的可執行文件名。你就可以想用gdb調試文件一樣調試你的core文件了。