使用 QEMU 對核心進行偵錯

Zircon 可使用 QEMU,在模擬時執行。可以透過以下方法安裝 QEMU: 預先建構的二進位檔,或在本機建構的二進位檔。

預先建構的 QEMU

jiri 下載為 jiri updatejiri run-hooks 的一部分。

QEMU 會擷取至 //prebuilt/third_party/qemu。您最多可以執行 輕鬆使用 fx qemu (請參閱下文)。

建構 QEMU

cd $SRC
git clone --recursive https://fuchsia.googlesource.com/third_party/qemu
cd qemu
./configure --target-list=aarch64-softmmu,x86_64-softmmu
make -j32
sudo make install

如果不想安裝在 /usr/local (預設),系統會規定 新增到根目錄,新增 --prefix=/path/to/install (或許 $HOME/qemu)。接著 必須將 /path/to/install/bin 新增至 PATH 或使用 -q /path/to/install 當叫用 run-zircon-{arch} 時。

在 QEMU 下執行 Zircon

# for aarch64
fx set bringup.arm64
fx build
fx qemu

# for x86
fx set bringup.x64
fx build
fx qemu

如果路徑上沒有 QEMU,請使用 -q 指定其位置。

-h 旗標會列出多個選項,包括 -b 等重建選項 優先,而 -g 以圖形框架緩衝區執行。

如要退出 qemu,請輸入 Ctrl-a x。按下 Ctrl + a h 可查看其他指令。

在 QEMU 下啟用網路

指定 -N 引數時,run-zircon 指令碼會嘗試建立 透過 Linux Tun/tap 網路裝置使用「qemu」網路介面QEMU 不需要以任何特殊權限執行這個程式碼,但您必須 及預先建立永久色調/輕觸裝置 (這需要取得 Root 權限):

sudo ip tuntap add dev qemu mode tap user $USER
sudo ip link set qemu up

這樣就能啟用連結本機 IPv6 (與記錄監聽器工具一樣)。

依 QEMU 使用模擬磁碟

使用以核心為基礎 (尤其是高於啟動的任何產品) 的建構版本,將會 會自動隱含為提供 fvm 分區的磁碟 包含可變動儲存空間的 minfs 分區,以及 blobf 分區 套件資料儲存空間

您可以使用下列旗標附加其他圖片:

fx qemu -d [-D <disk_image_path (default: "blk.bin")>]

使用 GDB 對核心偵錯

範例工作階段

在此提供一個範例課程,協助您快速上手。

使用殼層執行 QEMU 時,程式碼如下:

shell1$ fx qemu -- -s -S
[... some QEMU start up text ...]

這會啟動 QEMU,但系統會在啟動時凍結系統。 正在等待您繼續作業,按下 [繼續]。 如要在不使用 GDB 的情況下執行 QEMU,但之後也能與 GDB 連結 然後在不使用「-S」的情況下啟動 QEMU在上述範例中:

shell1$ fx qemu -- -s
[... some QEMU start up text ...]

然後在 out 目錄中找出 zircon.elf

接著,在殼層中執行 GDB:

shell2$ gdb path-to-zircon.elf -x ${FUCHSIA_DIR}/zircon/kernel/scripts/zircon.elf-gdb.py
Reading symbols from /fuchsia/out/default/kernel_x64-clang/zircon.elf...
Loading zircon.elf-gdb.py ...
Zircon extensions installed for /fuchsia/out/default/kernel_x64-clang/zircon.elf
(gdb) target extended-remote :1234
Remote debugging using :1234
0x000000000000fff0 in ?? ()

Thread 1 hit Breakpoint -1, 0x0000000000100050 in ?? ()
Watchpoint set on KASLR relocated base variable

Thread 1 hit Hardware read watchpoint -2: *0x767ca0

Value = 0
0x00000000001000ef in ?? ()
Update symbols and breakpoints for KASLR
KASLR: Correctly reloaded kernel at 0xffffffff00000000
(gdb) # Don't try to do too much at this point.
(gdb) # GDB can't handle architecture switching in one session,
(gdb) # and at this point the architecture is 16-bit x86.
(gdb) break lk_main
Breakpoint 1 at 0xfffffffff010cb58: file kernel/top/main.c, line 59.
(gdb) continue
Continuing.

