1. 程式人生 > >Linux核心除錯工具

Linux核心除錯工具

一些Linux Kernel的分析除錯工作,主要包換qemu,kprobes和trace等,以作備忘。

Qemu原始碼級除錯Kernel

1. Qemu編譯與安裝

先安裝libsdl的開發庫

$ ./configure

$ make

# make install

Qemu-1.2.1試過能work,早先的版本編譯啟動時可能有問題。怕麻煩的可以直接apt-get install qemu。。。但這樣裝起來的qemu有可能斷點不work。

2. Linux kernel編譯

如果要在64位機上編譯32位核心,要加上ARCH=xxx選項。如

# make ARCH=i386 defconfig

# make ARCH=i386 menuconfig

然後選上:

   kernel hacking –> compile the kernel with debug info

   kernel hacking –> compile the kernel with frame pointers

另外選上      

    File system -> The extended 4 (ext4) filesystem

否則對有些img可能會在啟動時掛載root失敗.

# make ARCH=i386 bzImage

結束後生成Arch/x86/boot/bzImage和vmlinux,再在qemu的官網上下linux-0.2.img.bz2並解壓得到linux-0.2.img。執行

$ qemu -kernel bzImage -hda linux-0.2.img -append root=/dev/sda rw -s -S

由於加了-S起來後停住在1234埠上等待debugger連線,於是起gdb client:

$ gdb vmlinux

(gdb) target remote localhost:1234

然後就可以像調app一樣調kernel了。如圖:

 

注意Root檔案系統映象除了用qemu提供的test image外,還可以自己用busybox做。嫌麻煩的可以用Buildroot,它會自動下載和編譯Linux核心和rootfs等等。

