檢查 zxdb 中的記憶體

Zxdb 支援下列指令來檢查記憶體:

aspace:顯示對應記憶體區域。

aspace 指令是縮寫的 as,會輸出程序的位址空間資訊。在法國,虛擬記憶體是由虛擬記憶體物件 (VMO) 階層組成。

如果沒有參數,aspace 指令會顯示程序中所有 VMO。

[zxdb] as

如果有指定位址,aspace 指令會顯示只包含該位址的 VMO 階層。這有助於判斷位址在記憶體中的位置,因為 VMO 的名稱通常表示該區域類型。

[zxdb] as 0x10b7f304d28

瞭解輸出內容

在以下範例中,aspace 指令會詳細資料 0x10b7f304d28 位址的相關資訊:

  • 包含位址的 VMO 階層。
  • 每個 VMO 的位址和大小。
  • 每個 VMO 的名稱,可對其用途提供線索。
    • 透過這個範例的名稱,您可以知道位址位於由 pthread 分配的堆疊中。
          Start              End   Size  Koid    Offset  Com.Pgs  Name
      0x1000000   0x7ffffffff000   127T                           proc:3109
      0x1000000   0x7ffffffff000   127T                             root
  0x10b7f104000    0x10b7f305000     2M                               useralloc
  0x10b7f105000    0x10b7f305000     2M  3824       0x0        2        pthread_t:0x10c4ea38b00

以下是可納入 aspace 指令輸出內容中的相關 VMO 名稱:

  • initial-thread:啟動執行緒的堆疊。
  • pthread_t:0x...:透過 pthread 建立的執行緒的堆疊。該位址會指出該執行緒「pthread_t」結構的記憶體位置。
  • *uncompressed-bootfs:來自啟動檔案系統 (核心系統程式庫) 的記憶體對應程式庫。libs 指令可顯示該位址的程式庫名稱。
  • stack: msg of ...:啟動堆疊。這個非常小型的堆疊僅用於動態連結器和載入器程式碼。
  • scudo:*:使用快照記憶體管理工具分配的頁面。如果這個程序使用 Scudo,這些區域就是應用程式的堆積。
  • vdso/next:實作下一個系統呼叫的內建程式庫。
  • vdso/stable:實作穩定系統呼叫的內建程式庫。
  • blob-*:對應程式庫,來自 blobf。libs 指令可顯示該位址的程式庫名稱。

如要進一步瞭解 VMO,請使用下列指令:handle -k <koid>

「Cmt.Pgs」欄會顯示對應 VMO 中該記憶體區域內的修訂頁面數量 (非位元組)。對於 blob 等記憶體對應檔案 (例如 blob 和其他共用 VMO) 而言,這個問題可能會令人感到意外。

如果 VMO 為子項 (例如對應的 blob),原始資料將出現在父項 VMO 中,但實際對應的子項 VMO 則會間接參照這項資料。子項中唯一會計為已修訂的頁面,是因寫入時複製而重複的網頁。因此,未修改的 blob 和其他未修改的檔案不會有確認頁數。

mem-analyze:傾印記憶體,嘗試解讀指標。

這個指令會嘗試將記憶體解讀為指標,並解碼其指向的內容。具有對應符號的地址會符號化,其他地址則會指出所屬記憶體對應區域的名稱 (請參閱 aspace 指令)。轉儲不明記憶體時可能非常有用。

[zxdb] ma 0x42ff9c2fdd30
       Address               Data
0x42ff9c2fdd30 0x00000000000015f0
0x42ff9c2fdd38 0x0000000000000008
0x42ff9c2fdd40 0x000042f401a8a730 ▷ ldso
0x42ff9c2fdd48 0x000042f401a8a9f8 ▷ $(dls3.app)
0x42ff9c2fdd50 0x0000000000000053
0x42ff9c2fdd58 0x0000000010469c6b
0x42ff9c2fdd60 0x000042f401a8a9f8 ▷ $(dls3.app)
0x42ff9c2fdd68 0x0000000000000000
0x42ff9c2fdd70 0x000042ff9c2fde70 ▷ inside map "stack: msg of 0x1000"
0x42ff9c2fdd78 0x000042f4015e5548 ▷ dls3 + 0x42b
0x42ff9c2fdd80 0x10469c6b10769c7b
0x42ff9c2fdd88 0x10569c3310469c23
0x42ff9c2fdd90 0x10469c2710469c37

