1. 程式人生 > >核心除錯工具 — kdump & crash

核心除錯工具 — kdump & crash

kdump簡介

kdump是系統崩潰的時候,用來轉儲執行記憶體的一個工具。

系統一旦崩潰,核心就沒法正常工作了,這個時候將由kdump提供一個用於捕獲當前執行資訊的核心,

該核心會將此時記憶體中的所有執行狀態和資料資訊收集到一個dump core檔案中以便之後分析崩潰原因。

一旦記憶體資訊收集完成,可以讓系統將自動重啟。

kdump是RHEL5之後才支援的,2006被主線接收為核心的一部分。它的原理簡單來說是在記憶體中保留一塊

區域,這塊區域用來存放capture kernel,當production kernel發生crash的時候,通過kexec把保留區域的

capure kernel給執行起來,再由捕獲核心負責把產品核心的完整資訊 - 包括CPU暫存器、堆疊資料等轉儲

到指定位置的檔案中。

kdump原理

kexec是kdump機制的關鍵,包含兩部分:

核心空間的系統呼叫kexec_load。負責在生產核心啟動時將捕獲核心載入到指定地址。

使用者空間的工具kexec-tools。將捕獲核心的地址傳遞給生產核心,從而在系統崩潰的時候找到捕獲核心的地址並執行。

kdump是一種基於kexec的核心崩潰轉儲機制。當系統崩潰時,kdump使用kexec啟動到第二個核心。第二個核心通常

叫做捕獲核心,以很小記憶體啟動以捕獲轉儲映象。第一個核心保留了記憶體的一部分給第二個核心啟動使用。

由於kdump利用kexec啟動捕獲核心,繞過了BIOS,所以第一個核心的記憶體得以保留。這是記憶體崩潰轉儲的本質。

捕獲核心啟動後,會像一般核心一樣,去執行為它建立的ramdisk上的init程式。而各種轉儲機制都可以事先在init中實現。

為了在生產核心崩潰時能順利啟動捕獲核心,捕獲核心以及它的ramdisk是事先放到生產核心的記憶體中的。

生產核心的記憶體是通過/proc/vmcore這個檔案交給捕獲核心的。為了生成它,使用者工具在生產核心中分析出記憶體的使用和

分佈等情況,然後把這些資訊綜合起來生成一個ELF標頭檔案儲存起來。捕獲核心被引導時會被同時傳遞這個ELF檔案頭的

地址,通過分析它,捕獲核心就可以生成出/proc/vmcore。有了/proc/vmcore這個檔案,捕獲核心的ramdisk中的指令碼就

可以通過通常的檔案讀寫和網路來實現各種策略了。

kdump配置

RHEL5開始,kexec-tools是預設安裝的。

如果需要除錯kdump生成的vmcore檔案,需要手動安裝kernel-debuginfo包。

(1) 預留記憶體

可以修改核心引導引數,為啟動捕獲核心預留指定記憶體。

在/etc/grub.conf (一般為/boot/grub/grub.conf的軟連結)中:

[email protected],Y是為kdump捕獲核心保留的記憶體,X是保留部分記憶體的起始位置。

預設為crashkernel=auto,可自行設定如crashkernel=256M。

(2) 配置檔案

配置檔案為/etc/kdump.conf,以下是幾個常用配置:

# path /var/crash

預設的vmcore存放目錄為/var/crash/%HOST-%DATE/,包括兩個檔案:vmcore和vmcore-dmesg.txt

# ssh <[email protected]>

will copy /proc/vmcore to <[email protected]>:<path>/%HOST-%DATE/ via SSH

make sure user has necessary write permissions on server.

自動拷貝到遠端機器上。

# default <reboot | halt | poweroff | shell | mount_root_run_init>

Actions to perform in case dumping to intended target fails.

轉儲失敗時執行。

(3) 啟動服務

# chkconfig kdump on // 開機啟動

# service kdump status // start、stop、restart等

(4) 功能驗證

Magic System request key is a magical key combo you can hit which the kernel will respond to regardless

