初步认识Linux oops 消息
? ? oops是英語口語"糟糕"的意思,當LINUX 內核發生嚴重錯誤時,比如內存段錯誤時,將會提示一大段信息。
? ? Oops提示信息相當多,包括出問題時的,各個常用寄存器的值,調用的堆棧,以及出錯的可能原因。
oops 的格式
? 內核的文檔里的詳細的Oops的說明,的名字是
? Documentation/oops-tracing.txt
? http://www.mjmwired.net/kernel/Documentation/oops-tracing.txt
oops第一段出錯是內存page地址,
? 例如提示,?
? Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c7510000
? 往往表示碰到空指針了。
??
第二段出錯時是寄存器的快照,不同CPU顯示不同情況;
? ?其中基本上所有CPU都會有的PC寄存器(Program counter register),它保存最后出問題的地址。
? ?LR保存著函數返回地址。這里就比較容易看出是誰出問題
? ?例如,
? ?<8>PC is at memcpy+0x48/0x330
? ?<8>LR is at s3c_fimc_v4l2_enum_fmt_vid_cap+0x44/0x4c
? 這里可以看出,最后出問題代碼在 memcpy里,而它是被s3c_fimc_v4l2_enum_fmt_vid_cap調用。結合前面的原因,可以知道應該是在memcpy里碰到空指針。
? ?函數名后面的兩個數字,第一個是調用偏移量,第二個是函數總尺寸。
最重要是第三段,即可出錯的調用堆棧(Call Trace).從這里即可推算出錯的所在函數,
oops消息產生機制
? ? oops(也稱 panic),稱程序運行崩潰,程序崩潰后會產生oops消息。應用程序或內核線程的崩潰都會產生oops消息,通常發生oops時,系統不會發生死機,而在終端或日志中打印oops信息。
? ? 當使用NULL指針或不正確的指針值時,通常會引發一個 oops 消息,這是因為當引用一個非法指針時,頁面映射機制無法將虛擬地址映像到物理地址,處理器就會向操作系統發出一個"頁面失效"的信號。內核無法"換頁"到并不存在的地址上,系統就會產生一個"oops"。
? ? oops 顯示發生錯誤時處理器的狀態,包括 CPU 寄存器的內容、頁描述符表的位置,以及其一些難理解的信息。這些消息由失效處理函數(arch/*/kernel/traps.c)中的printk 語句產生。較為重要的信息就是指令指針(EIP),即出錯指令的地址。
? ? 由于很難從十六進制數值中看出含義,可使用符號解析工具klogd。klogd 守護進程能在 oops 消息到達記錄文件之前對它們解碼。klogd在缺省情況下運行并進行符號解碼。
? ? Linux內核提供了調用,允許程序決定裝載哪些模塊和它們在內存中位置。通過這些系統調用,klogd守護進程生成一張符號表用于調試發生在可裝載模塊中的保護錯誤。內核模塊的裝載或者卸載都會自動向klogd發送信號,klogd可將內核模塊符號的地址動態翻譯為符號字符串。
下面來搞2個錯誤程序,看一下oops消息的基本情況;
先看test1.c;
#include <stdlib.h> #include <string.h>int main() {char *p = (char *) malloc(100);strcpy(p, "hello");free(p); // p 所指的內存被釋放,但是p所指的地址仍然不變if(p != NULL) // 沒有起到防錯作用{strcpy(p, "world"); // 出錯}getchar();return 0; }此程序應該出錯,因為p已釋放,然后執行了strcpy(p, "xxxx"); 但是沒有產生dump;
再看test2.c;
#include <stdlib.h>int main() {*(int *)0 = 0;getchar();return 0; }? ? test2.exe崩潰了,產生了dump;
? ? 在exe目錄下生成了一個dump文件;格式和內容如前所述;有時間再細看;
?
總結
以上是生活随笔為你收集整理的初步认识Linux oops 消息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初步了解Linux proc文件系统
- 下一篇: 初步了解Linux strace 命令和