錯誤簡介
出現 “Segmentation fault (core dumped)” 錯誤通常意味著程序訪問了未分配的內存或者越界訪問了已分配內存之外的區域。
段錯誤通常發生在以下情況:
- 空指針解引用:嘗試對空指針進行操作。
- 內存越界:訪問了超出分配內存邊界的區域。
- 棧溢出:遞歸深度過大或者局部變量過多導致棧空間不足。
在遇到段錯誤時,常用的調試方法包括:
- 使用調試器如
gdb
來跟蹤程序運行時的狀態,從而定位具體的錯誤發生位置。 - 檢查代碼中的指針操作,確保不會解引用空指針或者越界訪問。
- 考慮使用內存檢測工具(如 Valgrind)來幫助檢測內存泄漏或者非法內存訪問問題。
為什么 try-catch 捕獲不到?
在 C++ 中,try-catch
語句主要用于捕獲異常,而不是用來處理諸如段錯誤這樣的底層內存訪問問題。
core文件的生成
在ubuntu環境下,默認不生成core文件,需要生成core文件時,需要使用ulimit進行設定。
ulimit -c
判斷是否開啟轉儲,為0 則沒有開啟
1. 修改core文件路徑
在Linux系統中,/proc/sys/kernel/core_pattern文件用于指定核心轉儲文件的命名模式。這個文件通常是一個特殊的虛擬文件,修改它會影響系統在發生程序崩潰或異常時生成的核心轉儲文件的命名方式。
默認內容如下
|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
使用管理員模式,修改"/proc/sys/kernel/core_pattern"文件。
su
echo "core_%e_%p_%t" > /proc/sys/kernel/core_pattern
該路徑為在執行文件當前路徑創建相應的core文件,其中可選參數列表為:
%p - insert pid info filename
%u - insert current uid into filename
%g - insert current gid into filename
%s - insert signal that the coredump into the filename
%t - insert UNIX time that the coredump occurred into filename
%h - insert hostname where the coredump happened into filename
%e - insert coredumping executable name into filename
挑幾個翻譯下
- %e是執行文件名(可能被截斷)
- %P是pid
- %t是coredump生成時間戳
- %s是觸發生成coredump的信號值
注意:修改該文件后,如果重啟Linux系統,該文件又會變回初始值。
2. 使能core文件生成
# 列出當前終端所有資源限制
ulimit -a # 設置生成core文件的大小:1024k
ulimit -c 1024# 設置生成core文件的大小:不受限制
ulimit -c unlimited
注意:在終端通過ulimit命令設置core file size,僅在當前終端有效。
3. 驗證core文件生成
在修改core文件路徑和開啟core文件生成后,可以使用kill命令簡單驗證core文件生成。
kill -s SIGSEGV $$
core文件的分析
分析核心文件(core dump file)通常是為了理解程序崩潰的原因或故障的根本問題。以下是分析核心文件的一般步驟:
-
確認調試工具安裝:
確保系統上安裝了用于分析核心文件的調試工具,例如gdb
(GNU Debugger)或者適用于特定語言和環境的其他調試工具。 -
獲取符號信息:
如果程序是用編譯器的調試選項編譯的(例如-g
選項),則核心文件通常包含了符號信息,可以更好地分析。如果沒有符號信息,分析將更具挑戰性。 -
加載核心文件:
使用調試工具加載核心文件和程序執行文件(如果可用)。例如,在使用gdb
時,可以執行:gdb /path/to/your/program /path/to/core/file
-
分析堆棧信息:
使用調試工具查看堆棧回溯(backtrace),這將顯示程序在崩潰時的函數調用路徑。在gdb
中,可以使用bt
命令:(gdb) bt
-
查看變量和內存狀態:
如果有符號信息,可以查看在崩潰時程序的變量值和內存狀態。這對于理解程序崩潰的原因非常有幫助。 -
分析核心轉儲的代碼段和數據段:
核心文件通常包含程序崩潰時的代碼段和數據段的快照。分析這些內容有助于理解程序在崩潰時的狀態。 -
查找原因并調試:
根據堆棧信息和變量狀態,嘗試確定程序崩潰的確切原因。這可能涉及到查找空指針解引用、內存泄漏、未處理的異常等問題。 -
記錄和報告:
如果能夠找到程序崩潰的原因或者問題點,記錄并報告給開發團隊或相關人員,以便進行修復或進一步的調查。
實戰分析
- 編譯時用-g選項
g++ -g -o test.out test.cpp
- 修改core文件生成路徑到當前執行文件同目錄
echo "core_%e_%p_%t" > /proc/sys/kernel/core_pattern
- 設置生成core文件的大小:不受限制
ulimit -c unlimited
4.在當前終端運行程序,因為ulimit設置 只在當前終端有效。
./test.out
5.程序出錯后會在執行同目錄下生成類似 core_test.ou_2024_1720274485 文件,用gdb工具分析
gdb ./test.out ./core_test.ou_2024_1720274485
使用 gdb 檢查變量:
你可以在 gdb 中使用 print 命令查看 queue 和 front 的值。例如:
(gdb) print queue
(gdb) print front
相關資料:
- https://blog.csdn.net/ftswsfb/article/details/119192789
- https://blog.51cto.com/u_13536788/9686757