Skip to content

基础调试宏

古话

中国有句古话,叫做 ~~识~~ 工欲善其事,必先利其器

Uefi

不定义 MDEPKG_NDEBUG

  • ASSERT -> 断言
  • DEBUG -> 打印调试信息

配置

  • src/boot/SigmaBootPkg/Boot.dsc
[LibraryClasses]
    !if $(DBG_PRINT)
     DebugLib                    | MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
     DebugPrintErrorLevelLib     | MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
    !else
     DebugLib                    | MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
    !endif

[PcdsFixedAtBuild]
    !if $(DBG_PRINT)
     gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask       |0x02
     gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel    |0x80000040
    !endif

这里涉及到两个 PCD 变量

PCD 全名为 Platform Configuration Database, 它是一种数据库,用于存储在 Uefi 下可访问的数据, 类似于 Windows 上的注册表 --《Uefi编程实践》 罗冰 著

PcdDebugPropertyMask

控制Debug行为

  • PcdDebugPropertyMask - Bit mask to determine which features are on/off
  • PcdDebugPrintErrorLevel - Types of messages produced

开启则它为对应行为的掩码相与(不为0)

1
2
3
4
5
6
7
8
/* File : Edk2/MdePkg/Include/Library/DebugLib.h */

#define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED       0x01
#define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED        0x02
#define DEBUG_PROPERTY_DEBUG_CODE_ENABLED         0x04
#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED       0x08
#define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED  0x10 // 断言失败后触发第3号异常 (#BP)
#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED    0x20 // 断言失败后进入死循环, 实际断点优先

For example:

控制 DEBUG_PROPERTY_DEBUG_PRINT_ENABLEDDEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 开启,则它的值为 (0x02 | 0x01) 也可以写成: 0x3

PcdDebugPrintErrorLevel

#define DEBUG_INIT      0x00000001  // Initialization
#define DEBUG_WARN      0x00000002  // Warnings
#define DEBUG_LOAD      0x00000004  // Load events
#define DEBUG_FS        0x00000008  // EFI File system
#define DEBUG_POOL      0x00000010  // Alloc & Free (pool)
#define DEBUG_PAGE      0x00000020  // Alloc & Free (page)
#define DEBUG_INFO      0x00000040  // Informational debug messages

...

#define DEBUG_ERROR     0x80000000  // Error

/* Debug message bit masks的别名,
   出于历史缘故以及兼容性考虑    */
#define EFI_D_INIT      DEBUG_INIT
...

于是调整 PcdDebugPrintErrorLevel 将控制 DebugPrint() 的输出.

DEBUG

DEBUG ((ErrorLevel, Format, ...));

使用 char8* 的 Fotmat

  • %r -> EFI_STATUS
  • %a -> char8[] ASCII
  • %s -> char16[] UCS-2

ASSERT

ASSERT (Expression);

ASSERT (FALSE)时执行指定操作

  • DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED 0x10 -> 调试断点
  • DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20 -> 死循环

My own

  • ERR_RET(Status) -> 错误时返回
  • ERR_RETS(Status) -> 错误时返回Status