核心必須懂(六): 使用kgdb除錯核心

Sorrower發表於2019-04-17

核心必須懂(一): 用系統呼叫列印Hello, world!

核心必須懂(二): 檔案系統初探

核心必須懂(三): 重編Ubuntu18.04LTS核心4.15.0

核心必須懂(四): 撰寫核心驅動

核心必須懂(五): per-CPU變數

核心必須懂(六): 使用kgdb除錯核心


目錄

  • 前言
  • 虛擬機器串列埠設定
  • 測試串列埠
  • 配置目標機
  • 開始除錯
  • 除錯驅動模組
  • 最後

前言

除錯核心肯定不是什麼輕鬆的事情, 這裡是使用kgdb進行除錯, 你理解的沒錯, 就是kernel版的gdb.


虛擬機器串列埠設定

首先克隆下已經重新編譯核心的虛擬機器 然後設定兩者的串列埠, 這裡是用的win, mac端的串列埠我暫時還弄不太好, 所以很不情願地用了下win:

  • 開發機

開發機串列埠設定

  • 目標機

目標機串列埠設定


測試串列埠

目標機執行:

sudo cat /dev/ttyS1
複製程式碼

核心必須懂(六): 使用kgdb除錯核心

開發機切換成root使用者, 執行:

echo “Hello, world!”>/dev/ttyS1
複製程式碼

核心必須懂(六): 使用kgdb除錯核心


配置目標機

開啟grub檔案:

sudo vim /etc/default/grub
複製程式碼

增加如下內容:

GRUB_CMDLINE_LINUX="nokaslr rootdelay=90quiet splash text kgdboc=ttyS1,115200“
複製程式碼

核心必須懂(六): 使用kgdb除錯核心

更新grub:

sudo update-grub
複製程式碼

nokaslr, 禁止核心地址隨機化, 具體內容請自行google:

reboot
複製程式碼

然後重啟的時候, 就能夠看到一行關於nokaslr的提示了.


開始除錯

然後開始測試一下kgdb的除錯, 目標機切換為root使用者, 控制許可權交給kgdb, 目標機進入假死狀態:

echo g > /proc/sysrq-trigger
複製程式碼

開發機進入自編譯核心目錄

gdb ./vmlinux
target remote /dev/ttyS1
handle SIGSEGV noprint nostop pass
break sys_clone
c
s
複製程式碼

核心必須懂(六): 使用kgdb除錯核心

這裡把斷點給到sys_clone, 就是大家熟悉的fork會呼叫的, 這樣基本等一會, 系統就自己呼叫, 然後進入除錯了. 之後就和使用gdb無異了:

核心必須懂(六): 使用kgdb除錯核心

核心必須懂(六): 使用kgdb除錯核心


除錯驅動模組

要除錯自己的寫的驅動模組, 就有些麻煩了, 首先需要常規的插入模組, 不多說了. 然後這裡有個shell指令碼可以獲取下一些所需引數, 主要是用來插入符號引數:

#!/bin/bash
#
# usage: gdbline.sh module_name module_path
#
# This script will outputs an add-symbol-file line suitable for pasting into gdb to examine
# a loaded module.
#
cd /sys/module/$1/sections
echo -n add-symbol-file $2 `/bin/cat .text`
for section in .[a-z]* *; do
	if [ $section != ".text" ]; then
echo " \\"
echo -n " -s" $section `/bin/cat $section` 
	fi
done
echo
複製程式碼

首先, 需要在目標機make生成.ko檔案, 然後將這個.ko檔案拷貝至開發機的同名目錄下.
然後在目標機插入.ko檔案 用shell指令碼獲取.text, .data, .bss段基址. 如果你不太清楚這些東西, 還是請自行google, 因為如果展開, 篇幅就控制不住了.

核心必須懂(六): 使用kgdb除錯核心

目標機切換為root使用者, 控制許可權交給kgdb, 目標機進入假死狀態:

echo g > /proc/sysrq-trigger
複製程式碼

開發機進入自編譯核心目錄

gdb ./vmlinux
target remote /dev/ttyS1
handle SIGSEGV noprint nostop pass
複製程式碼

常規操作之前也說了, 然後就是新的操作, 要用add-symbol-file插入符號資訊, 然後輸入y確認:

核心必須懂(六): 使用kgdb除錯核心

然後把斷點打在模組函式DriverWrite中, 開始執行:

核心必須懂(六): 使用kgdb除錯核心

切回目標機, 已經不是假死了, 執行使用者態程式:

核心必須懂(六): 使用kgdb除錯核心

然後開發機就會觸發斷點:

核心必須懂(六): 使用kgdb除錯核心

接下來就和平常使用gdb除錯一樣了.


最後

如果要寫驅動模組, 必須要除錯核心, 上述方法並不是唯一方法. 下一篇將會介紹一些更實用的小工具來進行類似的除錯. 喜歡記得點贊, 有意見或者建議評論區見哦~


相關文章