簡介
存儲器區塊錯誤(英語:Segmentation fault,經常被縮寫為segfault),又譯為存儲器段錯誤,也稱訪問許可權衝突(access violation),是一種程式錯誤。
它會出現在當程式企圖訪問CPU無法定址的存儲器區塊時。當錯誤發生時,硬體會通知作業系統產生了存儲器訪問許可權衝突的狀況。作業系統通常會產生核心轉儲檔案(core dump)以方便程式設計師進行除錯。通常該錯誤是由於調用一個地址,而該地址為空(NULL)所造成的,例如鍊表中調用一個未分配地址的空鍊表單元的元素。數組訪問越界也可能產生這個錯誤。
x86記憶體分段
x86架構中,存儲器分段(英語:Memory Segmentation)是在不改變16位段選擇符時,使用單個索引暫存器(保存了段內地址偏移值)所能夠定址的的存儲器範圍部分。也指在英特爾x86指令集體系結構下存儲器分段的實現方式。
從8086開始到隨後的各款x86架構CPU,無論是實模式還是保護模式,記憶體定址時都使用16位段暫存器(segment register)。段暫存器默認使用情況為:
•代碼段暫存器CS與暫存器IP相配合獲得當前執行緒代碼執行到的記憶體位置;
•數據段暫存器DS與各通用暫存器配合訪問記憶體中的數據;
•棧段暫存器SS與暫存器(E)SP、(E)BP配合訪問執行緒的調用棧(call stack);
•擴展段暫存器ES用於特定字元串指令(如MOVS或CMPS)。
•80386引入了2個額外的段暫存器FS與GS,並無特定的硬體用途。
這些段暫存器除了有16位的可見部分,還有不可見的隱藏部分,稱為描述符快取“descriptor cache”或隱藏暫存器“shadow register”。當一個段選擇符(segment selector)裝入段暫存器的可見部分,處理器同時也把該段描述符的其它數據裝入到段暫存器的隱藏部分,這包括段開始的基地址、段長度、訪問控制信息等。這些信息快取到段暫存器中,避免了處理器在轉址(translate address)時花費額外的匯流排周期從段選擇符表中讀入數據。處理器指令中可以明示使用哪些段暫存器,這將替換掉默認使用的段暫存器。
核心轉儲
核心檔案(core file),也稱核心轉儲(core dump),是作業系統在進程收到某些信號而終止運行時,將此時進程地址空間的內容以及有關進程狀態的其他信息寫出的一個磁碟檔案。這種信息往往用於調試。
程式自身產生的coredump檔案一般可以用來分析程式運行到哪裡出錯了。Linux平台常用的coredump檔案分析工具是gdb;Solaris平台用pstack和pflags;Windows平台用userdump和windbg。外部程式觸發的dump一般用來分析進程的運行情況,比如分析記憶體使用/執行緒狀態等。Solaris的常用記憶體分析工具umem就是需要先通過gcore pid得到coredump的檔案然後繼續分析記憶體情況。