Breakpoint 1, lk_main (arg0=1, arg1=18446744071568293116, arg2=0, arg3=0)
    at kernel/top/main.c:59
59  {
(gdb) continue

此時,Zircon 啟動並返回 Shell1 時,您會處於 Zircon 提示。

mxsh>

如果這時在 Shell2 中按下 Ctrl-C 鍵,可以返回 GDB。

(gdb) # Having just done "continue"
^C
Program received signal SIGINT, Interrupt.
arch_idle () at kernel/arch/x86/64/ops.S:32
32      ret
(gdb) info threads
  Id   Target Id         Frame
  4    Thread 4 (CPU#3 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
  3    Thread 3 (CPU#2 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
  2    Thread 2 (CPU#1 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
* 1    Thread 1 (CPU#0 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32

QEMU 會針對每個 CPU 向 GDB 回報一個執行緒。

zircon.elf-gdb.py 指令碼

zircon/kernel/scripts/zircon.elf-gdb.py 指令碼應該由 gdb 自動載入。如果是 時,您可能需要將路徑新增至 gdb 的 auto-load-safe-path, 或者,您也可以在 gdb 的指令列標記中手動設定。

$ gdb path-to-zircon.elf -x ${FUCHSIA_DIR}/zircon/kernel/scripts/zircon.elf-gdb.py

此模式提供以下功能:

  • 為 gdb 重新定位 KASLR,讓您能正確設定函式中的中斷點。

  • 適用於 Zircon 物件的美化印表機 (目前無人提供)。

  • 多個 Zircon 特定指令,所有指令都包含「zircon」前置字串。查看方式如下:

(gdb) help info zircon
(gdb) help set zircon
(gdb) help show zircon
  • 加強瞭解開器支援,透過核心錯誤提供自動放鬆功能。

請注意:這個指令碼不一定會隨著 Zircon 變更而更新。

注意:由於錯誤 67893,KASLR 部分可能無法順利搭配 kvm 使用 qemu。 如要解決這個問題,您可以在 gdb 中執行下列程式碼:

(gdb) # before attaching to qemu
(gdb) mem 0 0xffffffffffffffff ro
(gdb) target extended-remote :1234
(gdb) ...
(gdb) # after the script performed the kaslr relocations
(gdb) mem auto

正在終止工作階段

如要終止 QEMU,您可以透過 GDB 傳送指令給 QEMU:

(gdb) monitor quit
(gdb) quit

透過 Gdb 與 QEMU 互動

如要查看可從 GDB 執行的 QEMU 指令清單:

(gdb) monitor help

正在儲存系統狀態以便偵錯

發生難以偵錯或需要協助的當機問題 偵錯也可以將系統狀態依核心傾印儲存至核心傾印

bash$ qemu-img create -f qcow2 /tmp/my_snapshots.qcow2 32M

將建立「3,200」區塊儲存裝置下次啟動 QEMU 並告訴大家 ,但不要告訴裝置如何將裝置連接至訪客系統。 這沒問題;我們不打算用它來備份磁碟狀態 以及核心傾印注意:如果您已在模擬環境中 並使用 qcow2 格式

bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2

到了要儲存核心狀態的時間點時,請將該選項拖曳至 QEMU 使用 存取控制台。此時您應該會收到 (qemu) 提示。 接著說出:

(qemu) savevm my_backup_tag_name

之後,再從相同的機器 (一台使用與之前相同的引數啟動) 中啟動 可以直接前往控制台並執行

(qemu) loadvm my_backup_tag_name

還原狀態或者,您也可以從 cmd 行中執行以下操作:

bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2 -loadvm my_backup_tag_name

理論上,您可以將 qcow2 映像檔與建構輸出內容封裝在一起 目錄,那麼任何人都應該要能還原您的狀態並開始提供服務 在 QEMU 控制台中運作