<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 GDB + Qemu 調(diào)試 Linux 內(nèi)核

          共 5186字,需瀏覽 11分鐘

           ·

          2021-12-01 10:13

          1. 概述

          在某些情況下,我們需要對(duì)于內(nèi)核中的流程進(jìn)行分析,雖然通過(guò) BPF 的技術(shù)可以對(duì)于函數(shù)傳入的參數(shù)和返回結(jié)果進(jìn)行展示,但是在流程的調(diào)試上還是不如直接 GDB 單步調(diào)試來(lái)的直接。本文采用的編譯方式如下,在一臺(tái) 16 核 CentOS 7.7 的機(jī)器上進(jìn)行內(nèi)核源碼相關(guān)的編譯(主要是考慮編譯效率),調(diào)試則是基于 VirtualBox 的 Ubuntu 20.04 系統(tǒng)中,采用 Qemu + GDB 進(jìn)行單步調(diào)試,網(wǎng)上查看了很多文章,在最終進(jìn)行單步跟蹤的時(shí)候,始終不能夠在斷點(diǎn)處停止,進(jìn)行過(guò)多次嘗試和查詢文檔,最終發(fā)現(xiàn)需要在內(nèi)核啟動(dòng)參數(shù)上添加?nokaslr?,本文是對(duì)整個(gè)搭建過(guò)程的總結(jié)。

          2. Linux 內(nèi)核編譯和文件系統(tǒng)制作

          2.1 Linux 內(nèi)核編譯

          編譯內(nèi)核和制作文件系統(tǒng)在 CentOS 7.7 的機(jī)器上。源碼從國(guó)內(nèi)清華的源下載:http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/, 此處選擇 linux-4.19.172.tar.gz 版本。詳細(xì)編譯步驟如下:

          $?sudo?yum?group?install?"Development?Tools"
          $?yum?install?ncurses-devel?bison?flex?elfutils-libelf-devel?openssl-devel
          ?
          $?wget?http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v4.x/linux-4.19.172.tar.gz
          $?tar?xzvf?linux-4.19.172.tar.gz
          $?cd?linux-4.19.172/
          $?make?menuconfig

          在內(nèi)核編譯選項(xiàng)中,開啟如下 “Compile the kernel with debug info”, 4.19.172 中默認(rèn)已經(jīng)選中:

          Kernel hacking —> Compile-time checks and compiler options —> [ ] Compile the kernel with debug info


          以上配置完成后會(huì)在當(dāng)前目錄生成?.config?文件,我們可以使用?grep?進(jìn)行驗(yàn)證:

          #?grep?CONFIG_DEBUG_INFO?.config
          CONFIG_DEBUG_INFO=y

          接著我們進(jìn)行內(nèi)核編譯:

          ?$?nproc???????#?查看當(dāng)前的系統(tǒng)核數(shù)
          ?$?make?-j?12??#?或者采用?make?bzImage?進(jìn)行編譯,?-j?N,表示使用多少核并行編譯
          ?
          ?#?未壓縮的內(nèi)核文件,這個(gè)在?gdb?的時(shí)候需要加載,用于讀取?symbol?符號(hào)信息,由于包含調(diào)試信息所以比較大
          ?$?ls?-hl?vmlinux?
          -rwxr-xr-x?1?root?root?449M?Feb??3?14:46?vmlinux

          #?壓縮后的鏡像文件?
          $?ls?-hl?./arch/x86_64/boot/bzImage
          lrwxrwxrwx?1?root?root?22?Feb??3?14:47?./arch/x86_64/boot/bzImage?->?../../x86/boot/bzImage

          $?ls?-hl?./arch/x86/boot/bzImage
          -rw-r--r--?1?root?root?7.6M?Feb??3?14:47?./arch/x86/boot/bzImage

          不同發(fā)行版本下的內(nèi)核的詳細(xì)編譯文檔可以參考這里。

          2.2 啟動(dòng)內(nèi)存文件系統(tǒng)制作

          #?首先安裝靜態(tài)依賴,否則會(huì)有報(bào)錯(cuò),參見后續(xù)的排錯(cuò)章節(jié)
          $?yum?install?-y?glibc-static.x86_64?-y

          $?wget?https://busybox.net/downloads/busybox-1.32.1.tar.bz2
          $?tar?-xvf?busybox-1.32.1.tar.bz2
          $?cd?busybox-1.32.1/

          $?make?menuconfig

          #?安裝完成后生成的相關(guān)文件會(huì)在?_install?目錄下
          $?make?&&?make?install???

          $?cd?_install
          $?mkdir?proc
          $?mkdir?sys
          $?touch?init??

          #??init?內(nèi)容見后續(xù)章節(jié),為內(nèi)核啟動(dòng)的初始化程序
          $?vim?init???

          #?必須設(shè)置成可執(zhí)行文件
          $?chmod?+x?init??

          $?find?.?|?cpio?-o?--format=newc?>?./rootfs.img
          cpio:?File?./rootfs.img?grew,?2758144?new?bytes?not?copied
          10777?blocks

          $?ls?-hl?rootfs.img
          -rw-r--r--?1?root?root?5.3M?Feb??2?11:23?rootfs.img

          其中上述的?init?文件內(nèi)容如下,打印啟動(dòng)日志和系統(tǒng)的整個(gè)啟動(dòng)過(guò)程花費(fèi)的時(shí)間:

          #!/bin/sh
          echo?"{==DBG==}?INIT?SCRIPT"
          mkdir?/tmp
          mount?-t?proc?none?/proc
          mount?-t?sysfs?none?/sys
          mount?-t?debugfs?none?/sys/kernel/debug
          mount?-t?tmpfs?none?/tmp

          mdev?-s?
          echo?-e?"{==DBG==}?Boot?took?$(cut?-d'?'?-f1?/proc/uptime)?seconds"

          #?normal?user
          setsid?/bin/cttyhack?setuidgid?1000?/bin/sh

          到此為止我們已經(jīng)編譯了好了 Linux 內(nèi)核(vmlinux 和 bzImage)和啟動(dòng)的內(nèi)存文件系統(tǒng)(rootfs.img)。

          2.3 錯(cuò)誤排查

          在編譯過(guò)程中出現(xiàn)以下報(bào)錯(cuò):

          /bin/ld:?cannot?find?-lcrypt
          /bin/ld:?cannot?find?-lm
          /bin/ld:?cannot?find?-lresolv
          /bin/ld:?cannot?find?-lrt
          collect2:?error:?ld?returned?1?exit?status
          Note:?if?build?needs?additional?libraries,?put?them?in?CONFIG_EXTRA_LDLIBS.
          Example:?CONFIG_EXTRA_LDLIBS="pthread?dl?tirpc?audit?pam"

          出錯(cuò)的原因是因?yàn)槲覀儾捎渺o態(tài)編譯依賴的底層庫(kù)沒(méi)有安裝,如果不清楚這些庫(kù)有哪些 rpm 安裝包提供,則可以通過(guò)?yum provides?命令查看,然后安裝相關(guān)依賴包重新編譯即可。

          $?yum?provides?*/libm.a
          //?...
          glibc-static-2.17-317.el7.x86_64?:?C?library?static?libraries?for?-static?linking.
          Repo????????:?base
          Matched?from:
          Filename????:?/usr/lib64/libm.a

          3. Qemu 啟動(dòng)內(nèi)核

          在上述步驟準(zhǔn)備好以后,我們需要在調(diào)試的 Ubuntu 20.04 的系統(tǒng)中安裝 Qemu 工具,其中調(diào)測(cè)的 Ubuntu 系統(tǒng)使用 VirtualBox 安裝。

          $?apt?install?qemu?qemu-utils?qemu-kvm?virt-manager?libvirt-daemon-system?libvirt-clients?bridge-utils

          把上述編譯好的 vmlinux、bzImage、rootfs.img 和編譯的源碼拷貝到我們當(dāng)前 Unbuntu 機(jī)器中。

          拷貝 Linux 編譯的源碼主要是在 gdb 的調(diào)試過(guò)程中查看源碼,其中 vmlinux 和 linux 源碼處于相同的目錄,本例中 vmlinux 位于 linux-4.19.172 源目錄中。

          $?qemu-system-x86_64?-kernel?./bzImage?-initrd??./rootfs.img?-append?"nokaslr?console=ttyS0"?-s?-S?-nographic

          使用上述命令啟動(dòng)調(diào)試,啟動(dòng)后會(huì)停止在界面處,并等待遠(yuǎn)程 gdb 進(jìn)行調(diào)試,在使用 GDB 調(diào)試之前,可以先使用以下命令進(jìn)程測(cè)試內(nèi)核啟動(dòng)是否正常。

          qemu-system-x86_64?-kernel?./bzImage?-initrd??./rootfs.img?-append?"nokaslr?console=ttyS0"?-nographic

          其中命令行中各參數(shù)如下:

          • -kernel ./bzImage:指定啟用的內(nèi)核鏡像;

          • -initrd ./rootfs.img:指定啟動(dòng)的內(nèi)存文件系統(tǒng);

          • -append "nokaslr console=ttyS0"?:附加參數(shù),其中?nokaslr?參數(shù)必須添加進(jìn)來(lái),防止內(nèi)核起始地址隨機(jī)化,這樣會(huì)導(dǎo)致 gdb 斷點(diǎn)不能命中;參數(shù)說(shuō)明可以參見這里。

          • -s?:監(jiān)聽在 gdb 1234 端口;

          • -S?:表示啟動(dòng)后就掛起,等待 gdb 連接;

          • -nographic:不啟動(dòng)圖形界面,調(diào)試信息輸出到終端與參數(shù)?console=ttyS0?組合使用;

          4. GDB 調(diào)試

          在使用?qemu-system-x86_64?命令啟動(dòng)內(nèi)核以后,進(jìn)入到我們從編譯機(jī)器上拷貝過(guò)來(lái)的 Linux 內(nèi)核源代碼目錄中,在另外一個(gè)終端我們來(lái)啟動(dòng) gdb 命令:

          [linux-4.19.172]$?gdb?
          (gdb)?file?vmlinux???????????#?vmlinux?位于目錄?linux-4.19.172?中
          (gdb)?target?remote?:1234
          (gdb)?break?start_kernel?????#?有些文檔建議使用?hb?硬件斷點(diǎn),我在本地測(cè)試使用?break?也是?ok?的
          (gdb)?c???????????? ?#?啟動(dòng)調(diào)試,則內(nèi)核會(huì)停止在?start_kernel?函數(shù)處

          整體運(yùn)行界面如下:

          5. Eclipse 圖像化調(diào)試

          我們可以通過(guò) eclipse-cdt 進(jìn)行可視化項(xiàng)目調(diào)試。

          ”File“ -> “New” -> “Project” ,然后選擇 ”Makefile Project with Existing Code“ 選項(xiàng),后續(xù)按照向?qū)?dǎo)入代碼。

          在 “Run” -> “Debug Configurations” 選項(xiàng)中,創(chuàng)建一個(gè) ”C/C++ Attach to Application“ 的調(diào)試選項(xiàng)。

          • Project:選擇我們剛才創(chuàng)建的項(xiàng)目名字;

          • C/C++ Application:選擇編譯 Linux 內(nèi)核帶符號(hào)信息表的 vmlinux;

          • Build before launching:選擇 ”Disable auto build“;

          • Debugger:選擇 gdbserver,具體設(shè)置如下圖;

          • 在 Debugger 中的 Connection 信息中選擇 ”TCP“,并填寫端口為 ”1234“;

          啟動(dòng) Debug 調(diào)試,即可看到與 gdb 類似的窗口。

          啟動(dòng) ”Debug“ 調(diào)試以后的窗口如下,在 Debug 窗口欄中,設(shè)置與 gdb 調(diào)試相同的步驟即可。

          6. 參考

          • How to compile and install Linux Kernel 5.6.9 from source code

          • 用qemu + gdb調(diào)試linux內(nèi)核?***

          • QEMU+busybox 搭建Linux內(nèi)核運(yùn)行環(huán)境?***

          • QEMU+gdb調(diào)試Linux內(nèi)核全過(guò)程?*

          • linux內(nèi)核編譯與調(diào)試方法

          • How to Build A Custom Linux Kernel For Qemu (2015 Edition)

          • qemu與qemu-kvm到底什么區(qū)別

          • 在qemu環(huán)境中用gdb調(diào)試Linux內(nèi)核?*

          原文:https://www.ebpf.top/post/qemu_gdb_busybox_debug_kernel/

          瀏覽 49
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美一级毛片久久99精品蜜桃 | SM在线观看免费版 | 亚洲欧洲视频在线观看 | 性视频午夜男女 | a 视频在线观看 |