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.oKDIR=/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 dumpKernel 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比較簡單,在安裝軟體上節約時間。 二、安裝