Personalización de la salida del depurador mediante DML
El lenguaje de marcado del depurador (DML) proporciona un mecanismo para mejorar la salida del depurador y las extensiones. De forma similar a HTML, la compatibilidad con el marcado del depurador permite que la salida incluya directivas de visualización y información adicional que no se muestre en forma de etiquetas. Las interfaces de usuario del depurador, como WinDbg, analizan la información adicional proporcionada en DML para mejorar la visualización de la información y proporcionar nuevos comportamientos, como pantallas de cuadrícula y ordenación. En este tema se describe cómo puede personalizar la salida de depuración mediante DML. Para obtener información general sobre cómo habilitar y usar DML en los depuradores, consulte Uso del lenguaje de marcado del depurador.
DML está disponible en Windows 10 y versiones posteriores.
Información general sobre DML
En cuanto a las principales ventajas de DML, proporciona la capacidad de vincular a información relacionada en la salida del depurador. Una de las etiquetas DML principales es la <etiqueta de vínculo> que permite a un productor de salida indicar que se puede acceder a la información relacionada con un fragmento de salida a través de la acción indicada del vínculo. Al igual que con los vínculos HTML en un explorador web, esto permite al usuario navegar por información con hipervínculos.
Una ventaja de proporcionar contenido con hipervínculos es que se puede usar para mejorar la detectabilidad del depurador y la funcionalidad de extensión del depurador. El depurador y sus extensiones contienen una gran cantidad de funcionalidad, pero puede ser difícil determinar el comando adecuado para usarlo en diferentes escenarios. Los usuarios simplemente deben saber qué comandos están disponibles para usar en escenarios específicos. Las diferencias entre la depuración de usuario y kernel agregan mayor complejidad. Esto suele significar que muchos usuarios no son conscientes de los comandos de depuración que podrían ayudarles. Los vínculos DML proporcionan la posibilidad de que los comandos de depuración arbitrarios se encapsulan en presentaciones alternativas, como texto descriptivo, sistemas de menús en los que se pueden hacer clic o la ayuda vinculada. Con DML, la salida del comando se puede mejorar para guiar al usuario a comandos relacionados adicionales relevantes para la tarea en cuestión.
Compatibilidad con DML del depurador
- La ventana de comandos de WinDbg admite todo el comportamiento de DML y mostrará colores, estilos de fuente y vínculos.
- Los depuradores de consola ( ntsd, cdb y kd) solo admiten los atributos de color de DML y el único cuando se ejecuta en una consola verdadera con el modo de color habilitado.
- Los depuradores con E/S redirigido, ntsd –d o remote.exe sesiones no mostrarán ningún color.
Especificación de contenido DML
DML no está diseñado para ser un lenguaje de presentación completo, como HTML. DML es deliberadamente muy sencillo y solo tiene una serie de etiquetas.
Dado que no todas las herramientas del depurador admiten texto enriquecido, DML está diseñado para permitir la traducción simple entre DML y texto sin formato. Esto permite que DML funcione en todas las herramientas del depurador existentes. Los efectos como los colores se pueden admitir fácilmente, ya que quitarlos no quita el texto que lleva la información real.
DML no es XML. DML no intenta llevar información semántica ni estructurada. Como se mencionó anteriormente, debe haber una asignación simple entre DML y texto sin formato, por este motivo, las etiquetas DML son descartables.
DML no es extensible; todas las etiquetas están predefinidas y validadas para funcionar en todas las herramientas del depurador existentes.
Estructura de etiquetas
De forma similar a XML, las etiquetas DML se proporcionan como un tagname inicial <[args]> y un siguiente </tagname>.
Caracteres especiales
El contenido DML sigue aproximadamente las reglas XML/HTML para caracteres especiales. Los caracteres &, <, > y " son especiales y no se pueden usar en texto sin formato. Las versiones de escape equivalentes son &, <, > y ". Por ejemplo, este texto:
"Alice & Bob piensa 3 < 4"
se convertirá en el siguiente DML.
"Alice & Bob think 3 < 4"
Caracteres de formato del lenguaje de programación C
Una salida significativa de las reglas XML/HTML es que el texto DML puede incluir caracteres de formato de estilo de secuencia del lenguaje de programación C, como \b, \t, \r y \n. Esto es para admitir la compatibilidad con la producción y el consumo de texto del depurador existente.
Ejemplo de DML
Supongamos que el archivo C:\Dml_Experiment.txt contiene las líneas siguientes.
My DML Experiment
<link cmd="lmD musb*">List modules that begin with usb.</link>
El siguiente comando muestra el texto y el vínculo en la ventana explorador de comandos.
.browse .dml_start c:\Dml_Experiment.txt
Si hace clic en los módulos de lista que comienzan por el vínculo usb, verá una salida similar a la siguiente imagen.
Comportamiento del botón derecho en DML
El comportamiento del clic con el botón derecho está disponible en DML. En este ejemplo se muestra cómo definir el comportamiento del clic con el botón derecho mediante <altlink> para enviar un comando bp (Establecer punto de interrupción) y enviar el comando u (Unassemble) con un clic normal.
<link cmd="u MyProgram!memcpy">
<altlink name="Set Breakpoint (bp)" cmd="bp MyProgram!memcpy" />
u MyProgram!memcpy
</link>
Referencia de etiquetas DML
<Enlace>
<link [name="text"] [cmd="debugger_command"][alt="Hover text to display"] [section="name"]>link text</link>
La etiqueta de vínculo es el mecanismo básico de hiper vinculación en DML. Dirige las interfaces de usuario que admiten la presentación DML para mostrar el texto del vínculo como un vínculo en el que se puede hacer clic. Cuando se hace clic en un vínculo con una especificación cmd, se ejecuta el comando del depurador y su salida debe reemplazar la salida actual.
Los argumentos name y section permiten la navegación entre vínculos con nombre, de forma similar a la compatibilidad con <un nombre> y #name HTML. Cuando se haga clic en un vínculo que tenga un argumento de sección en la interfaz de usuario, buscará un vínculo denominado con un nombre coincidente y lo desplazará a la vista. Esto permite que los vínculos apunten a diferentes secciones de la misma página (o a una sección determinada de una página nueva). El nombre de sección de DML es independiente para evitar tener que definir una nueva sintaxis que permitiría un nombre de sección al final de la cadena de comandos.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
<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>
Ejemplo
En este ejemplo se muestra el uso del atributo alt para crear texto que aparecerá al mantener el puntero sobre el vínculo 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 [name="text"] [cmd="debugger_command"] [section="name"]>alt link text</altlink>
La <etiqueta altlink> proporciona un comportamiento de clic con el botón derecho disponible en DML. Cuando se hace clic en un vínculo con una especificación cmd, se ejecuta el comando del depurador y su salida debe reemplazar la salida actual. La <pestaña altlink> normalmente se empareja con la etiqueta de <vínculo> para admitir el comportamiento normal y del clic derecho.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
En este ejemplo se muestra cómo definir el comportamiento de clic con el botón derecho mediante <altlink> para enviar un comando bp (Establecer punto de interrupción) y enviar el comando u (Unassemble) con un clic normal.
<link cmd="u MyProgram!memcpy">
<altlink name="Set Breakpoint (bp)" cmd="bp MyProgram!memcpy" />
u MyProgram!memcpy
</link>
<Exec>
<exec cmd="debugger_command">scriptiva text</exec>
Una etiqueta exec es similar a una etiqueta de vínculo en la que se debe presentar el texto descriptivo como un elemento en el que se puede hacer clic. Sin embargo, cuando la etiqueta exec se usa en una ventana del explorador de comandos, el comando especificado se ejecuta sin reemplazar la salida actual, esta etiqueta proporciona una manera de ejecutar comandos con un clic, desde un menú.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
En este ejemplo se muestra cómo definir dos comandos con un clic normal.
<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>
<b>negrita/<b>
Esta etiqueta solicita negrita. Los <b>, <i> y <u> se pueden anidar para tener una combinación de las propiedades.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
En este ejemplo se muestra cómo en negrita el texto.
<b>This is bold Text</b>
<i>
<Texto>en cursiva</i>
Esta etiqueta solicita cursiva. Los <b>, <i> y <u> se pueden anidar para tener una combinación de las propiedades.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
En este ejemplo se muestra cómo cursiva el texto.
<i>This is italicized Text</i>
<u>
<u>subrayado de texto</u>
Esta etiqueta solicita texto subrayado. El <b>, <i> y <u> se pueden anidar para tener una combinación de las propiedades.
La conversión a texto sin formato quita las etiquetas.
Ejemplo
En este ejemplo se muestra cómo subrayado el texto.
<u>This is underlined Text</u>
Ejemplo
En este ejemplo se muestra cómo combinar etiquetas en negrita, subrayado y cursiva de texto.
<b><u><i>This is bold, underlined and italizized text. </i></u></b>
<col>
<col fg="name" bg="name">text</col>
Solicite colores de primer plano y de fondo para el texto. Los colores se proporcionan como nombres de colores conocidos en lugar de valores absolutos, ya que permiten a los clientes controlar qué tipo de color ven. Nombres de color actuales (los valores predeterminados solo se aplican a WinDbg).
Etiquetas de elemento en primer plano y fondo
Configuración | Descripción/ejemplo |
wbg: fondo de Windows wfg: primer plano de Windows |
Fondo de ventana predeterminado y colores de primer plano. El valor predeterminado es los colores del sistema para el texto de ventana y ventana.
<col fg="wfg" bg="wbg"> Este es el primer plano estándar/ texto <de fondo /col> |
clbg: primer plano de línea actual clfg: fondo de línea actual |
Fondo de línea actual y colores de primer plano. El valor predeterminado es los colores del sistema para resaltar y resaltar texto.
<col fg="clfg" bg="clbg"> Test Text - Current Line</col> |
empbg: fondo resaltado emphfg - Énfasis en primer plano |
Texto resaltado. El valor predeterminado es azul claro.
<col fg="empfg" bg="empbg"> Esto es énfasis en primer plano/ texto <de fondo /col> |
subebbg: fondo subduido subfg- Subdued foreground |
Texto subduido. El valor predeterminado es el color del sistema para subtítulo texto inactivo y subtítulos inactivos.
<col fg="subfg" bg="subbg"> Este es subduido en primer plano/ texto <de fondo /col> |
normbg: fondo normal normfg: primer plano normal |
Normal <col fg="normfg" bg="normbg"> Test Text - Normal (normfg / normbg) </col> |
warnbg: fondo de advertencia warnfg: primer plano de advertencia |
Advertencia <col fg="warnfg" bg="warnbg"> Test Text - Warning (warnfg / warnbg) </col> |
errbg: fondo del error errfg: error en primer plano |
Error <col fg="errfg" bg="errbg"> Test Text - Error (errfg / errbg) </col> |
verbbg: fondo detallado verbfg: primer plano detallado |
Verbose <col fg="verbfg" bg="verbbg"> Test Text - Verbose (verbfg / verbbg) </col> |
Etiquetas de elemento único de código fuente
srcnum: constante numérica de origen |
Colores del elemento de origen.
<col fg="srcnum" bg="wbg"> Test Text - srcnum </col> |
srcchar: constante de caracteres de origen |
<col fg="srcchar" bg="wbg"> Test Text - srcchar </col> |
srcstr: constante de cadena de origen |
<col fg="srcstr" bg="wbg"> Test Text - srcstr </col> |
srcid :identificador de origen |
<col fg="srcid " bg="wbg"> Test Text - srcid </col> |
srckw- Keyword |
<col fg="srckw" bg="wbg"> Test Text - srckw </col> |
srcpair: llave de origen o par de símbolos coincidente |
<col fg="srcpair" bg="empbbg"> Test Text - srcpair </col> |
srccmnt: comentario de origen |
<col fg="srccmnt" bg="wbg"> Test Text - srccmnt </col> |
srcdrct: directiva source |
<col fg="srcdrct" bg="wbg"> Test Text - srcdrct </col> |
srcspid: identificador especial de origen |
<col fg="srcspid" bg="wbg"> Test Text - srcspid </col> |
srcannot: anotación de origen |
<col fg="srcannot" bg="wbg"> Test Text - srcannot </col> |
modificado: datos modificados |
Se usa para los datos que han cambiado desde un punto de detención anterior, como los registros modificados en WinDbg. El valor predeterminado es rojo.
<col fg="changed" bg="wbg"> Test Text - Changed</col> |
Código de ejemplo de DML
Este código de ejemplo ilustra lo siguiente.
- Llamar a comandos de depuración
- Implementar comandos de clic derecho
- Implementación del puntero sobre el texto
- Uso de color y texto enriquecido
<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 additional 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
En este código de ejemplo se muestra el uso de etiquetas de color y formato.
*** 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>
Adiciones DML a la interfaz dbgeng
Las API de extensión y motor de depurador proporcionan una interfaz para usar el motor del depurador para crear aplicaciones personalizadas. También puede escribir extensiones personalizadas que se ejecutarán en WinDbg, KD, CDB y NTSD. Para obtener más información, vea Escritura de extensiones de DbgEng. En esta sección se describen las mejoras de DML disponibles en las interfaces del motor del depurador.
Dbgeng ya tiene un conjunto de métodos de entrada e interfaces de salida de control de texto, el uso de DML solo requiere la especificación del tipo de contenido que se lleva en texto de entrada y salida.
Proporcionar contenido DML a dbgeng
La marca de control de salida DEBUG_OUTCTL_DML indica que el texto generado por un método dbgeng debe controlarse como contenido DML. Si esta marca no recibe el texto se trata como contexto de texto sin formato. DEBUG_OUTCTL_DML se puede usar con los métodos siguientes.
- IDebugControl4::ControlledOutput
- IDebugControl4::ControlledOutputVaList
- IDebugControl4::ControlledOutputWide
- IDebugControl4::ControlledOutputVaListWide
El texto especificado debe seguir las reglas DML para caracteres válidos.
Se han mejorado todas las rutinas de salida para permitir un nuevo especificador de formato %[h|w]Y{t}. Este especificador de formato tiene un puntero de cadena como argumento e indica que el texto especificado es texto sin formato y debe convertirse en formato DML durante el procesamiento de salida. Esto proporciona a los llamadores una manera sencilla de incluir texto sin formato en el contenido DML sin tener que convertir previamente al formato DML por sí mismos. Los calificadores h y w indican texto ANSI o Unicode, como con %s.
En la tabla siguiente se resume el uso del especificador de formato %Y.
%Y{t}: cadena entre comillas. Convertirá texto a DML si el formato de salida (primer argumento) es DML.
%Y{T}: cadena entre comillas. Siempre convertirá texto a DML independientemente del formato de salida.
%Y{s}: cadena sin comilla. Convertirá texto a DML si el formato de salida (primer argumento) es DML.
%Y{S}: cadena sin comilla. Siempre convertirá texto a DML independientemente del formato de salida.
%Y{as}: ULONG64. Agrega una cadena vacía o 9 caracteres de espaciado para rellenar la parte alta de 32 bits de los campos de puntero con formato del depurador. El espacio adicional genera 9 espacios que incluyen los 8 ceros superiores más el carácter ' .
%Y{ps}: ULONG64. Espacio adicional para rellenar campos de puntero con formato del depurador (incluye los 8 ceros superiores más el carácter ' ).
%Y{l}: ULONG64. Dirección como información de línea de origen.
Este fragmento de código muestra el uso del especificador de formato %Y.
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;
}
Este código de ejemplo generaría la salida siguiente.
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 <World>"
TEXT/NORMAL Y{s}: Hello <World>
TEXT/NORMAL Y{S}: Hello <World>
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]
Una marca de control adicional, DEBUG_OUTCTL_AMBIENT_DML, permite la especificación del texto de contexto DML sin modificar ningún atributo de control de salida. DEBUG_OUTCTL_AMBIENT_TEXT también se ha agregado como alias más descriptivo para el DEBUG_OUTCTL_AMBIENT existente anteriormente. Las marcas de control de salida se definen en dbgeng.h.
#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
Proporcionar contenido DML desde un depurador
El dbgeng se ha mejorado para examinar la salida del depurador para un marcador especial, que indica que el texto restante en una parte de la salida del depurador se debe tratar como DML. El cambio de modo solo se aplica a una sola parte de la salida del depurado, como una sola cadena OutputDebugString, y no es un conmutador de modo global.
En este ejemplo se muestra una combinación de salida de DML y sin formato.
OutputDebugString(“This is plain text\n<?dml?>This is <col fg=\”emphfg\”>DML</col> text\n”);
La salida generada tendrá una línea de texto sin formato seguida de una línea de DML donde el acrónimo DML se muestra en un color diferente.
IDebugOutputCallbacks2
IDebugOutputCallbacks2 permite a los clientes de interfaz dbgeng recibir contenido DML completo para la presentación. IDebugOutputCallbacks2 es una extensión de IDebugOutputCallbacks (no IDebugOutputCallbacksWide) para que se pueda pasar al método SetOutputCallbacks existente. El motor realizará una queryInterface para IDebugOutputCallbacks2 para ver qué interfaz admite el objeto de devolución de llamada de salida entrante. Si el objeto admite IDebugOutputCallbacks2, toda la salida se enviará a través de los métodos extendidos IDebugOutputCallbacks2; No se usará el método básico IDebugOutputCallbacks::Output.
Los nuevos métodos son:
IDebugOutputCallbacks2::GetInterestMask: permite al objeto de devolución de llamada describir qué tipos de notificaciones de salida quiere recibir. La opción básica es entre el contenido de texto sin formato (DEBUG_OUTCBI_TEXT) y el contenido DML (DEBUG_OUTCBI_DML). Además, el objeto de devolución de llamada también puede solicitar la notificación de vaciados explícitos (DEBUG_OUTCBI_EXPLICIT_FLUSH).
IDebugOutputCallbacks2::Output2: todas las notificaciones IDebugOutputCallbacks2 pasan por Output2. El parámetro Which indica en qué tipo de notificación se incluye mientras los parámetros Flags, Arg y Text llevan la carga de notificación. Las notificaciones incluyen:
DEBUG_OUTCB_TEXT: salida de texto sin formato. Las marcas proceden de DEBUG_OUTCBF_*, Arg es la máscara de salida y Text es el texto sin formato. Esto solo se recibirá si DEBUG_OUTCBI_TEXT se dio en la máscara de interés.
DEBUG_OUTCB_DML: salida de contenido DML. Las marcas proceden de DEBUG_OUTCBF_*, Arg es la máscara de salida y Text es el contenido DML. Esto solo se recibirá si DEBUG_OUTCBI_DML se ha dado en la máscara de interés.
DEBUG_OUTCB_EXPLICIT_FLUSH: un llamador ha llamado FlushCallbacks sin texto almacenado en búfer. Normalmente, cuando se vacía el texto almacenado en búfer, se establecerá la marca DEBUG_OUTCBF_COMBINED_EXPLICIT_FLUSH, doblando las dos notificaciones en una. Si no se almacena en búfer ningún texto, se envía una notificación de solo vaciado.
Las marcas de máscara de interés se definen en dbgeng.h, como se muestra aquí.
// 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
Tenga en cuenta que un objeto de salida puede registrarse para el contenido de texto y DML si puede controlarlos ambos. Durante el procesamiento de salida de la devolución de llamada, el motor elegirá el formato que reduce las conversiones, por lo que admitir ambas puede reducir las conversiones en el motor. No es necesario, sin embargo, y admitir solo un formato es el modo de operación esperado.
Conversiones automáticas
Dbgeng convertirá automáticamente entre texto sin formato y DML según sea necesario. Por ejemplo, si un llamador envía contenido DML al motor, el motor lo convertirá en texto sin formato para todos los clientes de salida que solo aceptan texto sin formato. Como alternativa, el motor convertirá texto sin formato en DML para todas las devoluciones de llamada de salida que solo aceptan DML.