31.4.1 Configuring DebugLib with EDK II
The EDK II provides several methods to manage the DebugLib macros. These include:
- DebugLib library instances
- DebugLib Platform Configuration Database (PCD) settings
MDEPKG_NDEBUGis defined when a UEFI Driver is built, then all the
DebugLibmacros used by a UEFI Driver are removed. This provides a smaller executable, but all debug log messages, assert condition checks, and debug code are removed from the UEFI Driver that is produced by the EDK II build. The example below shows the addition of a
[BuildOptions]section to the DSC files from Chapter 30. It forces
MDEPKG_NDEBUGto be defined for
RELEASEbuilds, which means all the
DebugLibmacros are disabled when the
-b RELEASEflag is used when building a UEFI Driver.
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
MdePkgprovides 4 different implementations of the
DebugLiblibrary class. These are:
BaseDebugLibNullis an implementation of the
DebugLibwith empty worker functions. This means the
DebugLibmacros are mapped to empty worker functions, so if the library instances is used by a UEFI Driver, no debug log messages, assert condition checks, or debug code are active. Using this library mapping is not as small as using
MDEPKG_NDEBUG, but switching to this library mapping does not require a rebuild of the UEFI Driver sources.
BaseDebugLibStdErris the recommended library instance for UEFI drivers that are being debugged and is the library that is used in the example DSC file in Chapter 30. This sends all messages to the Standard Error console in the UEFI System Table. If there is no output, then the likely cause is that the Standard Error device is not configured. Use the platform setup to configure the Standard Error.
BaseDebugLibConOutmay be used as a substitute for
BaseDebugLibStdErrwhen it is not possible to get the Standard Error console configured. This sends all messages to the Standard Output console in the UEFI System Table. This mixes debug messages with the normal console activity, so the display may be difficult to read, and since most UEFI consoles do not support scroll up operations, it may be difficult to see the messages when many are displayed.
BaseDebugLibSerialPortis not a UEFI conformant DebugLib. It directly accesses serial port hardware through a
SerialPortLiblibrary instance. This can be useful when debugging UEFI Drivers that execute before UEFI consoles are initialized, such as UEFI Drivers that are loaded and executed from a PCI Option ROM. When this library instance is used, the UEFI Driver writer must know that there is a serial port available on the target platform under test and must configure a
SerialPortLibwith for the attributes of the specific serial port that is to be used.
DebugLibuses several Platform Configuration Database (PCD) setting to control the behavior of the DebugLib macros. The token names for these PCD settings are as follows:
PcdDebugPropertyMaskprovides fine grain control over the macros provided by the
DebugLib. The previous two sections discuss how to disable the entire
DebugLiband how to select different
PcdDebugPropertryMaskis a bit mask that allows individual
DebugLibmacro types to be enabled or disabled. The example below shows the bitmask definitions.
0x04enables the 3
0x20control the behavior of the
ASSERT()macro if the assert condition evaluates to
0x10causes a CPU breakpoint to be generated, which is useful if a source level debugger is being used, and
0x20causes the CPU to enter an infinite loop so execution of the UEFI Driver stops.
// Declare bits for PcdDebugPropertyMask
#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
#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED 0x20
Example 267-PcdDebugPropertyMask bitmask PcdDebugPrintErrorLevelprovides a bitmask of the debug error levels that are currently enabled. The debug print error levels are shown in the Error Levels table above. Any combination of the values can be set in the bitmask. If a bit is set, then
DEBUG()macros with that same
ErrorLevelbit set are printed.
PcdDebugClearMemoryValueprovides the 8-bit byte value to use when
DEBUG_CLEAR_MEMORY()macros are used. This value is typically set to
0x00, but it is usually a good idea to try a few different values to make sure code is not improperly using buffer contents that have been cleared.
The following example shows the addition of a
[PcdsFixedAtBuild]section to the DSC files from Chapter 30. It sets
DEBUG_CODE()macros are enabled and a breakpoint is generated when an
ASSERT()is triggered. It also sets the
PcdDebugPrintErrorLevelat a fairly high verbosity level with
DEBUG_INITall enabled. Finally, it configures
DEBUG_CLEAR_MEMORY()macros, when they are enabled, fill buffers with