of whatever else it is doing, unless it is completely locked up.

使用sysrq需要編譯選項CONFIG_MAGIC_SYSRQ的支援。詳細資訊可看documentation/sysrq.txt。

故意讓系統崩潰,來測試kdump是否正常工作。

# echo c > /proc/sysrq-trigger

Will perform a system crash by a NULL pointer dereference.

A crash dump will be taken if configured.

Magic SysRq還有一些很有趣的值,有的具有很大的破環性,輸出在/var/log/messages:

f:call oom_kill to kill a memory hog process. 執行oom killer。

l:shows a stack backtrace for all active CPUs. 打印出所有CPU的stack backtrace。

m:dump current memory info. 打印出記憶體使用資訊。

p:dump the current registers and flags. 打印出所在CPU的暫存器資訊。

(5) 捕獲核心

捕獲核心是一個未壓縮的ELF映像檔案,檢視捕獲核心是否載入到記憶體中:

# cat /sys/kernel/kexec_crash_loaded

縮小捕獲核心佔用的記憶體:

# echo N > /sys/kernel/kexec_crash_size

crash簡介

當系統崩潰時,通過kdump可以獲得當時的記憶體轉儲檔案vmcore,但是該如何分析vmcore呢?

crash是一個用於分析核心轉儲檔案的工具,一般和kdump搭配使用。

使用crash時,要求除錯核心vmlinux在編譯時帶有-g選項,即帶有除錯資訊。

如果沒有指定vmcore,則預設使用實時系統的記憶體來分析。

值得一提的是,crash也可以用來分析實時的系統記憶體,是一個很強大的除錯工具。

crash使用gdb作為內部引擎,語法類似於gdb,命令的使用說明可以用<cmd> help來檢視。

使用crash需要安裝crash工具包和核心除錯資訊包:

crash

kernel-debuginfo-common

kernel-debuginfo

crash使用

Analyze Linux crash dump data or a live system.

crash [OPTION] NAMELIST MEMORY-IMAGE      (dumpfile form)

crash [OPTION] [NAMELIST]                                   (live system form)

使用crash來除錯vmcore,至少需要兩個引數:

NAMELIST:未壓縮的核心映像檔案vmlinux,預設位於/usr/lib/debug/lib/modules/$(uname -r)/vmlinux,由

核心除錯資訊包提供。

MEMORY-IMAGE:記憶體轉儲檔案vmcore,預設位於/var/crash/%HOST-%DATE/vmcore,由kdump生成。

例如:# crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux   /var/crash/%HOST-%DATE/vmcore

(1) 錯誤型別

首先可以在vmcore-dmesg.txt中先檢視錯誤型別,如:

