本主题介绍如何自定义使用 DML 您调试输出。 

DML 是可用在 Windows 10 及更高版本。

DML 概述

为使用 web 浏览器中的 HTML 链接这样用户能够导航超链接的信息。

使用 DML,可以对命令输出来增强用户引导到适用于手头的任务的其他相关命令。

调试器 DML 支持

  • 命令窗口在 WinDbg 中的支持所有 DML 行为,将显示颜色、 字体样式和链接。
  • 使用颜色模式已启用,则返回 true 的控制台中运行时,控制台调试器 – ntsd、 cdb 和 kd – 仅支持 DML,和唯一的颜色属性。
  • 通过重定向 I/O 的调试器,ntsd – d 或 remote.exe 会话不会显示任何颜色。

DML 内容规范

DML 是精心设计的非常简单,只有少量的标记。

可以轻松地支持颜色等效果,因为删除它们不会删除携带的实际信息的文本。

如上所述,必须有一个简单之间的映射 DML 和纯文本,因此,DML 标记是所有可放弃。

DML 不是可扩展的;所有标记是预定义的并验证,以跨所有现有的调试器工具工作。

标记结构

类似于 XML,DML 标记可以作为起点<tagname [args] >并且下列</tagname>。

特殊字符

例如此文本:

将转换为以下 dml。

text
"Alice & Bob think 3 &lt 4"

C 编程语言格式设置字符

这是为了支持与现有调试器文本生成和使用的兼容性。

DML 标记参考

  • <link>

    link>

    示例

    <b> Handy Links </b>
    <link cmd="!dml_proc">Display process information with DML rendering.</link>
    <link cmd="kM">Display stack information with DML rendering.</link>

    此示例演示如何使用 alt 属性创建时你将鼠标悬停 DML 链接将显示的文本。

    <b>Hover Example</b>
    <link cmd="lmD" alt="This link will run the list modules command and display the output in DML format">LmD</link>
  • <altlink>

    此示例演示如何定义行为使用右键单击<altlink>发送断点最佳实践 (设置断点) 命令并将发送 u (反汇编) 正则单击。

    <link cmd="u MyProgram!memcpy">
    <altlink name="Set Breakpoint (bp)" cmd="bp MyProgram!memcpy" />
    u MyProgram!memcpy
    </link>
  • 但是,当在命令浏览器窗口中使用 exec 标记时,而无需替换当前的输出执行给定的命令,此标记提供了一种方法执行单击一下,从一个菜单命令。

    示例

    此示例演示如何定义正则单击两个命令。

    <b>Exec Sample</b>
    <exec cmd="!dml_proc">Display process information with DML rendering.</exec>
    <exec cmd="kM">Display stack information with DML rendering.</exec>

  • 示例

    此示例演示如何为粗体文本。

    <b>This is bold Text</b>
  • 此示例演示如何以文本变为斜体。
    <i>This is italicized Text</i>
  • <B>,<我>并<u>可以嵌套以混合的属性。

    示例

    此示例演示如何以带有下划线的文本。

    <u>This is underlined Text</u>

    此示例演示如何组合标记来设置粗体、 下划线和斜体文本。

    <b><u><i>This is bold, underlined and italizized text. </i></u></b> 

  • 当前颜色名称 (默认值仅适用于 WinDbg)。

    前景色和背景元素标记
    设置 说明 / 示例

    wbg-Windows 背景

    wfg-Windows 前景色

    默认为窗口和窗口文本的系统颜色。

    clbg 的当前行的前景色

    clfg 的当前行背景

    默认为突出显示的系统颜色和突出显示文本。

    empbg 的重要背景

    emphfg-重要的前景色

    默认为浅蓝色。

    subbg-Subdued 背景

    subfg Subdued 前景色

    默认为非活动标题文本和非活动状态的隐藏式字幕的系统颜色。

    normbg 的正常后台

    normfg-正常的前景色

    正常

    warnbg-警告背景

    warnfg-警告前景色

    警告

    errbg-错误背景

    errfg-错误前景色

    错误

    verbbg-Verbose 背景

    verbfg-Verbose 前景色

    Verbose

    源代码单个元素标记

    srcnum-源数值常量

    源元素的颜色。

    srcchar-源字符常量

    srcstr-源字符串常量

    srcid-源标识符

    srckw 关键字

    srcpair-源大括号或匹配的符号对

    srccmnt-源注释

    srcdrct-源指令

    srcspid-源特殊标识符

    srcannot-源批注

    更改-更改的数据

    默认值为红色。


