Debugging gem5
原英文版在https://www.gem5.org/documentation/learning_gem5/part2/debugging
Using debug flags
除錯標誌用於debug。通常在gem5,不能使用 std::cout
,而應藉助除錯標誌進行輸出。
gem5透過可選的除錯標誌(--debug-flag
)提供printf風格的跟蹤/除錯支援。
用--debug-help
可獲取除錯標誌說明(啟用多種除錯標誌用逗號隔開)。
下面以Exec介紹一個例子
build/RISCV/gem5.opt --debug-flags=Exec configs/learning_gem5/part1/simple-riscv.py | head -n 50
Exec本身就是很多除錯標誌的集合
因為,debug輸出資訊很多,所以這裡只取前面一部分
Adding a new debug flag
-
建立新除錯標記時,我們首先要在 SConscript 檔案中宣告它。 將以下內容新增到包含 hello 物件程式碼的目錄(src/learning_gem5/SConscript中)。
DebugFlag('HelloExample')
-
透過在 SConscript 檔案中宣告除錯標誌,除錯標頭檔案會自動生成,允許我們使用除錯標誌。標頭檔案在./build/{ISA}/debug/HelloExample.hh除錯目錄中,其名稱(和大小寫)與我們在 SConscript 檔案中宣告的名稱相同。 因此,我們需要在任何計劃使用除錯標記的檔案中包含自動生成的標頭檔案。(記得修改後要重新構建一下
scons build/X86/gem5.opt
)#include "base/trace.hh" #include "debug/HelloExample.hh"
-
透過宏
DPRINTF
使用DPRINTF(HelloExample, "Created the hello object\n");
這裡需要解釋一下
DPRINTF
,宏展開如下。每次執行動態 DPRINTF 時,都會向 stdout 列印三項內容。 第一,執行 DPRINTF 時的當前刻度curTick()
。 第二,呼叫 DPRINTF 的模擬物件的名稱name()
。 該名稱通常是 Python 配置檔案中例項的名字,即SimObject name()
函式返回的名稱。 第三,是傳遞給 DPRINTF 函式的格式字串。#define DPRINTF(x,__VA_ARGS__...) do { if (GEM5_UNLIKELY(TRACING_ON && ::gem5::debug::x)) { ::gem5::trace::getDebugLogger()->dprintf_flag( ::gem5::curTick(), name(), #x, __VA_ARGS__); } } while (0) 擴充套件到: do { if (__builtin_expect(!!(TRACING_ON && ::gem5::debug::HelloExample), 0)) { ::gem5::trace::getDebugLogger()->dprintf_flag( ::gem5::curTick(), name(), "HelloExample", "Created the hello object\n"); } } while (0)
Debug output
預設情況下,所有除錯輸出都列印到 stdout。 也可以使用--debug-file
引數控制除錯輸出的位置,比如用以下命令
build/X86/gem5.opt --debug-flags=HelloExample --debug-file debug.txt xxx.py
輸出會重定向到./m5out/debug.txt
中。
Using functions other than DPRINTF
DPRINTF
是最常用的。此外gem5還有其他除錯功能,參考見https://doxygen.gem5.org/release/current/base_2trace_8hh.html
這些函式與之前的 :cppDDUMP、:cppDPRINTF 和 :cppDPRINTFR
函式類似,只是它們不將標誌作為引數。所有這些函式只有在以 "opt"或 "debug"模式編譯 gem5 時才會啟用。 所有其他模式都為上述函式使用空佔位符宏,因此,如果要使用除錯標記,必須使用 "gem5.opt "或 "gem5.debug"。