1. divide error: 0000 [#1] SMP,除數為0造成核心崩潰,由1號CPU觸發。

2. BUG: unable to handle kernel NULL pointer dereference at 000000000000012c,引用空指標。

這樣一來就能知道引發核心崩潰的錯誤型別。

(2) 錯誤地點

RIP為造成核心崩潰的指令,Call Trace為函式呼叫棧,通過RIP和Call Trace可以確定函式的呼叫路徑,以及在

哪個函式中的哪條指令引發了錯誤。

例如RIP為:[<ffffffff812cdb54>] ? tcp_enter_loss+0x1d3/0x23b

[<ffffffff812cdb54>]是指令在記憶體中的虛擬地址。

tcp_enter_loss是函式名(symbol)。

0x1d3是這條指令相對於tcp_enter_loss入口的偏移,0x23b是函式編譯成機器碼後的長度。

這樣一來就能確定在哪個函式中引發了錯誤,以及錯誤的大概位置。

Call Trace為函式的呼叫棧,是從下往上看的。可以用來分析函式的呼叫關係。

(3) crash基本輸出

# crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux   /var/crash/%HOST-%DATE/vmcore

      KERNEL: /usr/lib/debug/lib/modules/2.6.32-358.el6.x86_64/vmlinux
    DUMPFILE: vmcore  [PARTIAL DUMP]
        CPUS: 12
        DATE: Fri Sep 19 16:47:01 2014
      UPTIME: 7 days, 06:37:46
LOAD AVERAGE: 0.19, 0.05, 0.01
       TASKS: 282
    NODENAME: localhost.localdomain
     RELEASE: 2.6.32-358.el6.x86_64
     VERSION: #1 SMP Tue Oct 29 10:18:21 CST 2013
     MACHINE: x86_64  (1999 Mhz)
      MEMORY: 48 GB
       PANIC: "Oops: 0002 [#1] SMP " (check log for details)
         PID: 0
     COMMAND: "swapper"
        TASK: ffffffff81a8d020  (1 of 12)  [THREAD_INFO: ffffffff81a00000]
         CPU: 0
       STATE: TASK_RUNNING (PANIC)

這些基本輸出資訊簡單明瞭,可由sys命令觸發。

(4) crash常用命令

bt:列印函式呼叫棧,displays a task's kernel-stack backtrace,可以指定程序號bt <pid>。

log:列印系統訊息緩衝區,displays the kernel log_buf contents,如log | tail -n 30。

ps:顯示程序的狀態,>表示活躍的程序,如ps | grep RU。

sys:顯示系統概況。

kmem -i:顯示記憶體使用資訊。

dis <addr>:對給定地址進行反彙編。

exception RIP即為造成錯誤的指令。

關於log命令:

核心首先把訊息列印到核心態的ring buffer,使用者態的klogd負責讀取並轉發給syslogd,讓它記錄到磁碟。

在核心崩潰時,可能無法把訊息記錄到磁碟,但是ring buffer中一般會有記錄。所以log命令有時候能檢視

到系統日誌中所缺失的資訊。

(5) 結構體和變數

檢視結構體中所有成員的值,例如:

# ps | grep RU

>     0      0   0  ffffffff81a8d020  RU   0.0       0      0  [swapper]

# struct task_struct ffffffff81a8d020

struct task_struct {
  state = 0, 
  stack = 0xffffffff81a00000, 
  usage = {
    counter = 2
  }, 
  flags = 2097408, 

顯示整個結構體的定義:

# struct task_struct

struct task_struct {
    volatile long int state;
    void *stack;
    atomic_t usage;
    unsigned int flags;

顯示整個結構體的定義,以及每個成員的偏移:

# struct -o task_struct

struct task_struct {
     [0] volatile long int state;
     [8] void *stack;
    [16] atomic_t usage;
    [20] unsigned int flags;
    ...

顯示結構體中的成員定義,以及它的偏移:

# struct task_struct.pid

struct task_struct {
  [1192] pid_t pid;
}

顯示結構體中成員的值:

# struct task_struct.pid ffffffff81a8d020

  pid = 0

檢視全域性變數的值:

# p sysctl_tcp_rmem

sysctl_tcp_rmem = $4 = 
 {40960, 873800, 41943040}

檢視percpu全域性變數(加字首per_cpu_):

# p per_cpu__irq_stat

PER-CPU DATA TYPE:
  irq_cpustat_t per_cpu__irq_stat; // 變數型別的宣告
PER-CPU ADDRESSES:
  [0]: ffff880028216540 // 0號CPU對應變數的地址
  [1]: ffff880645416540
  ...

檢視0號CPU對應變數的值:

# struct irq_cpustat_t ffff880028216540

struct irq_cpustat_t {
  __softirq_pending = 0, 
  __nmi_count = 4780195, 
  irq0_irqs = 148, 
  ...

(6) 反彙編和原始碼行

反彙編:

# dis ffffffffa021ba91 // 反彙編一條指令

# dis -l probe_2093+497 10 // 反彙編從某個地址開始的10條指令

對於核心中的符號:

# sym tcp_v4_do_rcv // 通過symbol,顯示虛擬地址和原始碼位置

# sym ffffffff8149f930 // 通過虛擬地址,顯示symbol和原始碼位置

對於模組中的符號:

需要先載入相應的模組進來,才能顯示符號對應的原始碼:

# mod // 檢視模組

# mod -s module /path/to/module.ko // 載入模組

# sym symbol // 顯示符號對應的模組原始碼,也可以用virtual address

(7) 修改記憶體

提供動態的修改執行中核心的功能,以供除錯,但是RHEL和CentOS上不允許。

wr:modifies the contents of memory.

wr [-u | -k | -p] [-8 | -16 | -32 | -64] [address | symbol] value

使用例子:

# p sysctl_tcp_timestamps

sysctl_tcp_timestamps = $3 = 1

# wr sysctl_tcp_timestamps 0

wr: cannot write to /dev/crash!


我勒個擦,/dev/crash的檔案屬性是rw,但是crash_fops中並沒有提供寫函式,所以還是隻讀的。

這個功能很有用,但被RHEL和CentOS禁止了,所以如需動態修改執行核心還是用systemtap吧。

Reference

相關推薦

核心除錯工具kdump & crash

kdump簡介 kdump是系統崩潰的時候,用來轉儲執行記憶體的一個工具。 系統一旦崩潰,核心就沒法正常工作了,這個時候將由kdump提供一個用於捕獲當前執行資訊的核心, 該核心會將此時記憶體中的所有執行狀態和資料資訊收集到一個dump core檔案中以便之後分析崩潰原因

Linux核心除錯工具

一些Linux Kernel的分析除錯工作,主要包換qemu,kprobes和trace等,以作備忘。 Qemu原始碼級除錯Kernel 1. Qemu編譯與安裝 先安裝libsdl的開發庫 $ ./configure $ make # make install Qe

記一次Linux核心崩潰:kdump,crash,vmcore

### 原理 Linux核心傳送崩潰時,kdump會生成一個核心轉儲檔案vmcore。 可以通過分析vmcore分析出核心崩潰的原因。 crash是一個被廣泛應用的核心奔潰轉儲檔案分析工具。使用crash除錯核心轉儲檔案,需要安裝crash工具和核心除錯工具kernel-debuginfo。 ### 安裝需

【舊文章搬運】Windbg+Vmware驅動除錯入門(四)---VirtualKD核心除錯加速工具

原文發表於百度空間,2009-01-09========================================================================== 今天又想起來VirtualKD這個東西,試用了一下,真是爽壞了,可能我火星了~~ 很久以前就知道小喂有個VmKd工具

Linux核心除錯的方式以及工具集錦

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可, 轉載請註明出處, 謝謝合作 因本人技術水平和知識面有限, 內容如有紕漏或者需要修正的地方, 歡迎大家指正, 也歡迎大家提供一些其他好的除錯工具以供收錄, 鄙人在此謝

linux3.0 核心除錯工具KDB支援反彙編

      KDB是linux核心整合的一個除錯工具,關於更多KDB的資訊,請查閱相關的資訊。本文就是移植kdb的反彙編命令ID。      在KDB成為核心自身的一部分的時候,關於ID命令就已經被移除,具體的原因不知道。現在的核心雖然支援kdb了,但是並沒有這個命令  I

vue 開發除錯工具vue-devtools 安裝

安裝前的準備 因為安裝依賴需要Node.js環境。所以,第一件事就是安裝Node.js。 安裝完成之後,從github的下載地址將該外掛下載下來:https://github.com/vuejs/vue-devtools 安裝步驟 下載之後,解壓檔案,然後複製貼上解

推薦程式碼除錯工具 Xdebug

寫程式碼總繞不過需要除錯,除了 UnitTest 外,我們還是需要藉助 Xdebug 進行除錯。 所以今天來說說如何基於本地 Docker 環境下,使用 Xdebug。 這裡的使用,是分別整合到 VS Code 和 PHPStorm 下。 安裝 Xdebug 還是基於神級武

linux核心資料結構以及核心除錯

一、可移植性 1.1 資料型別可移植性 由於核心可能執行在不同的架構上,不同的架構具有不同的機器字長,因而可移植性對核心程式設計非常重要。核心資料使用的資料型別分為 3 個主要型別 標準C型別 明確大小的型別 用作特定核心物件的型別 1.1.1 標準 C 型別 使用標準

移動端web開發除錯工具——Vorlon.JS上手教程

問題提出: 在移動端頁面的日常開發中常常會碰到這樣一個問題,頁面在Chrome的Device模式下顯示正常,但在移動端瀏覽器或者內嵌到APP裡就會出現樣式問題或者Js程式碼問題,但是移動端上沒有類似Chrome的開發者除錯工具,只能通過嘗試修改,重複釋出版本來檢查問題,或者寫一大堆a

在 thinkphp5.1+ 中利用 composer 安裝 php 除錯工具 kint

在 thinkphp 中,沒有 php 除錯函式,如類似在 Laravel/Lumen 中有一個常用的除錯 dd(),我們可以利用 composer 工具安裝一個類似這樣的 php 除錯工具. 文件地址 https://kint-php.github.io/kint/ 直接在專案中

除錯前端頁面的瀏覽器除錯工具

主要瀏覽器的除錯工具 通常,瀏覽器啟用除錯工具一般是按下 F12 鍵,並在除錯選單中選擇 "Console" 。 各瀏覽器的步驟如下: Chrome 瀏覽器 開啟瀏覽器。 在選單中選擇工具。 在工具中選擇開發者工具。 最後,選擇 Console。 Fi

Laravel Telescope:優雅的應用除錯工具

文章轉自:laravel-china.org/topics/1901… 視訊教程:047. 優雅的應用除錯工具--laravel/telescope (5.7 新擴充套件) Laravel Telescope 是由 Mohamed Said 和 Taylor Otwell 開源 

SylixOS 核心除錯

1、printk()是最常用的,可以在核心態中列印響應除錯資訊; 2、部分核心程式碼中無法使用printk()列印資訊時就需要用到_DebugFormat(),申明如下: _DebugFormat(level, fmt, ...) level可選值如下: #define __LO

SylixOS下開啟核心除錯資訊

    開啟檔案libsylixos/SylixOS/config/net/net_cfg.h 將巨集LW_CFG_LWIP_DEBUG置1     開啟檔案libsylixos/SylixOS/include/network/

GDB程式除錯工具

使用gcc/g++編譯程式時加-g選項以方便除錯。 設定系統允許產生core檔案: $ulimit -c unlimited 除錯由test程式產生的core檔案: $gdb ./test core 設定輸出資訊時的分頁功能 set pagination on # 或者 set heigh

Mac OS下安裝串列埠除錯工具minicom

最近在做一個Mac下的ssh除錯工具,但是出現了一點問題。後來發現居然Mac下有串列埠除錯工具可以用,所以果斷換串列埠了,是普通PL2303晶片的usb轉串列埠線。 接下來說下簡單的安裝步驟吧。我是勤勞的搬磚工。。。 首先的是安裝PL2303串列埠驅動,轉載自在MAC OS X下安裝usb轉

嵌入式Linux開發——(十六)Linux核心除錯技術

1、核心列印函式printk     ①printk函式與printf函式用法格式完全相同     ②它所列印的字串頭部可以加入“<n>”樣式字元,n=0---7表示這條資訊的記錄  級別     ③對於p

【Linux C/C++】 第07講 gdb除錯工具詳解

     當你需要單步跟蹤除錯的時候,就必然會用到gdb工具,不同於VS方便的除錯方式,gdb的除錯並不是那麼的方便直觀。不要降低熱情,熟練以後你會發現Linux下的程式設計方式非常好用。       一、簡介   &

除錯除錯工具】 Windbg的gflags.exe 和 pageheap的使用和原理分析

PageHeap / Gflags 使用,溢位容易用到   堆除錯工具——pageheap的使用和原理分析 今天除錯一個bug,用pageheap解決,在此記錄一下。 bug症狀如下: 1:不確定性崩潰,用vs除錯啟動每次崩潰地點都在crt分配或者釋放堆的位置 2:崩潰時v