DML 的示例代码

此示例代码说明了以下。

  • 调用调试命令
  • 实现右键单击命令
  • 实现悬停文本
  • 使用颜色和丰富的文本
XML
<col fg="srckw" bg="wbg"> <b>
*******************************************************
*** Example debug commands for crash dump analysis ****
*******************************************************
</b></col>
<col fg="srcchar" bg="wbg"><i>
**** Hover over commands for additional information ****
        **** Right-click for command help ****
</i></col>

<col fg="srccmnt" bg="wbg"><b>*** Common First Steps for Crash Dump Analysis ***</b> </col>
<link cmd=".symfix" alt="Set standard symbol path using .symfix">.symfix<altlink name="Help about .symfix" cmd=".hh .symfix" /> </link> - Set standard symbol path
<link cmd=".sympath+ C:\Symbols" alt="This link adds addtional symbol directories">.sympath+ C:\Symbols<altlink name="Help for .sympath" cmd=".hh .sympath" /> </link> - Add any additional symbol directories, for example C:\Symbols
<link cmd=".reload /f" alt="This link reloads symbols">.reload /f<altlink name="Help for .reload" cmd=".hh .reload" /> </link> - Reloads symbols to make sure they are in good shape
<link cmd="!analyze -v" alt="This link runs !analyze with the verbose option">!analyze -v<altlink name="Help for !analyze" cmd=".hh !analyze" /> </link> - Run !analyze with the verbose option
<link cmd="vertarget" alt="This link runs checks the target version">vertarget<altlink name="Help for vertarget" cmd=".hh vertarget" /></link> - Check the target version
<link cmd="version" alt="This link displays the versions in use">version<altlink name="Help for version" cmd=".hh version" /></link> - Display the versions in use
<link cmd=".chain /D" alt="This link runs .chain">.chain /D<altlink name="Help for .chain" cmd=".hh .chain" /></link> - Use the .chain /D command to list debugger extensions
<link cmd="kM" alt="This link displays the stack backtrace using DML">kD<altlink name="Help for k" cmd=".hh k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)" /> </link> - Display the stack backtrace using DML rendering
<link cmd="lmD" alt="This link will run the list modules command and display the output in DML format">LmD<altlink name="Help for lmD" cmd=".hh lm" /> </link> - List modules command and display the output in DML format
<link cmd=".help /D" alt="Display help for commands">.help /D <altlink name="Help for .dot commands" cmd=".hh commands" /></link> - Display help for commands in WinDbg
<link cmd=".hh" alt="Start help">.hh<altlink name="Debugger Reference Help".hh Contents" cmd=".hh Debugger Reference" /></link> - Start help

<col fg="srccmnt" bg="wbg"><b>*** Registers and Context ***</b></col>
<link cmd="r" alt="This link displays registers">r<altlink name="Help about r command" cmd=".hh r" /></link>  - Display registers
<link cmd="dt nt!_CONTEXT" alt="This link displays information about nt_CONTEXT">dt nt!_CONTEXT<altlink name="Help about the dt command" cmd=".hh dt" /></link> - Display information about nt_CONTEXT
<link cmd="dt nt!_PEB" alt="This link calls the dt command to display nt!_PEB">dt nt!_PEB<altlink name="Help about dt command" cmd=".hh dt" /></link> - Display information about the nt!_PEB
<link cmd="ub" alt="This link unassembles backwards">ub<altlink name="Help about ub command" cmd=".hh u, ub, uu (Unassemble)" /></link> - Unassemble Backwards

<col fg="srcchar" bg="wbg"><i>
**** Note: Not all of the following commands will work with all crash dump data ****
</i></col>
<col fg="srccmnt" bg="wbg"><b>*** Device Drivers ***</b></col>
<link cmd="!devnode 0 1" alt="This link displays the devnodes">!devnode 0 1<altlink name="Help about !devnode command" cmd=".hh !devnode" /></link> - Display devnodes
<link cmd=".load wdfkd.dll;!wdfkd.help" alt="Load wdfkd extensions and display help">.load wdfkd.dll;!wdfkd.help<altlink name="Help about the wdfkd extensions" cmd=".hh !wdfkd" /></link> - Load wdfkd extensions and display help
<link cmd="!wdfkd.wdfldr" alt="This link displays !wdfkd.wdfldr">!wdfkd.wdfldr<altlink name="Help about !wdfkd.wdfldr" cmd=".hh !wdfkd.wdfldr" /></link>  - Display WDF framework driver loader information
<link cmd="!wdfkd.wdfumtriage" alt="This link displays !wdfkd.umtriage">!wdfkd.umtriage<altlink name="Help about !wdfkd.umtriage" cmd=".hh !wdfkd_wdfumtriage" /></link> - Display WDF umtriage driver information

