GDB 調(diào)試內(nèi)核模塊

1 利用virt-manager創(chuàng)建需要虛擬機(jī)

2 更換虛擬機(jī)的內(nèi)核到需要調(diào)試的內(nèi)核.

3 virsh edit <vm_name> 更改虛擬機(jī)配置,使其支持調(diào)試

<domain type='kvm' xmlns:qemu='[http://libvirt.org/schemas/domain/qemu/1.0'
<qemu:commandline> 
    <qemu:arg value='-s'/> 
 </qemu:commandline>

注意 只加-s 參數(shù)即可。
Qemu arg

4 拷貝虛擬機(jī)里的編譯好的內(nèi)核到宿主機(jī),并進(jìn)入 gdb 調(diào)試

scp -r linux-4.18.20 root@10.190.2.19:~
gdb vmlinux
target remote 127.0.0.1:1234

5 在 do_init_module 添加斷點(diǎn)并繼續(xù)執(zhí)行。

b do_init_module
c

6 在虛擬機(jī)上插入需要調(diào)試的模塊:

insmod progger_trace.ko

7 gdb 里打印 text section,data section 和 bss section 的名稱和地址:

 print mod->sect_attrs->attrs[1]->name 
 print mod->sect_attrs->attrs[7]->name 
 print mod->sect_attrs->attrs[9]->name 
 print /x mod->sect_attrs->attrs[1]->address 
 print /x mod->sect_attrs->attrs[7]->address 
 print /x mod->sect_attrs->attrs[9]->address

8 根據(jù)上面打印的地址導(dǎo)入編譯好的內(nèi)核模塊

add-symbol-file /root/progger/linux_progger/progger_trace.ko <text addr> -s .data <data addr> -s .bss <bss addr>

9 下面就可以在模塊代碼中添加斷點(diǎn)并單步調(diào)試了:

編譯內(nèi)核

yum groupinstall "Development Tools"
make menuconfig
make -j 4
make modules
make modules_install
sudo make install

錯(cuò)誤:

Remote 'g' packet reply is too long 錯(cuò)誤的原因
這個(gè)錯(cuò)誤是當(dāng)目標(biāo)程序執(zhí)行時(shí)發(fā)生模式切換(real mode 16bit -> protected mode 32bit -> long mode 64bit)的時(shí)候,gdb server(此處就是 qemu)發(fā)送了不同長(zhǎng)度的信息,gdb 無(wú)法正確的處理這種情況,所以直接就報(bào)錯(cuò)。 此時(shí)需要斷開(kāi)連接并切換 gdb 的 arch (i386:x86-64 和 i386:x86-64:intel ),arch 變化后,gdb 會(huì)重新設(shè)置緩沖區(qū),然后再連接上去就能正常調(diào)試。這個(gè)方法規(guī)避了一些麻煩,但是實(shí)際上有兩種正規(guī)的解決方案:
(1) 修改 gdb 的源碼,使 gdb 支持這種長(zhǎng)度變化(gdb 開(kāi)發(fā)者似乎認(rèn)為這個(gè)問(wèn)題應(yīng)該由 gdb server 解決).
(2) 修改 qemu 的 gdb server,始終發(fā)送 64bit 的消息(但是這種方式可能導(dǎo)致無(wú)法調(diào)試 real mode 的代碼)

解決方法:

1 修改gdb代碼,打patch。
2 # 斷開(kāi) gdb 的連接
  disconnect
  # 重新設(shè)置 arch
  # 此處設(shè)置和之前 show arch 的要不一樣
  # 之前是  i386:x86-64 于是改成  i386:x86-64:intel
  set arch i386:x86-64:intel

cannot access memory 解決方法主要看4
因?yàn)閮?nèi)核啟用這項(xiàng)特性之后,內(nèi)核啟動(dòng)時(shí)會(huì)隨機(jī)化內(nèi)核的各個(gè) section 的虛擬地址(VA),導(dǎo)致 gdb 斷點(diǎn)設(shè)置在錯(cuò)誤的虛擬地址上,內(nèi)核執(zhí)行時(shí)就不會(huì)觸發(fā)這些斷點(diǎn)。

可以更改/etc/grub2.conf 添加 nokasrl 命令參數(shù)。
然后`grub2-mkconfig -o /boot/grub2/grub.cfg`

或者取消 Processor type and features -> Build a relocatable kernel 
取消后 Build a relocatable kernel 的子項(xiàng) Randomize the address of the kernel image (KASLR) 也會(huì)一并被取消

參考:
1 https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2016/06/21/gdb-linux-kernel-by-qemu
2 https://linux.cn/article-9665-1.html
3 https://imkira.com/a21.html
4 https://stackoverflow.com/questions/44612822/why-gdb-cannot-find-the-source-lines-of-the-linux-kernel-when-debugging-through

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容