鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 作為一個半路出家的linuc用戶,coredump這個問題太讓人抓狂了,網上找了好多都是不全面,不適應或者看不懂;現在終於解決了,記錄一下防止以後出現還是無解,同時也分享給大家,希望大家能少踩一些坑。 1.什麼是段錯誤 core dump又叫核心 ...
鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站
作為一個半路出家的linuc用戶,coredump這個問題太讓人抓狂了,網上找了好多都是不全面,不適應或者看不懂;現在終於解決了,記錄一下防止以後出現還是無解,同時也分享給大家,希望大家能少踩一些坑。
1.什麼是段錯誤
core dump又叫核心轉儲, 當程式運行過程中發生異常, 程式異常退出時, 由操作系統把程式當前的記憶體狀況存儲在一個core文件中, 叫core dump. (linux中如果記憶體越界會收到SIGSEGV信號,然後就會core dump)。產生段錯誤的原因大致上有三類:訪問不存在的記憶體地址、訪問系統保護的記憶體地址和訪問只讀的記憶體地址。
2. 解決方案
網上的資料雖然比較亂,但是也提供了一個解決問題的思路:
(1)設置core文件,找到段錯誤生成的core文件
(2)利用core文件,使用GDB測試找到問題所在
3.解決過程
先看問題:
3.1 生成Core文件
3.1.1 使用ulimit -a命令查看core文件大小限制
可以看到core file size的大小為0,文件根本裝不進,需要使用 ulimit -c unlimited 修改這個文件的大小
修改成功後,按照網上的說法,再運行程式就會生成core文件,一般路徑和可執行程式一個路徑。但是在ubuntu20.04下,怎麼也找不到去哪裡了(反正我的是這樣),因此需要查看core文件的生成路徑。
3.1.2 在終端輸入 cat /proc/sys/kernel/core_pattern 查看core的生成路徑。
轉到這個路徑下去找是找不到core文件,這是因為ubuntu的服務apport.service。自動生成崩潰報告,官方為了自動收集錯誤的。我們肯定想到修改路徑的辦法,那就演示一下會怎麼樣。
core的設置主要有兩個命令:
//控制core文件的文件名中是否添加pid作為擴展
echo "1" > /proc/sys/kernel/core_uses_pid
//設置core文件的輸出路徑和輸出文件名,這裡我的路徑是/home/boy/corefile,文件名就是後面的部分
echo "/home/boy/corefile/core-%e-%p-%t"> /proc/sys/kernel/core_pattern
//參數說明
%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 "/home/boy/corefile/core-%e-%p-%t"> /proc/sys/kernel/core_pattern 進行修改,結果如圖
3.1.3 修改core文件生成路徑
因為我們修改的core_pattern文件是只讀文件,沒法這樣修改。所以要換一種思路,修改不了就先停掉apport.service,這個服務對我們來說基本沒用。
錯誤報告的部分操作命令如下:
//1.啟用錯誤報告
sudo systemctl enable apport.service
//或
sudo service apport start
//2.關閉錯誤報告
sudo systemctl disable apport.service
//或
sudo service apport stop
所以,用sudo service apport stop關閉錯誤報告後我們再看core文件的路徑會怎麼樣
可以看到,路徑發生了變化,再運行一次試試,看現在能不能生成core
可以看到,運行完後用ll查看生成了core文件,方法有限,下麵就是GDB調試找到錯誤的位置了。
3.2 GDB測試
GDB詳細說明請看參考資料大佬的整理,這裡只記錄一下我怎麼測試的
3.2.1 啟動gdb
輸入gdb 運行文件 core文件,例如:
gdb bin/run_vo core
結果如下:
可以看到對記憶體出現非法訪問時將收到段錯誤信號SIGSEGV下麵就是出錯的位置,我們還可以使用backtrace回溯定位問題。
3.2.2 輸入bt回溯定位
可以看到現在的報告更加詳細。
到此,coredump問題已經解決,輸入q,即可退出gdb,剩下就是修改問題部分了。
原文鏈接:https://blog.csdn.net/weixin_52402390/article/details/123900689