<col fg="srccmnt" bg="wbg"><b>*** IRPs and IRQL ***</b></col>
<link cmd="!processirps" alt="This link displays process IRPs">!processirps<altlink name="Help about !processirps command" cmd=".hh !processirps" /></link> - Display process IRPs
<link cmd="!irql" alt="This link displays !irql">!irql<altlink name="Help about !irql command" cmd=".hh !irql" /></link> - Run !irql

<col fg="srccmnt" bg="wbg"><b>*** Variables and Symbols ***</b></col>
<link cmd="dv" alt="This link calls the dv command">dv<altlink name="Help about dv command" cmd=".hh dv" /></link> - Display the names and values of all local variables in the current scope

<col fg="srccmnt" bg="wbg"><b>*** Threads, Processes, and Stacks ***</b></col>
<link cmd="!threads" alt="This link displays threads">!threads<altlink name="Help about the !threads command" cmd=".hh !threads" /></link> - Display threads
<link cmd="!ready 0xF" alt="This link runs !ready 0xF">!ready 0xF<altlink name="Help about the !ready command" cmd=".hh !ready" /></link> - Display threads in the ready state
<link cmd="!process 0 F" alt="This link runs !process 0 F ">!process 0 F<altlink name="Help about the !process command" cmd=".hh !process" /></link> - Run !process 0 F
<link cmd="!stacks 2" alt="This link displays stack information using !stacks 2 ">!stacks 2<altlink name="Help about the !stacks command" cmd=".hh !stacks" /></link> - Display stack information using !stacks 2
<link cmd=".tlist" alt="This link displays a process list using TList ">tlist<altlink name="Help about the TList command" cmd=".hh .tlist" /></link> - Display a process list using tlist
<link cmd="!process" alt="This link displays process ">!process<altlink name="Help about the !process command" cmd=".hh !process" /></link> - Display process information
<link cmd="!dml_proc" alt="This link displays process information with DML rendering.">!dml_proc<altlink name="Help about the !dml_proc command" cmd=".hh !dml_proc" /></link> - Display process information with DML rendering

此示例代码演示如何使用颜色和格式设置标记。

XML
*** Text Tag Examples ****

<b>This is bold text</b>
<u>This is underlined text</u>
<i>This is italizized text</i>
<b><u><i>This is bold, underlined and italizized text</i></u></b>

<b>Color Tag Examples</b>
<col fg="wfg" bg="wbg"> This is standard foreground / background text </col>
<col fg="empfg" bg="empbg"> This is emphasis foreground / background text </col>
<col fg="subfg" bg="subbg"> This is subdued foreground / background text </col>
<col fg="clfg" bg="clbg"> Test Text - Current Line</col>

<b>Other Tags Sets</b>
<col fg="normfg" bg="normbg"> Test Text - Normal (normfg / normbg) </col>
<col fg="warnfg" bg="warnbg"> Test Text - Warning (warnfg / warnbg) </col>
<col fg="errfg" bg="errbg"> Test Text - Error (errfg / errbg) </col>
<col fg="verbfg" bg="verbbg"> Test Text - Verbose (verbfg / verbbg) </col>

<b>Changed Text Tag Examples</b>
<col fg="changed" bg="wbg"> Test Text - Changed</col>

<b>Source Tags - using wbg background</b>
<col fg="srcnum" bg="wbg"> Test Text - srcnum  </col>
<col fg="srcchar" bg="wbg"> Test Text - srcchar  </col>
<col fg="srcstr" bg="wbg"> Test Text - srcstr  </col>
<col fg="srcid " bg="wbg"> Test Text - srcid   </col>
<col fg="srckw" bg="wbg"> Test Text - srckw </col>
<col fg="srcpair" bg="empbbg"> Test Text - srcpair </col>
<col fg="srccmnt" bg="wbg"> Test Text - srccmnt  </col>
<col fg="srcdrct" bg="wbg"> Test Text - srcdrct </col>
<col fg="srcspid" bg="wbg"> Test Text - srcspid </col>
<col fg="srcannot" bg="wbg"> Test Text - srcannot </col>