另請參閱 stack,這是用於堆疊分析的 mem-analyze 指令變化版本。

mem-read:傾印程序記憶體

mem-read 指令是縮寫的 x,提供指定位址的十六進位傾印。您需要提供位址,並視情況使用 -s 選項覆寫預設大小。

[zxdb] x -s 100 0x42ff9c2fdd30
0x42ff9c2fdd30:  f0 15 00 00 00 00 00 00-08 00 00 00 00 00 00 00  |
0x42ff9c2fdd40:  30 a7 a8 01 f4 42 00 00-f8 a9 a8 01 f4 42 00 00  |0    B       B
0x42ff9c2fdd50:  53 00 00 00 00 00 00 00-6b 9c 46 10 00 00 00 00  |S       k F
0x42ff9c2fdd60:  f8 a9 a8 01 f4 42 00 00-00 00 00 00 00 00 00 00  |     B
0x42ff9c2fdd70:  70 de 2f 9c ff 42 00 00-48 55 5e 01 f4 42 00 00  |p /  B  HU^  B
0x42ff9c2fdd80:  7b 9c 76 10 6b 9c 46 10-23 9c 46 10 33 9c 56 10  |{ v k F # F 3 V 
0x42ff9c2fdd90:  37 9c 46 10

您也可以提供一個評估為地址的運算式。如果指標的類型具有已知大小,傾印會自動顯示許多位元組:

[zxdb] x &self->main_waker
0x1605a5d1ed0:  70 1a c8 36 47 04 00 00-68 fe 3d dd 25 01 00 00  |p  6G   h = %

stack-data:提供低階堆疊分析

stack-data 指令會以類似 mem-analyze 的方式分析堆疊。該元件預設為在目前執行緒堆疊的頂端。stack-data 指令會嘗試解碼記憶體區域中存在的地址,但也會新增執行緒已知註冊值和堆疊基本指標的註解。

[zxdb] stack-data
      Address               Data
0x1605a5d1428 0x000042a352fca11f ◁ rsp. ▷ _zx_port_wait + 0x1f
0x1605a5d1430 0x000001605a5d1460 ◁ frame 1 rsp. ▷ inside map "initial-thread"
0x1605a5d1438 0x000001605a5d1540 ▷ inside map "initial-thread"
0x1605a5d1440 0x7fffffffffffffff
0x1605a5d1448 0x0000044ab6c81800 ▷ inside map "scudo:primary"
0x1605a5d1450 0x000001605a5d14d0 ◁ rbp, frame 1 base. ▷ inside map "initial-thread"
0x1605a5d1458 0x00000125dd3566f5 ▷ fuchsia_zircon_status::Status::ok
0x1605a5d1460 0x0000000000000000 ◁ frame 2 rsp
0x1605a5d1468 0x0000000000000000
0x1605a5d1470 0x0000000000000000
0x1605a5d1478 0x0000000000000000
0x1605a5d1480 0x0000000000000000 ◁ rdx, r14

在附註欄中,向左指向的箭頭表示哪個註冊點指向該堆疊位置,向右箭頭表示堆疊進入點的值會將其解讀為地址。

sym-near:將地址對應至符號

sym-near 指令 (縮寫為 sn) 會嘗試將地址對應至符號名稱。執行指令會輸出地址上或之前的符號名稱和行資訊 (如有),最常用於指出指標指向的意義。

[zxdb] sym-near 0x125dd3a845e
0x125dd3a845e, power_manager::main() • main.rs:37