用Qemu調有個好處是還可以用Qemu的Monitor檢視系統資訊(http://doc.opensuse.org/products/draft/SLES/SLES-kvm_sd_draft/cha.qemu.monitor.html)  。如檢視control register,tlb或者memory mapping,在除錯時都是非常有用的。

Kprobes, jprobes,dprobes

Xprobes族工具以module的方式在指定地址或函式位置加hook,然後使用者可以呼叫自定義的handler。kprobes用來截地址(當然更多時候是根據symbol定位地址),jprobes用來截函式,用它檢視函式引數比較方便,因為它的handler原型和要截的函式是一樣的。Dprobes可以動態執行。

大多數時候我們會通過symbol來加hook,kernel的symbol可以通過以下三種方式找到

1. kernel編譯生成的System.map檔案

2. $ nm vmlinuz

3. /proc/kallsyms

檢視當前的kprobes:

# cat/sys/kernel/debug/kprobes/list

關閉

# echo "0"> /sys/kernel/debug/kprobes/enabled

開啟

# echo "1"> /sys/kernel/debug/kprobes/enabled

Linux kernel提供了相關文件Documentation/kprobes.txt,並且提供了幾個例子,在samples/kprobes下。用以下Makefile單獨編譯例子:

obj-m +=jprobe_example.o kprobe_example.o

KDIR=/lib/modules/$(shell uname -r)/build

all:

$(MAKE)-C $(KDIR) SUBDIRS=$(PWD) modules

clean:

rm-rf *.o *.ko *.mod.* .c* .t*

編譯完後:

# insmod./kprobes_example.ko

然後用 dmesg命令就可以看到handler的輸出,如:

[ 1251.789211]Planted kprobe at c1058e30

[ 1256.716389]pre_handler: p->addr = 0xc1058e30, ip = c1058e31, flags = 0x246

[ 1256.716394]post_handler: p->addr = 0xc1058e30, flags = 0x246

[ 1262.680009]pre_handler: p->addr = 0xc1058e30, ip = c1058e31, flags = 0x246

[ 1262.680024]post_handler: p->addr = 0xc1058e30, flags = 0x246

...

[ 1468.928704]Planted jprobe at c1058e30, handler addr e08ff000

[ 1471.688212]jprobe: clone_flags = 0x1200011, stack_size = 0x0, regs = 0xcef87fb4

[ 1474.153652]jprobe: clone_flags = 0x1200011, stack_size = 0x0, regs = 0xcef87fb4

產生kernel Core dump

Kernel core dump需要核心支援,Linux kernel中的Documentation/kdump.txt對此講得比較詳細。

Ubuntu上可以裝linux-crashdump, 其中包含crash,kexec-tools和makedumpfile等工具。裝完後重啟機子,啟動時按shift進grub,按e看到啟動選項多了crashkernel=XXX啥的。進入系統後

# service kdump start

開啟kdump程序。系統崩潰時就會在/var/crash/下產生dump檔案。簡便使系統crash的方法是用magic sysrq:

SysrqAlt+SysRq+s // sync

SysrqAlt+SysRq+c // force crash

分析core dump和實時檢視系統

crash可用於檢視core dump或者實時檢視執行狀態。假設核心core dump在/var/crash/linux-image-2.6.32-38-generic.0.crash。先從crash檔案中解壓出vmcore檔案:

# apport-unpack /var/crash/linux-image-2.6.32-38-generic.0.crash  ./

再用crash檢視:

# crash vmlinux  ./VmCore

這裡的vmlinux是kernel source編譯出來的binary。

crash還可以用來實時檢視當前執行的系統,直接執行:

# crash vmlinux

其實相當於

# crash vmlinux /proc/kcore,/proc/kcore是系統虛擬出來的core檔案。

gdb, ddd也可用於相同功能,比如要實時檢視系統:

# ddd vmlinux /proc/kcore

就可以對系統進行有限的gdb除錯。

 

Kernel Trace

Kernel的trace功能依賴於debugfs,如果還沒掛載的話要先掛上。trace的主要檔案在/sys/kernel/debug/tracing下。其用法在kernel中的documentation/trace下寫得比較詳細,同時kernel還提供了相關例子sample/trace_events.c。

在/sys/kernel/debug/tracing下幾個重要的檔案:

trace: tracer的輸出

available_tracers: 可用tracer

current_tracer:當前enabled的tracer

tracing_enabled:開關

例:

# echo function > current_tracer

# echo 1> tracing_enabled

# cat trace > trace.txt

# echo 0> tracing_enabled

# cat ./trace.txt

得到如:

...

Xorg-896   [000]  212.518803: do_softirq <-irq_exit

Xorg-896   [000]  212.518806: __do_softirq <-do_softirq

Xorg-896   [000]  212.518813: run_timer_softirq <-__do_softirq

Xorg-896   [000]  212.518816: hrtimer_run_pending <-run_timer_softirq

Xorg-896   [000]  212.518818: _raw_spin_lock_irq <-run_timer_softirq

Xorg-896   [000]  212.518821: rcu_bh_qs <-__do_softirq

Xorg-896   [000]  212.518824: __local_bh_enable <-__do_softirq

Xorg-896   [000]  212.518826: rcu_irq_exit <-irq_exit

Xorg-896   [000]  212.518828: rcu_enter_nohz <-rcu_irq_exit

 Xorg-896   [000]  212.518831: idle_cpu <-irq_exit

...

:上面的工具依賴於一些kernel的feature,如debugfs和sysrq等,要使用則要在核心編譯時加上它們。

debugfs使核心的資訊以基於記憶體的檔案系統呈現,從而使使用者很方便地與之互動。詳見kernel的Documentation/debugfs.txt。掛載通過

# mount-t debugfs nodev /sys/kernel/debug

Sysrq提供了一些用於開發除錯kernel的熱鍵,詳見kernel的Documentation/sysrq.txt, 該feature的開啟通過

# echo 1 >/proc/sys/kernel/sysrq

或將/etc/sysctl.conf設定kernel.sysrq = 1。

上面介紹的只是kernel除錯工具中的滄海一粟,還有好多神器無法列舉,如kgdb, kdb遠端除錯kernel,kmemcheck,faultinjection等等。

相關推薦

Linux核心除錯工具

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

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

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

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

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

linux核心除錯技巧之一 dump_stack【轉】

在核心中程式碼呼叫過程難以跟蹤,上下文關係複雜,確實讓人頭痛 呼叫dump_stack()就會列印當前cpu的堆疊的呼叫函數了。 如此,一目瞭然的就能看到當前上下文環境,呼叫關係了 假設: 遇到uvc_probe_video這麼一個函式,不知道它最終是被誰呼叫到的,根據linux裝置模型,初步推測,p

Linux核心TC工具鏈路頻寬設計--無類佇列規定

      Linux 核心的 TC(traffic control)工具可以用來對網路頻寬做一定的設計和管理,這裡將對這一工具的使用做一定的介紹,在正式開始介紹TC 之前,先對一些基本的單位做一個說明。為了避免概念混亂,TC 採用如下規定

Linux核心TC工具鏈路頻寬設計--CBQ佇列規定

1.1 著名的 CBQ 佇列規定       除了可以分類之外,CBQ 也是一個整形器。如果想把一個 10Mbps 的連線整形成 1Mbps 的速率,就應該讓鏈路 90%的時間處於閒置狀態,必要的話就強制,以保證 90% 的閒置

Linux核心TC工具鏈路頻寬設計--HTB佇列規定

1 HTB(Hierarchical Token Bucket, 分層的令牌桶)       HTB 使用令牌和儲存桶的概念,以及基於類的系統和過濾器,以允許對流量進行復雜和精細的控制。藉助複雜的借用模型,HTB 可以執行各種複雜的流量控制技術。該佇列規則允

linux核心除錯環境搭建

版本linux4.17 ubuntu18.04先給系統至少80G記憶體1。編譯核心先配置檔案make mrpropermake menuconfig我這裡需要的依賴有 sudo apt install make cmake gcc g++ clang sudo apt-get install libnc

arm-linux-gdb除錯工具的安裝與交叉編譯gdbserver

arm-linux-gdb除錯工具的安裝與交叉編譯gdbserver 分類:嵌入式 開發環境:LPC3250 開發板:安裝linux2.6.39; 交叉編譯工具:arm-none-linux-gnueabi-gcc pc的虛擬機器:Linux version 2.6.32.

linux核心除錯方法

核心開發比使用者空間開發更難的一個因素就是核心除錯艱難。核心錯誤往往會導致系統宕機,很難保留出錯時的現場。除錯核心的關鍵在於你的對核心的深刻理解。 一  除錯前的準備 在除錯一個bug之前,我們所要做的準備工作有: 有一個被確認的bug。 包含這個bug的核心

Linux核心除錯方法總結

核心開發比使用者空間開發更難的一個因素就是核心除錯艱難。核心錯誤往往會導致系統宕機,很難保留出錯時的現場。除錯核心的關鍵在於你的對核心的深刻理解。  一  除錯前的準備 在除錯一個bug之前,我們所要做的準備工作有:  有一個被確認的bug。 包含這

linux核心除錯技巧四:gdb除錯+vmlinux

vmlinux是個elf檔案,它的符號表中包含了所有核心符號。 注意linux中很多檔案是沒有後綴的,比如我見到的這個elf檔案的檔名是“vmlinux-3.10.62”,沒有後綴。 既然是elf檔案

linux 核心除錯技術

核心開發比使用者空間開發更難的一個因素就是核心除錯艱難。核心錯誤往往會導致系統宕機,很難保留出錯時的現場。除錯核心的關鍵在於你的對核心的深刻理解。 一  除錯前的準備 在除錯一個bug之前,我們所要做的準備工作有: 有一個被確認的bug。 包含這個bug的核心版本號,需要分析出這個b

Linux核心除錯環境搭建(基於ubuntu12.04)

by Netfairy - 2016-05-29 一、測試環境 物理機:ubuntu16.04 LTS target(被除錯機)環境:VirtualBox 5.0.20+ubuntu 12.04 LTS + linux kernel 3.0.4 host

Linux核心除錯

#define    KERN_EMERG    "<0>"   /* system is unusable */#define    KERN_ALERT    "<1>"    /* action must be taken immediately    */#define    

Linux 核心除錯之 printk

問題描述:最近這兩天再除錯 platform 驅動,程式老是有點小問題,得不到自己想要的結果,突然意識到核心除錯重要性,重新整理一下 printk 基本用法。核心通過 printk() 輸出相關資訊

Linux核心除錯技術——jprobe使用與實現

前一篇博文介紹了kprobes的原理與kprobe的使用與實現方式,本文介紹kprobes中的第二種探測技術jprobe,它基於kprobe實現,不能在函式的任意位置插入探測點,只能在函式的入口處探測,一般用於監測函式的入參值。本文首先通過一個簡單的示例介紹jprobe的使

linux 核心除錯方法

kdb:只能在彙編程式碼級進行除錯;   優點是不需要兩臺機器進行除錯。   gdb:在除錯模組時缺少一些至關重要的功能,它可用來檢視核心的執行情況,包括反彙編核心函式。   kgdb:能很方便的在原始碼級對核心進行除錯,缺點是kgdb只能進行遠端除錯,它需要一根串列埠線及兩臺機器來除錯核心(也可以是在同一

linux核心除錯技巧三:kallsyms

kallsyms是linux的一個子系統,顧名思義,kernel_all_syms,也就是核心的所有符號。 kallsyms子系統的功能是把核心程式碼的所有符號(其實不是所有,沒仔細研究,不過重要的都

linux核心除錯+qemu+eclipse

一、除錯環境: 在ubuntu16.04下,在虛擬機器裡邊執行的ubuntu,裝32位的執行較快,選擇較新的ubuntu版本是因為安裝qemu、eclipse比較簡單,在安裝軟體上節約時間。 二、安裝