<b>Source Tags - using empbg background</b>
<col fg="srcnum" bg="empbg"> Test Text - srcnum  </col>
<col fg="srcchar" bg="empbg"> Test Text - srcchar  </col>
<col fg="srcstr" bg="empbg"> Test Text - srcstr  </col>
<col fg="srcid " bg="empbg"> Test Text - srcid   </col>
<col fg="srckw" bg="empbg"> Test Text - srckw </col>
<col fg="srcpair" bg="empbbg"> Test Text - srcpair </col>
<col fg="srccmnt" bg="empbg"> Test Text - srccmnt  </col>
<col fg="srcdrct" bg="empbg"> Test Text - srcdrct </col>
<col fg="srcspid" bg="empbg"> Test Text - srcspid </col>
<col fg="srcannot" bg="empbg"> Test Text - srcannot </col>

<b>Source Tags - using subbg background</b>
<col fg="srcnum" bg="subbg"> Test Text - srcnum  </col>
<col fg="srcchar" bg="subbg"> Test Text - srcchar  </col>
<col fg="srcstr" bg="subbg"> Test Text - srcstr  </col>
<col fg="srcid " bg="subbg"> Test Text - srcid   </col>
<col fg="srckw" bg="subbg"> Test Text - srckw </col>
<col fg="srcpair" bg="subbg"> Test Text - srcpair </col>
<col fg="srccmnt" bg="subbg"> Test Text - srccmnt  </col>
<col fg="srcdrct" bg="subbg"> Test Text - srcdrct </col>
<col fg="srcspid" bg="subbg"> Test Text - srcspid </col>
<col fg="srcannot" bg="subbg"> Test Text - srcannot </col>

Dbgeng 接口 DML 新增功能

本部分介绍调试器引擎接口的可用 DML 增强功能。

Dbgeng 已有一组文本处理输入的法和输出接口,DML 的使用仅需要执行输入和输出文本中的内容类型的规范。

为 dbgeng 提供 DML 内容

调试_OUTCTL_可以使用以下方法使用 DML。

  • IDebugControl4::ControlledOutput
  • IDebugControl4::ControlledOutputVaList
  • IDebugControl4::ControlledOutputWide
  • IDebugControl4::ControlledOutputVaListWide

给定的文本必须遵循有效字符的 DML 的规则。

H 和 w 限定符表示与 %的 ANSI 或 Unicode 文本。

下表总结了使用 %Y 格式说明符。

   
%Y{t} 会将文本转换为 DML,如果输出格式 (第一个参数) 是 DML。
%Y{T} 将始终将文本转换为 DML 无论输出格式。
%Y {s} 会将文本转换为 DML,如果输出格式 (第一个参数) 是 DML。
%Y{S} 将始终将文本转换为 DML 无论输出格式。
%Y{as} 额外的空间输出 9 空格包括上限 8 零再加上`字符。
%Y{ps} 多余空间用于填充调试器格式化指针字段 (包括上限 8 零再加上`字符)。
%Y{l} 地址作为源行信息。

此代码片段演示如何使用 %Y 格式说明符。

C++
HRESULT CALLBACK testout(_In_ PDEBUG_CLIENT pClient, _In_ PCWSTR /*pwszArgs*/)
{
    HRESULT hr = S_OK;

    ComPtr<IDebugControl4> spControl;
    IfFailedReturn(pClient->QueryInterface(IID_PPV_ARGS(&spControl)));

    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{t}: %Y{t}\n", L"Hello <World>");
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{T}: %Y{T}\n", L"Hello <World>");
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{s}: %Y{s}\n", L"Hello <World>");
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{S}: %Y{S}\n", L"Hello <World>");

    spControl->ControlledOutputWide(0, DEBUG_OUTPUT_NORMAL, L"TEXT/NORMAL Y{t}: %Y{t}\n", L"Hello <World>");
    spControl->ControlledOutputWide(0, DEBUG_OUTPUT_NORMAL, L"TEXT/NORMAL Y{T}: %Y{T}\n", L"Hello <World>");
    spControl->ControlledOutputWide(0, DEBUG_OUTPUT_NORMAL, L"TEXT/NORMAL Y{s}: %Y{s}\n", L"Hello <World>");
    spControl->ControlledOutputWide(0, DEBUG_OUTPUT_NORMAL, L"TEXT/NORMAL Y{S}: %Y{S}\n", L"Hello <World>");

    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{a}: %Y{a}\n", (ULONG64)0x00007ffa7da163c0);
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{as} 64bit   : '%Y{as}'\n", (ULONG64)0x00007ffa7da163c0);
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{as} 32value : '%Y{as}'\n", (ULONG64)0x1);

    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{ps} 64bit   : '%Y{ps}'\n", (ULONG64)0x00007ffa7da163c0);
    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{ps} 32value : '%Y{ps}'\n", (ULONG64)0x1);

    spControl->ControlledOutputWide(DEBUG_OUTCTL_DML, DEBUG_OUTPUT_NORMAL, L"DML/NORMAL Y{l}: %Y{l}\n", (ULONG64)0x00007ffa7da163c0);

    return hr;

}

此示例代码会生成以下输出。

dbgcmd
0:004> !testout
DML/NORMAL Y{t}: "Hello <World>"
DML/NORMAL Y{T}: "Hello <World>"
DML/NORMAL Y{s}: Hello <World>
DML/NORMAL Y{S}: Hello <World>
TEXT/NORMAL Y{t}: "Hello <World>"
TEXT/NORMAL Y{T}: "Hello &lt;World&gt;"
TEXT/NORMAL Y{s}: Hello <World>
TEXT/NORMAL Y{S}: Hello &lt;World&gt;
DML/NORMAL Y{a}: 00007ffa`7da163c0
DML/NORMAL Y{as} 64bit   : '         '
DML/NORMAL Y{as} 32value : '         '
DML/NORMAL Y{ps} 64bit   : '        '
DML/NORMAL Y{ps} 32value : '        '
DML/NORMAL Y{l}: [d:\th\minkernel\kernelbase\debug.c @ 443]

Dbgeng.h 中定义的输出控制标志。

C++
#define DEBUG_OUTCTL_DML               0x00000020

// Special values which mean leave the output settings
// unchanged.
#define DEBUG_OUTCTL_AMBIENT_DML       0xfffffffe
#define DEBUG_OUTCTL_AMBIENT_TEXT      0xffffffff

// Old ambient flag which maps to text.
#define DEBUG_OUTCTL_AMBIENT           DEBUG_OUTCTL_AMBIENT_TEXT

从调试对象提供 DML 内容

模式更改仅适用于单个调试对象输出,如单个 OutputDebugString 字符串,且不是全局模式开关。

此示例演示纯和 DML 输出的组合。

text
OutputDebugString(“This is plain text\n<?dml?>This is <col fg=\”emphfg\”>DML</col> text\n”);

输出生成,将具有一个行跟的 DML 首字母缩略词 DML 以不同的颜色的显示位置的行的纯文本。

IDebugOutputCallbacks2

如果对象支持所有的输出将发送通过扩展 IDebugOutputCallbacks2 方法; IDebugOutputCallbacks2将不使用基本 idebugoutputcallbacks:: Output 方法。

新的方法是:

  • 此外,回调对象还可以请求通知的显式刷新 (调试_OUTCBI_EXPLICIT_刷新)。

  • 通知包括:

    • 这将仅收到如果调试_OUTCBI_相关掩码中所提供的文本。

    • 这将仅收到如果调试_OUTCBI_DML 相关掩码中所提供。

    • 如果没有文本进行缓冲处理仅刷新通知将发送。

Dbgeng.h 中定义了感兴趣的掩码标志,如下所示。

C++
// IDebugOutputCallbacks2 interest mask flags.
//
// Indicates that the callback wants notifications
// of all explicit flushes.
#define DEBUG_OUTCBI_EXPLICIT_FLUSH 0x00000001
// Indicates that the callback wants
// content in text form.
#define DEBUG_OUTCBI_TEXT           0x00000002
// Indicates that the callback wants
// content in markup form.
#define DEBUG_OUTCBI_DML            0x00000004

#define DEBUG_OUTCBI_ANY_FORMAT     0x00000006

但是,没有必要,并且支持仅一种格式是操作的预期的模式。

自动转换

或者,该引擎将所有输出回调仅接受 DML,将纯文本都转换为 DML。

相关文章: