<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Daniel Martín's blog : Windbg</title><link>http://msmvps.com/blogs/dmartin/archive/tags/Windbg/default.aspx</link><description>Tags: Windbg</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Tutorial sobre Windbg [Parte IV]</title><link>http://msmvps.com/blogs/dmartin/archive/2009/11/13/tutorial-sobre-windbg-parte-iv.aspx</link><pubDate>Fri, 13 Nov 2009 13:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1738116</guid><dc:creator>dmartin</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/rsscomments.aspx?PostID=1738116</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/commentapi.aspx?PostID=1738116</wfw:comment><comments>http://msmvps.com/blogs/dmartin/archive/2009/11/13/tutorial-sobre-windbg-parte-iv.aspx#comments</comments><description>&lt;p&gt;En esta cuarta parte del tutorial sobre Windbg, se van a tratar algunos comandos b&amp;aacute;sicos para conocer el estado de la m&amp;aacute;quina que estamos depurando. El primer aspecto que se va a tratar es el estado del banco de registros.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Estado del banco de registros&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Toda computadora dispone de un conjunto compuesto por un cierto n&amp;uacute;mero de registros. El n&amp;uacute;mero de registros y su tama&amp;ntilde;o (en n&amp;uacute;mero de bits) es algo que depende de la arquitectura de la plataforma. Los registros principalmente sirven para almacenar de manera temporal peque&amp;ntilde;os valores que se van necesitando durante la ejecuci&amp;oacute;n del c&amp;oacute;digo m&amp;aacute;quina, as&amp;iacute; como valores de retorno de funciones, &lt;em&gt;flags&lt;/em&gt; de estado del procesador, etc. Si ha seguido la parte tres del tutorial (&lt;a href="http://msmvps.com/blogs/dmartin/archive/2009/08/13/tutorial-sobre-windbg-parte-iii.aspx"&gt;http://msmvps.com/blogs/dmartin/archive/2009/08/13/tutorial-sobre-windbg-parte-iii.aspx&lt;/a&gt;), en ella se indicaron algunos comandos que sirven para detener el flujo de ejecuci&amp;oacute;n de un programa dentro del depurador. Si en ese estado queremos examinar cu&amp;aacute;l es el contenido de los registros de la m&amp;aacute;quina, podemos ejecutar el comando &lt;strong&gt;r&lt;/strong&gt;. Este es un ejemplo de la salida del comando r en un sistema operativo de 32 bits que est&amp;aacute; siendo depurado:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; r&lt;br /&gt;eax=00000000 ebx=00000000 ecx=0012fb0c edx=779664f4 esi=fffffffe edi=00000000&lt;br /&gt;eip=779be60e esp=0012fb28 ebp=0012fb54 iopl=0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nv up ei pl zr na pe nc&lt;br /&gt;cs=001b&amp;nbsp; ss=0023&amp;nbsp; ds=0023&amp;nbsp; es=0023&amp;nbsp; fs=003b&amp;nbsp; gs=0000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; efl=00000246&lt;br /&gt;ntdll!LdrpDoDebuggerBreak+0x2c:&lt;br /&gt;779be60e cc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;En la salida del comando se muestra el contenido de los registros de la arquitectura IA-32: Eax (registro acumulador), Ebx (registro base), Ecx (registro contador), Esi (registro origen en operaciones con la memoria), Edi (registro destino en operaciones con la memoria), Eip (registro de instrucciones), Esp (registro que contiene el puntero de pila), Ebp (registro con el puntero base de pila), y algunos &lt;em&gt;flags&lt;/em&gt; que est&amp;aacute;n activados en el registro de estado del procesador.&lt;/p&gt;
&lt;p&gt;Sin embargo, estos no son todos los registros que componen el banco de registros del procesador. Por defecto, Windbg aplica una m&amp;aacute;scara al banco de registros que sirve para que solamente se muestren los registros de enteros del procesador. El comando &lt;strong&gt;rm&lt;/strong&gt; devuelve cu&amp;aacute;l es la m&amp;aacute;scara que est&amp;aacute; siendo aplicada:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; rm&lt;br /&gt;Register output mask is 9:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 - Integer state (32-bit)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8 - Segment registers&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;En este ejemplo vemos que se est&amp;aacute;n mostrando los registros de enteros y los registros de segmento del procesador. Si en nuestra depuraci&amp;oacute;n necesit&amp;aacute;ramos echar un vistazo tambi&amp;eacute;n&amp;nbsp;a los registros de punto flotante, el comando&lt;strong&gt; rm ?&lt;/strong&gt; nos puede ayudar a descubrir qu&amp;eacute; m&amp;aacute;scara aplicar:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; rm ?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 - Integer state (32-bit) or&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 - Integer state (64-bit), 64-bit takes precedence&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4 - Floating-point state&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8 - Segment registers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10 - MMX registers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 20 - Debug registers and, in kernel, CR4&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 40 - SSE XMM registers&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Como queremos establecer el bit&amp;nbsp;0 (registros de enteros), el bit 2 (registros de punto flotante) y el bit 3 (registros de segmento), formamos el n&amp;uacute;mero binario 1101, que en hexadecimal es el n&amp;uacute;mero D. Ejecutamos&lt;strong&gt; rm&amp;nbsp;D&lt;/strong&gt; y a continuaci&amp;oacute;n&lt;strong&gt; rm&lt;/strong&gt; para ver la m&amp;aacute;scara aplicada:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; rm D&lt;br /&gt;0:000&amp;gt; rm&lt;br /&gt;Register output mask is d:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 - Integer state (32-bit)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4 - Floating-point state&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8 - Segment registers&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Comprobamos que efectivamente lo hemos hecho bien:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; r&lt;br /&gt;eax=00000000 ebx=00000000 ecx=0012fb0c edx=777e64f4 esi=fffffffe edi=00000000&lt;br /&gt;eip=7783e60e esp=0012fb28 ebp=0012fb54 iopl=0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nv up ei pl zr na pe nc&lt;br /&gt;cs=001b&amp;nbsp; ss=0023&amp;nbsp; ds=0023&amp;nbsp; es=0023&amp;nbsp; fs=003b&amp;nbsp; gs=0000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; efl=00000246&lt;br /&gt;fpcw=027F: rn 53 puozdi&amp;nbsp; fpsw=0000: top=0 cc=0000 --------&amp;nbsp; fptw=FFFF&lt;br /&gt;fopcode=0000&amp;nbsp; fpip=0000:00000000&amp;nbsp; fpdp=0000:00000000&lt;br /&gt;st0= 0.000000000000000000000e+0000&amp;nbsp; st1= 0.000000000000000000000e+0000&lt;br /&gt;st2= 0.000000000000000000000e+0000&amp;nbsp; st3= 0.000000000000000000000e+0000&lt;br /&gt;st4= 0.000000000000000000000e+0000&amp;nbsp; st5= 0.000000000000000000000e+0000&lt;br /&gt;st6= 0.000000000000000000000e+0000&amp;nbsp; st7= 0.000000000000000000000e+0000&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Es destacable comentar que en Windbg existe el concepto de &lt;em&gt;pseudo-registros&lt;/em&gt;. Dependiendo de la arquitectura de la computadora en la que estemos trabajando, los nombres de los registros pueden cambiar, pese a que su sem&amp;aacute;ntica sea la misma. Por ejemplo, en la arquitectura x86 el registro de instrucciones es el registro Eip, mientras que en la arquitectura x64 es el registro Rip. Para evitar tener que memorizar este tipo de cosas, podemos hacer uso del &lt;em&gt;pseudo-registro&lt;/em&gt; $ip. Aparte de este, dos de los &lt;em&gt;pseudo-registros&lt;/em&gt; que m&amp;aacute;s uso son $ra, que sirve para hacer referencia a la direcci&amp;oacute;n de retorno de la funci&amp;oacute;n en curso, y $retreg, que hace referencia al registro que almacena el resultado de una funci&amp;oacute;n, una vez que esta ha finalizado (en el caso de la arquitectura x86, se trata del registro f&amp;iacute;sico Eax).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vista del c&amp;oacute;digo en ejecuci&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Otro aspecto muy importante durante una sesi&amp;oacute;n de depuraci&amp;oacute;n es tener acceso al c&amp;oacute;digo ensamblador que est&amp;aacute; siendo ejecutado por el procesador. Windbg nos permite desensamblar el c&amp;oacute;digo m&amp;aacute;quina (binario)&amp;nbsp;presente en la memoria del computador para convertirlo al lenguaje ensamblador, mucho m&amp;aacute;s legible.&lt;/p&gt;
&lt;p&gt;Para desensamblar las instrucciones de la funci&amp;oacute;n en curso, podemos hacer uso del comando &lt;strong&gt;uf .&lt;/strong&gt;&amp;nbsp;(&lt;em&gt;Unassemble function&lt;/em&gt;). El punto que hay despu&amp;eacute;s de &amp;quot;uf&amp;quot; sirve como referencia a la instrucci&amp;oacute;n presente en el registro de instrucciones, pero en general despu&amp;eacute;s de &amp;quot;uf&amp;quot; puede ponerse cualquier otra&amp;nbsp;direcci&amp;oacute;n de memoria.&lt;/p&gt;
&lt;p&gt;Si queremos desensamblar instrucciones a partir de la instrucci&amp;oacute;n actual (para ver qu&amp;eacute; c&amp;oacute;digo va a ejecutar el procesador inmediatamente despu&amp;eacute;s), podemos hacer uso del comando &lt;strong&gt;u .&lt;/strong&gt; (o &lt;strong&gt;u $ip&lt;/strong&gt;, haciendo uso de los &lt;em&gt;pseudo-registros&lt;/em&gt; comentados anteriormente). Por defecto, si no se indica nada, Windbg desensambla 8 instrucciones.&lt;/p&gt;
&lt;p&gt;Si en cambio&amp;nbsp;quisi&amp;eacute;ramos desensamblar 8 instrucciones &lt;em&gt;anteriores&lt;/em&gt; a la instrucci&amp;oacute;n actual, el comando a ejecutar ser&amp;iacute;a &lt;strong&gt;ub $ip&lt;/strong&gt; Esto deber&amp;iacute;a ser uno de los primeros pasos que deber&amp;iacute;amos dar si nos&amp;nbsp;hemos encontrado con un estado de la m&amp;aacute;quina incorrecto y queremos saber por qu&amp;eacute; la m&amp;aacute;quina ha llegado a tal estado, es decir,&amp;nbsp;qu&amp;eacute; se ha estado ejecutando antes de que ocurriera el desastre.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Examinar el contenido de la memoria&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;La memoria de un computador que est&amp;aacute; ejecutando un programa contiene regiones con diferentes&amp;nbsp;tipos de informaci&amp;oacute;n. Pueden contener el c&amp;oacute;digo del programa,&amp;nbsp;datos, la pila de ejecuci&amp;oacute;n, &lt;em&gt;heap&lt;/em&gt;, etc.&lt;/p&gt;
&lt;p&gt;La extensi&amp;oacute;n de Windbg &lt;strong&gt;!address &lt;em&gt;&amp;lt;Direcci&amp;oacute;n&amp;gt;&lt;/em&gt;&lt;/strong&gt; facilita el saber de qu&amp;eacute; tipo es la regi&amp;oacute;n que engloba a una direcci&amp;oacute;n de memoria determinada. Por ejemplo:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; !address $ip&lt;br /&gt;&amp;nbsp;ProcessParametrs 007117a8 in range 00710000 00715000&lt;br /&gt;&amp;nbsp;Environment 00710810 in range 00710000 00715000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 777a0000 : 777a1000 - 000d6000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 01000000 MEM_IMAGE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Protect&amp;nbsp; 00000020 PAGE_EXECUTE_READ&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp; 00001000 MEM_COMMIT&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Usage&amp;nbsp;&amp;nbsp;&amp;nbsp; RegionUsageImage&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FullPath ntdll.dll&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; se puede ver, entre otras cosas,&amp;nbsp;como la direcci&amp;oacute;n de memoria que se est&amp;aacute; ejecutando actualmente contiene c&amp;oacute;digo (&amp;quot;RegionUsageImage&amp;quot;), lo que es algo completamente normal.&lt;/p&gt;
&lt;p&gt;Veamos qu&amp;eacute; ocurre si ejecutamos ese mismo&amp;nbsp;comando pero haciendo referencia esta vez al puntero de pila:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;0:000&amp;gt; !address @esp&lt;br /&gt;&amp;nbsp;ProcessParametrs 007117a8 in range 00710000 00715000&lt;br /&gt;&amp;nbsp;Environment 00710810 in range 00710000 00715000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00030000 : 0012e000 - 00002000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 00020000 MEM_PRIVATE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Protect&amp;nbsp; 00000004 PAGE_READWRITE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; State&amp;nbsp;&amp;nbsp;&amp;nbsp; 00001000 MEM_COMMIT&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Usage&amp;nbsp;&amp;nbsp;&amp;nbsp; RegionUsageStack&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Pid.Tid&amp;nbsp; 16fc.c4c&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Podemos ver que, obviamente, se trata de&amp;nbsp;una regi&amp;oacute;n de la pila (&amp;quot;RegionUsageStack&amp;quot;).&lt;/p&gt;
&lt;p&gt;El comando !address personalmente lo uso cuando me encuentro con una direcci&amp;oacute;n de memoria involucrada en alg&amp;uacute;n problema y quiero saber qu&amp;eacute; tipo de contenido tiene. Podr&amp;iacute;a ser que fuera una direcci&amp;oacute;n inv&amp;aacute;lida, o bien que el procesador estuviera intentando ejecutar c&amp;oacute;digo desde una regi&amp;oacute;n de memoria marcada como contenedora de datos, por culpa de&amp;nbsp;alg&amp;uacute;n puntero que apunte a donde no debe o qui&amp;eacute;n sabe si por alg&amp;uacute;n fallo de hardware. Otro uso que le doy a la extensi&amp;oacute;n !address es saber qu&amp;eacute; tipo de fuga de memoria tiene un proceso. Si nos encontramos con un proceso que consume memoria de manera desmedida, existe la posibilidad de que tenga una fuga de memoria. Como un proceso puede fugar diversos tipos de memoria, una manera de saber qu&amp;eacute; tipo de memoria est&amp;aacute; utilizando sin liberar es ejecutar el comando !address sin par&amp;aacute;metros para ver un resumen estad&amp;iacute;stico del consumo de memoria de un proceso.&lt;/p&gt;
&lt;p&gt;Para ver lo que contiene una direcci&amp;oacute;n de memoria, Windbg nos proporciona la familia de comandos &lt;strong&gt;d*&lt;/strong&gt;, que tienen la sintaxis&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;d&lt;em&gt;&amp;lt;Tipo&amp;gt;&lt;/em&gt; &lt;em&gt;&amp;lt;Rango_direcciones&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;Tipo&amp;gt;&lt;/em&gt; sirve para ayudar al depurador a interpretar el contenido de la memoria situado en el rango &lt;em&gt;&amp;lt;Rango_direcciones&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;En la documentaci&amp;oacute;n de Windbg est&amp;aacute; disponible una lista con todos los tipos de comando d* que se pueden usar, seg&amp;uacute;n lo que queramos mostrar sean valores ASCII, Unicode, palabras dobles, valores en punto flotante, etc. Si el resultado de un comando d* es una ristra de s&amp;iacute;mbolos &amp;quot;?&amp;quot;, esto quiere decir que Windbg ha intentado acceder a una posici&amp;oacute;n inv&amp;aacute;lida de memoria. Esto merecer&amp;iacute;a una investigaci&amp;oacute;n m&amp;aacute;s en profundidad usando alguno de los comandos que se han descrito anteriormente.&lt;/p&gt;
&lt;p&gt;En el pr&amp;oacute;ximo art&amp;iacute;culo se tratar&amp;aacute;n en detalle&amp;nbsp;los comandos de Windbg que nos permiten explorar dos estructuras muy importantes en el estado de una m&amp;aacute;quina que est&amp;aacute; siendo depurada: El bloque de control de proceso (y de hilo) y la pila de ejecuci&amp;oacute;n.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1738116" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Windbg/default.aspx">Windbg</category><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Tutorial sobre Windbg [Parte III]</title><link>http://msmvps.com/blogs/dmartin/archive/2009/08/13/tutorial-sobre-windbg-parte-iii.aspx</link><pubDate>Thu, 13 Aug 2009 21:44:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1715444</guid><dc:creator>dmartin</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/rsscomments.aspx?PostID=1715444</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/commentapi.aspx?PostID=1715444</wfw:comment><comments>http://msmvps.com/blogs/dmartin/archive/2009/08/13/tutorial-sobre-windbg-parte-iii.aspx#comments</comments><description>&lt;p&gt;En el anterior art&amp;iacute;culo vimos c&amp;oacute;mo abrir nuestra aplicaci&amp;oacute;n&amp;nbsp;en modo usuario dentro de&amp;nbsp;Windbg y comprendimos mejor qu&amp;eacute; es lo que ocurre cuando este se hace cargo de nuestra aplicaci&amp;oacute;n. Ahora tenemos a nuestra disposici&amp;oacute;n una ventana con salida de texto y una caja de entrada de comandos pero, &amp;iquest;qu&amp;eacute; podemos hacer?&lt;/p&gt;
&lt;p&gt;Es importante saber que podemos manejar la ventana de Windbg e introducir comandos en su caja de texto porque nuestra aplicaci&amp;oacute;n est&amp;aacute; detenida debido a la excepci&amp;oacute;n STATUS_BREAKPOINT que se recibe por defecto nada m&amp;aacute;s abrir la aplicaci&amp;oacute;n en Windbg. As&amp;iacute; pues, lo primero que buscamos es una forma de permitir que&amp;nbsp;nuestra aplicaci&amp;oacute;n&amp;nbsp;contin&amp;uacute;e con su ejecuci&amp;oacute;n. El comando &lt;strong&gt;g&lt;/strong&gt; (o presionar F5) consigue esto mismo. Este comando hace que la aplicaci&amp;oacute;n siga ejecut&amp;aacute;ndose hasta que se encuentre con alguna condici&amp;oacute;n de parada (posteriormente aprenderemos a configurar esto), o bien ocurra alg&amp;uacute;n tipo de excepci&amp;oacute;n (por ejemplo, la aplicaci&amp;oacute;n quiere acceder a una posici&amp;oacute;n de memoria incorrecta).&lt;/p&gt;
&lt;p&gt;El comando g admite alguna que otra variante. Si, por ejemplo, queremos que nuestra aplicaci&amp;oacute;n siga ejecut&amp;aacute;ndose hasta que se alcance una determinada&amp;nbsp;posici&amp;oacute;n de memoria, podemos usar la sintaxis &lt;strong&gt;g &lt;em&gt;&amp;lt;Direcci&amp;oacute;n&amp;gt;&lt;/em&gt;.&lt;/strong&gt; Por otra parte, si solo nos interesa que contin&amp;uacute;e la ejecuci&amp;oacute;n hasta que finalice la funci&amp;oacute;n en curso, podemos usar el comando &lt;strong&gt;gu&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;C&amp;oacute;mo detener la ejecuci&amp;oacute;n de la aplicaci&amp;oacute;n en los momentos que nos interese?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Uno de los aspectos m&amp;aacute;s importantes en la depuraci&amp;oacute;n de aplicaciones es la creaci&amp;oacute;n de &lt;em&gt;breakpoints&lt;/em&gt;. Windbg nos proporciona los medios necesarios para crear todo tipo de &lt;em&gt;breakpoints&lt;/em&gt;, desde los m&amp;aacute;s sencillos hasta los m&amp;aacute;s imaginativos. Saber qu&amp;eacute; tipo de &lt;em&gt;breakpoint&lt;/em&gt; se debe usar en cada caso nos permitir&amp;aacute; ahorrar horas de trabajo infructuoso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Establecer &lt;em&gt;breakpoints&lt;/em&gt; en c&amp;oacute;digo&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El primer tipo de &lt;em&gt;breakpoints&lt;/em&gt; que voy a tratar son los cl&amp;aacute;sicos &lt;em&gt;breakpoints&lt;/em&gt; en c&amp;oacute;digo. Como su nombre indica, son &lt;em&gt;breakpoints&lt;/em&gt; que se alcanzan en una determinada direcci&amp;oacute;n de c&amp;oacute;digo (t&amp;iacute;picamente el inicio de una funci&amp;oacute;n, pero podr&amp;iacute;a ser cualquier otra cosa). El comando de Windbg para crear este tipo de &lt;em&gt;breakpoints&lt;/em&gt; es &lt;strong&gt;bp&lt;/strong&gt;. Este comando recibe como par&amp;aacute;metro la direcci&amp;oacute;n en la que queremos detener la ejecuci&amp;oacute;n del programa y, opcionalmente, algunas restricciones y comandos que se ejecuten autom&amp;aacute;ticamente cuando se llegue al &lt;em&gt;breakpoint&lt;/em&gt;. El abanico de restricciones que se pueden establecer conforma un amplio tipo de &lt;em&gt;breakpoints&lt;/em&gt; que se conocen como &lt;em&gt;breakpoints condicionales&lt;/em&gt;, que se tratar&amp;aacute;n m&amp;aacute;s adelante en este art&amp;iacute;culo. Por ejemplo, si introducimos el comando &lt;strong&gt;bp MiAplicacion!MiFuncion &amp;quot;kb&amp;quot;&lt;/strong&gt; y pulsamos INTRO, lo que va a ocurrir es que cuando reanudemos la ejecuci&amp;oacute;n de nuestra aplicaci&amp;oacute;n (con el comando g, como ya sabe) y se llegue a la funci&amp;oacute;n cuyo s&amp;iacute;mbolo es &lt;em&gt;MiAplicacion!MiFuncion&lt;/em&gt;, el depurador informar&amp;aacute; sobre esto y autom&amp;aacute;ticamente ejecutar&amp;aacute; el comando &lt;strong&gt;kb&lt;/strong&gt;, que como ver&amp;aacute; posteriormente, sirve para ver el estado de una estructura de datos muy importante para un proceso/hilo, la pila de ejecuci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Una cosa que quiz&amp;aacute; se pregunte es, &amp;iquest;c&amp;oacute;mo averiguar qu&amp;eacute; s&amp;iacute;mbolo de funci&amp;oacute;n me interesa? Una opci&amp;oacute;n de fuerza bruta consiste en mostrar en pantalla todos los s&amp;iacute;mbolos que cumplan con un determinado patr&amp;oacute;n y buscar aquella funci&amp;oacute;n que puede interesarnos. El comando &lt;strong&gt;x&lt;/strong&gt; consigue esto mismo. Por ejemplo, si quisiera mostrar los s&amp;iacute;mbolos de MiAplicacion que contuvieran la palabra &amp;quot;Window&amp;quot;, podr&amp;iacute;amos usar la sintaxis &lt;strong&gt;x MiAplicacion!*Window*&lt;/strong&gt;. Al pulsar INTRO, WIndbg buscar&amp;aacute; entre los s&amp;iacute;mbolos disponibles aquellos que coincidan con el patr&amp;oacute;n establecido y los mostrar&amp;aacute; en pantalla junto con sus correspondientes direcciones. Si bien esta aproximaci&amp;oacute;n de fuerza bruta es &amp;uacute;til en algunos casos, lo m&amp;aacute;s probable es que el s&amp;iacute;mbolo en el que quiera detener la ejecuci&amp;oacute;n del programa lo obtenga de los resultados que le proporcione Windbg al ejecutar otros comandos.&lt;/p&gt;
&lt;p&gt;Por supuesto, tambi&amp;eacute;n&amp;nbsp;podemos crear m&amp;uacute;ltiples &lt;em&gt;breakpoints&lt;/em&gt; sin necesidad de tener que&amp;nbsp;establecerlos uno a uno. Supongamos que nuestra aplicaci&amp;oacute;n tiene alg&amp;uacute;n problema a la hora de escribir ciertos archivos en el disco. Podr&amp;iacute;amos suponer que los s&amp;iacute;mbolos que m&amp;aacute;s nos interesa son los de aquellas funciones que contengan la palabra &amp;quot;Write&amp;quot;. Para agregar &lt;em&gt;breakpoints&lt;/em&gt; para todos y cada uno de los s&amp;iacute;mbolos que cumplan con este patr&amp;oacute;n, podemos usar el comando &lt;strong&gt;bm&lt;/strong&gt;, de la siguiente manera: &lt;strong&gt;bm MiAplicacion!*Write*&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si la aplicaci&amp;oacute;n que se est&amp;aacute; depurando tiene un cierto grado de complejidad, es bastante probable que haga uso de librer&amp;iacute;as din&amp;aacute;micas (DLL) cuya carga no se conoce de antemano y se produce en tiempo de ejecuci&amp;oacute;n. Por este motivo, si necesitara parar la ejecuci&amp;oacute;n en alguna funci&amp;oacute;n dentro de esas librer&amp;iacute;as din&amp;aacute;micas no le ser&amp;iacute;a posible, pues Windbg no conoce la direcci&amp;oacute;n de la funci&amp;oacute;n donde debe detenerse. A fin de cuentas, Windbg solo entiende de direcciones de memoria. Para dar soluci&amp;oacute;n a este problema, existe el comando &lt;strong&gt;bu&lt;/strong&gt;. Por ejemplo, si nuestra aplicaci&amp;oacute;n hiciera uso de una DLL para calcular los primeros d&amp;iacute;gitos decimales del n&amp;uacute;mero pi,&amp;nbsp;podemos&amp;nbsp;detener la ejecuci&amp;oacute;n en dicha funci&amp;oacute;n ejecutando el comando &lt;strong&gt;bu MiDLL!CalcularPI&lt;/strong&gt;. Una vez introducido el comando lo que ocurre es que Windbg sabe que justo en el momento en que el m&amp;oacute;dulo correspondiente a esa DLL (MiDLL)&amp;nbsp;se cargue en memoria (eche un vistazo al art&amp;iacute;culo anterior para obtener m&amp;aacute;s informaci&amp;oacute;n sobre la carga de m&amp;oacute;dulos), debe crear el correspondiente &lt;em&gt;breakpoint&lt;/em&gt;, ahora que sabe cu&amp;aacute;l es su direcci&amp;oacute;n de memoria.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Establecer &lt;em&gt;breakpoints&lt;/em&gt; por acceso a un dato&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En muchos casos vamos a necesitar parar la ejecuci&amp;oacute;n de nuestro programa no cuando se llegue a una porci&amp;oacute;n de c&amp;oacute;digo, sino cuando se acceda a un dato. El escenario t&amp;iacute;pico de esto es una aplicaci&amp;oacute;n que en apariencia sufre un &lt;em&gt;bug&lt;/em&gt; del tipo &lt;em&gt;buffer overrun&lt;/em&gt;. B&amp;aacute;sicamente este tipo de problemas implica que se sobreescriban posiciones de memoria contiguas a las de una porci&amp;oacute;n de datos del programa, por ejemplo un vector. En esta situaci&amp;oacute;n, quiz&amp;aacute; necesitemos indagar sobre todos y cada uno de los accesos que se produzcan hacia este vector. Podemos lograr esto ejecutando el comando &lt;strong&gt;ba w4 miVector&lt;/strong&gt;, suponiendo que el s&amp;iacute;mbolo &lt;em&gt;miVector&lt;/em&gt; sea el correspondiente al vector que queremos examinar. Por supuesto, podemos sustituir el s&amp;iacute;mbolo por una direcci&amp;oacute;n de memoria. &amp;iquest;Qu&amp;eacute; significa el &lt;strong&gt;w4&lt;/strong&gt; que aparece como primer par&amp;aacute;metro del comando ba? &amp;quot;W&amp;quot; indica que estamos buscando accesos de tipo escritura. Otras posibilidades son &amp;quot;E&amp;quot; (ejecuci&amp;oacute;n) y &amp;quot;R&amp;quot; (lectura). El &amp;quot;4&amp;quot; indica el n&amp;uacute;mero de bytes que queremos monitorizar. En las arquitecturas de 32 bits este valor puede ser 1, 2 &amp;oacute; 4. En las de 64 bits existe la posibilidad de establecer tambi&amp;eacute;n 8 bytes como tama&amp;ntilde;o.&lt;/p&gt;
&lt;p&gt;Como habr&amp;aacute; podido observar, la creaci&amp;oacute;n de &lt;em&gt;breakpoints&lt;/em&gt; es un aspecto complejo de Windbg. La capacidad m&amp;aacute;s interesante a mi juicio es la posibilidad de crear &lt;em&gt;breakpoints&lt;/em&gt; condicionales. Como vimos, para crear un &lt;em&gt;breakpoint&lt;/em&gt; se usa el comando &lt;strong&gt;bp&lt;/strong&gt;. Uno de los par&amp;aacute;metros de este comando va entrecomillado y representa una condici&amp;oacute;n adicional a la condici&amp;oacute;n est&amp;aacute;ndar (la llegada&amp;nbsp;a la correspondiente funci&amp;oacute;n). Incluso se puede omitir la funci&amp;oacute;n y dejar solamente la condici&amp;oacute;n. Supongamos que nuestro programa tiene una variable &lt;em&gt;Contador&lt;/em&gt; que va increment&amp;aacute;ndose cada vez que se itera en un bucle, por ejemplo. Quiz&amp;aacute; estemos interesados en parar la ejecuci&amp;oacute;n de nuestra aplicaci&amp;oacute;n cuando la variable Contador adquiera el valor 10, que sabemos que es el valor de finalizaci&amp;oacute;n del bucle. Para ello podr&amp;iacute;amos usar esta sintaxis:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;bp &amp;quot;.if (poi(Contador)==10) {.echo Fin de cuenta }&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando establece un &lt;em&gt;breakpoint&lt;/em&gt; (bp) cuya condici&amp;oacute;n (.if) es que la variable &lt;em&gt;Contador&lt;/em&gt; sea igual al n&amp;uacute;mero 10. En tal caso, sacamos por pantalla (.echo) la cadena &amp;quot;Fin de cuenta&amp;quot;. El comando &lt;strong&gt;poi&lt;/strong&gt; se usa porque de no hacerlo, la variable &lt;em&gt;Contador&lt;/em&gt; ser&amp;iacute;a interpretada como una direcci&amp;oacute;n de memoria, y esto no es lo que queremos. Como queremos tener acceso al contenido de esa direcci&amp;oacute;n de memoria, los programadores de C que est&amp;eacute;n leyendo esto contestar&amp;aacute;n r&amp;aacute;pidamente que necesitamos &lt;em&gt;desreferenciar&lt;/em&gt; ese acceso. En C esto se hace con el operador&amp;nbsp;* y en Windbg con poi.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C&amp;oacute;mo mostrar un listado de los &lt;em&gt;breakpoints&lt;/em&gt; que hemos a&amp;ntilde;adido&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Una vez que hayamos establecido los &lt;em&gt;breakpoints&lt;/em&gt; que necesitemos, es posible que queramos ver un listado de los mismos. Puede usar para ello el comando &lt;strong&gt;bl&lt;/strong&gt; o bien usar la interfaz gr&amp;aacute;fica de Windbg: Si pulsa F9, se abrir&amp;aacute; el cuadro de di&amp;aacute;logo &lt;em&gt;Breakpoints&lt;/em&gt;, desde el que podr&amp;aacute; ver un listado de los &lt;em&gt;breakpoints&lt;/em&gt; asociados a la sesi&amp;oacute;n de depuraci&amp;oacute;n actual y crear de manera m&amp;aacute;s o menos intuitiva otros nuevos. Mi consejo es usar siempre que sea posible&amp;nbsp;la propia consola de comandos de Windbg, pues suele ofrecer m&amp;aacute;s flexibilidad que la interfaz gr&amp;aacute;fica, pero comento esta posibilidad por si alguien se siente m&amp;aacute;s c&amp;oacute;modo/a usando cuadros de di&amp;aacute;logo.&lt;/p&gt;
&lt;p&gt;En este art&amp;iacute;culo hemos aprendido a crear &lt;em&gt;breakpoints&lt;/em&gt; b&amp;aacute;sicos y sencillos y otros no tan sencillos. Hemos visto tambi&amp;eacute;n que la potencia de los &lt;em&gt;breakpoints&amp;nbsp;reside &lt;/em&gt;en&lt;em&gt; &lt;/em&gt;los &lt;em&gt;breakpoints&lt;/em&gt; condicionales, pues el &amp;uacute;nico l&amp;iacute;mite pr&amp;aacute;cticamente es el de nuestra imaginaci&amp;oacute;n. La documentaci&amp;oacute;n de Windbg (F1)&amp;nbsp;ofrece informaci&amp;oacute;n m&amp;aacute;s detallada sobre cada uno de los comandos que he tratado aqu&amp;iacute;, pero espero esto que sirva como punto de partida para sacarle el mayor provecho posible a esta funcionalidad que nos proporciona el sistema operativo en conjunci&amp;oacute;n con Windbg. En los pr&amp;oacute;ximos art&amp;iacute;culos veremos comandos que nos permiten examinar el estado de la m&amp;aacute;quina. Para comprender mejor la salida de estos comandos, se explicar&amp;aacute;n tambi&amp;eacute;n algunos conceptos importantes de la estructura de un computador y del sistema operativo, como son el repertorio de registros, la pila de ejecuci&amp;oacute;n o el bloque de control de un proceso/hilo.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1715444" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Windbg/default.aspx">Windbg</category><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Tutorial sobre Windbg [Parte II]</title><link>http://msmvps.com/blogs/dmartin/archive/2009/05/15/tutorial-sobre-windbg-parte-ii.aspx</link><pubDate>Fri, 15 May 2009 19:21:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1692497</guid><dc:creator>dmartin</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/rsscomments.aspx?PostID=1692497</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/commentapi.aspx?PostID=1692497</wfw:comment><comments>http://msmvps.com/blogs/dmartin/archive/2009/05/15/tutorial-sobre-windbg-parte-ii.aspx#comments</comments><description>&lt;p&gt;En la primera parte de esta serie de art&amp;iacute;culos aprendi&amp;oacute; a instalar Windbg y a configurar un aspecto b&amp;aacute;sico, los s&amp;iacute;mbolos de depuraci&amp;oacute;n. En este art&amp;iacute;culo veremos c&amp;oacute;mo configurar otros aspectos menores de Windbg, pero que le pueden resultar necesarios, y depuraremos la primera aplicaci&amp;oacute;n en modo usuario.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configurar la ruta de c&amp;oacute;digo fuente&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si est&amp;aacute; depurando una aplicaci&amp;oacute;n que no haya desarrollado, es probable que no disponga del c&amp;oacute;digo fuente de la misma; sin embargo, si estuviera depurando una aplicaci&amp;oacute;n de la que dispone el c&amp;oacute;digo fuente, es muy buena idea configurar Windbg para que sea capaz de&amp;nbsp;usar toda esa informaci&amp;oacute;n y&amp;nbsp;mostrar la ejecuci&amp;oacute;n paso a paso en formato de instrucciones de c&amp;oacute;digo fuente, no instrucciones m&amp;aacute;quina. Para configurar este aspecto, despliegue el men&amp;uacute; &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Source File Path&lt;/em&gt; (o pulse Ctrl+P). Tambi&amp;eacute;n puede usar el comando &lt;strong&gt;.srcpath &lt;em&gt;&amp;lt;Ruta_c&amp;oacute;digo_fuente&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para que el depurador muestre instrucciones de c&amp;oacute;digo fuente y no instrucciones m&amp;aacute;quina es necesario adem&amp;aacute;s que los s&amp;iacute;mbolos de depuraci&amp;oacute;n contengan informaci&amp;oacute;n acerca del fichero fuente y n&amp;uacute;mero de l&amp;iacute;nea que se corresponde con un determinado s&amp;iacute;mbolo. Estos s&amp;iacute;mbolos, denominados normalmente s&amp;iacute;mbolos privados, no suelen estar a disposici&amp;oacute;n de los usuarios ajenos a la empresa creadora del software en cuesti&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configurar la ruta de los m&amp;oacute;dulos&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En la mayor&amp;iacute;a de ocasiones, Windbg es capaz por s&amp;iacute; solo de encontrar las im&amp;aacute;genes de los ejecutables implicados en una sesi&amp;oacute;n de depuraci&amp;oacute;n. En determinados casos, como por ejemplo cuando se est&amp;aacute; depurando un volcado de memoria peque&amp;ntilde;o o &lt;em&gt;minidump&lt;/em&gt; (la depuraci&amp;oacute;n de volcados de memoria se tratar&amp;aacute; en un posterior art&amp;iacute;culo), es necesario indicarle al depurador d&amp;oacute;nde debe buscar los m&amp;oacute;dulos (.exe, .dll, .sys, etc.). Para ello, abra &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Image File Path&lt;/em&gt; (o pulse Ctrl+I). Como siempre, si desea lograr esto mediante un comando de Windbg, ejecute &lt;strong&gt;.exepath &lt;em&gt;&amp;lt;Ruta_ejecutables&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ejecutar una aplicaci&amp;oacute;n dentro del depurador&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ya est&amp;aacute; en condiciones de depurar su primera aplicaci&amp;oacute;n en Windbg y para ello vamos a ejecutar la calculadora de Windows dentro de Windbg.&lt;/p&gt;
&lt;p&gt;Abra &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Open Executable&lt;/em&gt; (o pulse Ctrl+E) y busque el ejecutable Calc.exe dentro del directorio&amp;nbsp;\Windows\system32\. En este caso deje desmarcada la casilla &lt;em&gt;Debug child processes also&lt;/em&gt;, que sirve para depurar no solo el proceso principal que cree ese ejecutable sino sus procesos hijos tambi&amp;eacute;n. Haga clic sobre &lt;em&gt;Abrir&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;La pantalla de Windbg se rellenar&amp;aacute; con un texto similar al siguiente:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;p&gt;Microsoft (R) Windows Debugger Version 6.11.0001.404 X86&lt;br /&gt;Copyright (c) Microsoft Corporation. All rights reserved.&lt;/p&gt;
&lt;p&gt;CommandLine: C:\WINDOWS\system32\calc.exe&lt;br /&gt;Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols&lt;br /&gt;Executable search path is: &lt;br /&gt;ModLoad: 01000000 0101f000&amp;nbsp;&amp;nbsp; calc.exe&lt;br /&gt;ModLoad: 7c910000 7c9c5000&amp;nbsp;&amp;nbsp; ntdll.dll&lt;br /&gt;ModLoad: 7c800000 7c903000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\kernel32.dll&lt;br /&gt;ModLoad: 7e6a0000 7eec1000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\SHELL32.dll&lt;br /&gt;ModLoad: 77da0000 77e4c000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\ADVAPI32.dll&lt;br /&gt;ModLoad: 77e50000 77ee2000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\RPCRT4.dll&lt;br /&gt;ModLoad: 77fc0000 77fd1000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\Secur32.dll&lt;br /&gt;ModLoad: 77ef0000 77f39000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\GDI32.dll&lt;br /&gt;ModLoad: 7e390000 7e421000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\USER32.dll&lt;br /&gt;ModLoad: 77be0000 77c38000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\msvcrt.dll&lt;br /&gt;ModLoad: 77f40000 77fb6000&amp;nbsp;&amp;nbsp; C:\WINDOWS\system32\SHLWAPI.dll&lt;br /&gt;(23c.24c): Break instruction exception - code 80000003 (first chance)&lt;br /&gt;eax=001a1eb4 ebx=7ffdb000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4&lt;br /&gt;eip=7c91120e esp=0007fb20 ebp=0007fc94 iopl=0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nv up ei pl nz na po nc&lt;br /&gt;cs=001b&amp;nbsp; ss=0023&amp;nbsp; ds=0023&amp;nbsp; es=0023&amp;nbsp; fs=003b&amp;nbsp; gs=0000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; efl=00000202&lt;br /&gt;ntdll!DbgBreakPoint:&lt;br /&gt;7c91120e cc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/p&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Analicemos detalladamente toda esta informaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;La l&amp;iacute;nea &lt;em&gt;CommandLine&lt;/em&gt; nos est&amp;aacute; indicando el archivo que vamos a ejecutar dentro de Windbg, en este caso la calculadora de Windows. A continuaci&amp;oacute;n se muestra la ruta establecida para los s&amp;iacute;mbolos y la ruta de b&amp;uacute;squeda de m&amp;oacute;dulos ejecutables, que en este caso est&amp;aacute; vac&amp;iacute;a porque no la hemos establecido desde la opci&amp;oacute;n &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Image File Path&lt;/em&gt;. Seguidamente el depurador ha registrado informaci&amp;oacute;n sobre la carga de una serie de m&amp;oacute;dulos de los que depende la calculadora de Windows. Para ver las dependencias de un m&amp;oacute;dulo yo recomiendo usar la herramienta Dependency Walker (&lt;a href="http://www.dependencywalker.com/"&gt;http://www.dependencywalker.com/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;La siguiente l&amp;iacute;nea, &lt;em&gt;(23c.24c): Break instruction exception - code 80000003 (first chance)&lt;/em&gt;, da pie a comentar bastantes cosas:&lt;/p&gt;
&lt;p&gt;La sintaxis (23c.24c) la va a encontrar no pocas veces en Windbg. Hace referencia a un hilo dentro de un proceso. 23c es el identificador de proceso (PID), en formato hexadecimal. En este caso es el PID del proceso Calc.exe. 24c hace referencia al identificador de hilo (TID), en formato hexadecimal tambi&amp;eacute;n. La excepci&amp;oacute;n recibida en este caso es &amp;quot;Break instruction&amp;quot; (STATUS_BREAKPOINT), identificada por el c&amp;oacute;digo hexadecimal 0x80000003. Vamos a ver qu&amp;eacute; ocurre &amp;quot;por lo bajo&amp;quot; para explicar por qu&amp;eacute; ha ocurrido esto:&lt;/p&gt;
&lt;p&gt;Cuando hemos seleccionado el ejecutable Calc.exe y hemos hecho clic sobre &lt;em&gt;Abrir&lt;/em&gt;, Windbg ha llamado a la API &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms682425.aspx"&gt;CreateProcess&lt;/a&gt; con el sexto par&amp;aacute;metro establecido a DEBUG_PROCESS. Esto permite crear un proceso e indicarle a Windows que deseamos depurarlo. Pero depurar un proceso requiere de algo m&amp;aacute;s. Requiere que el programa depurador reciba una serie de eventos procedentes de la ejecuci&amp;oacute;n de la aplicaci&amp;oacute;n y los muestre al usuario o los trate de manera conveniente. Lo que ocurre durante una sesi&amp;oacute;n de depuraci&amp;oacute;n se puede entender como un bucle en el cual el depurador espera eventos de depuraci&amp;oacute;n mediante la API &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms681423(VS.85).aspx"&gt;WaitForDebugEvent&lt;/a&gt;, los trata de manera conveniente, y continua la ejecuci&amp;oacute;n del programa mediante la API &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms679285(VS.85).aspx"&gt;ContinueDebugEvent&lt;/a&gt;. Este bucle&amp;nbsp;se repite indefinidamente hasta que o bien&amp;nbsp;la aplicaci&amp;oacute;n que est&amp;aacute; siendo depurada desaparece de la&amp;nbsp;memoria, o bien finaliza correctamente su ejecuci&amp;oacute;n, o bien desacoplamos el depurador mediante el comando &lt;em&gt;Debug&lt;/em&gt;, &lt;em&gt;Detach Debugee&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;La frase &lt;em&gt;(first chance)&lt;/em&gt; hace referencia al comportamiento de las excepciones. Cuando una aplicaci&amp;oacute;n genera una excepci&amp;oacute;n y est&amp;aacute; siendo depurada, el depurador recibe una excepci&amp;oacute;n de primera oportunidad (&lt;em&gt;first chance&lt;/em&gt;) y le da la opci&amp;oacute;n de tratarla. En este caso, el depurador trata la excepci&amp;oacute;n STATUS_BREAKPOINT deteniendo la ejecuci&amp;oacute;n de la aplicaci&amp;oacute;n permitiendo que el usuario introduzca comandos o examine el estado de la imagen de memoria del proceso&amp;nbsp;y el estado del procesador. Si el depurador no capturase la excepci&amp;oacute;n, se comprueba si el c&amp;oacute;digo de la aplicaci&amp;oacute;n la capturara. Este procedimiento implica verificar en la pila de ejecuci&amp;oacute;n si hay alg&amp;uacute;n c&amp;oacute;digo manejador de excepciones, desde el marco de activaci&amp;oacute;n m&amp;aacute;s reciente hasta&amp;nbsp;al m&amp;aacute;s antiguo. Este procedimiento recibe t&amp;eacute;cnicamente el nombre de &lt;em&gt;stack unwinding&lt;/em&gt;. No se preocupe, en posteriores art&amp;iacute;culos se va a tratar la estructura de datos conocida como pila, pues es de capital importancia a la hora de entender buena parte de la informaci&amp;oacute;n que nos proporcione Windbg. En caso de que el c&amp;oacute;digo no capturase la excepci&amp;oacute;n, se lanza al depurador una excepci&amp;oacute;n de segunda oportunidad (&lt;em&gt;second chance&lt;/em&gt;) y se vuelve a comprobar si el c&amp;oacute;digo captura la excepci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Lo que aparece a continuaci&amp;oacute;n en la pantalla de Windbg es el estado de los registros del procesador. Para entender esta parte de la salida es necesario disponer de ciertos conocimientos espec&amp;iacute;ficos de la m&amp;aacute;quina que est&amp;aacute; siendo depurada. En este caso se trata de la arquitectura x86, por lo que la referencia obligada es este documento: &lt;a href="http://download.intel.com/design/PentiumII/manuals/24319102.PDF"&gt;http://download.intel.com/design/PentiumII/manuals/24319102.PDF&lt;/a&gt;. Cuando veamos algunos casos de estudio ver&amp;aacute; c&amp;oacute;mo aplicar la informaci&amp;oacute;n sobre los registros de la m&amp;aacute;quina a un caso real.&lt;/p&gt;
&lt;p&gt;Para finalizar&amp;nbsp;nos aparece la &amp;uacute;ltima instrucci&amp;oacute;n ejecutada en el procesador antes de que se pasara el control al depurador. En este caso se trata de una instrucci&amp;oacute;n dentro de&amp;nbsp;la funci&amp;oacute;n DbgBreakPoint&amp;nbsp;dentro del m&amp;oacute;dulo Ntdll.dll. La instrucci&amp;oacute;n en cuesti&amp;oacute;n es la instrucci&amp;oacute;n &lt;em&gt;int 3&lt;/em&gt;, identificada mediante el c&amp;oacute;digo hexadecimal CC. Esta instrucci&amp;oacute;n lanza una interrupci&amp;oacute;n software. El par&amp;aacute;metro 3 indica que ejecutaremos la posici&amp;oacute;n 3 del vector de interrupciones&amp;nbsp;y&amp;nbsp;b&amp;aacute;sicamente&amp;nbsp;se enviar&amp;aacute; la excepci&amp;oacute;n STATUS_BREAKPOINT al depurador, para que haga con ella lo que considere oportuno. La direcci&amp;oacute;n de memoria que contiene esa instrucci&amp;oacute;n es la 7c91120e (en este ejemplo particular).&lt;/p&gt;
&lt;p&gt;Para concluir, puede configurar Windbg para que no informe de ciertos eventos (tales como la finalizaci&amp;oacute;n de un proceso, la carga de una DLL, etc.). Para ello puede ir al men&amp;uacute; &lt;em&gt;Debug&lt;/em&gt;, &lt;em&gt;Event Filters&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img height="465" width="531" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dmartin/Filtro_5F00_eventos.PNG" alt="Cuadro de di&amp;aacute;logo Event Filter" style="vertical-align:middle;" /&gt;&lt;/p&gt;
&lt;p&gt;Si desea hacer uso de la l&amp;iacute;nea de comandos de Windbg, el comando en cuesti&amp;oacute;n es &lt;strong&gt;sx&lt;/strong&gt; y sus derivados &lt;strong&gt;sxe&lt;/strong&gt;, &lt;strong&gt;sxd&lt;/strong&gt;, &lt;strong&gt;sxi&lt;/strong&gt;, &lt;strong&gt;sxn&lt;/strong&gt;. En la documentaci&amp;oacute;n de Windbg (&lt;em&gt;Help&lt;/em&gt;, &lt;em&gt;About&lt;/em&gt;) puede obtener informaci&amp;oacute;n adicional sobre el uso de estos comandos.&lt;/p&gt;
&lt;p&gt;En este art&amp;iacute;culo hemos aprendido a configurar Windbg para comenzar una sesi&amp;oacute;n de depuraci&amp;oacute;n&amp;nbsp;y hemos ejecutado nuestra primera aplicaci&amp;oacute;n dentro del depurador. Tambi&amp;eacute;n hemos aprendido qu&amp;eacute; quiere decir la informaci&amp;oacute;n que aparece en pantalla y en qu&amp;eacute; consiste &amp;quot;por lo bajo&amp;quot; la depuraci&amp;oacute;n de aplicaciones y el manejo de excepciones. En la siguiente parte veremos algunos comandos para examinar el estado de la m&amp;aacute;quina y del proceso que est&amp;aacute; siendo depurado. Se detallar&amp;aacute;n tambi&amp;eacute;n algunos aspectos de la arquitectura interna de Windows que son importantes para saber realmente lo que est&amp;aacute; pasando.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1692497" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Windbg/default.aspx">Windbg</category><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Tutorial sobre Windbg [Parte I]</title><link>http://msmvps.com/blogs/dmartin/archive/2009/04/04/tutorial-sobre-windbg-parte-i.aspx</link><pubDate>Sat, 04 Apr 2009 14:09:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1684673</guid><dc:creator>dmartin</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/rsscomments.aspx?PostID=1684673</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/dmartin/commentapi.aspx?PostID=1684673</wfw:comment><comments>http://msmvps.com/blogs/dmartin/archive/2009/04/04/tutorial-sobre-windbg-parte-i.aspx#comments</comments><description>&lt;p&gt;A petici&amp;oacute;n de un buen n&amp;uacute;mero de personas que me han escrito a trav&amp;eacute;s del &lt;em&gt;blog&lt;/em&gt;, he decidido comenzar un tutorial sobre depuraci&amp;oacute;n de aplicaciones y el sistema operativo Windows usando Windbg. A trav&amp;eacute;s de este tutorial espero cubrir conceptos introductorios (tales como aprender a configurar Windbg, saber qu&amp;eacute; comandos son los m&amp;aacute;s destacados y para qu&amp;eacute; sirven, etc.), hasta llegar a conceptos m&amp;aacute;s avanzados que impliquen la aplicaci&amp;oacute;n de la teor&amp;iacute;a al an&amp;aacute;lisis y soluci&amp;oacute;n de problemas reales. Se van a tratar tanto la depuraci&amp;oacute;n de volcados de memoria (algo que se conoce como &lt;em&gt;postmortem debugging&lt;/em&gt;), como la depuraci&amp;oacute;n de sistemas en vivo (&lt;em&gt;live debugging&lt;/em&gt;). Al final del tutorial espero que tenga la informaci&amp;oacute;n apropiada para abordar un problema en su m&amp;aacute;quina&amp;nbsp;ejecutando algo m&amp;aacute;s que el&amp;nbsp;cl&amp;aacute;sico comando de Windbg&amp;nbsp;&amp;quot;analyze -v&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;Qu&amp;eacute; es un depurador y qu&amp;eacute; tipos de depuradores hay?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El concepto de depuraci&amp;oacute;n en el &amp;aacute;mbito de la computaci&amp;oacute;n podr&amp;iacute;a describirse como un procedimiento met&amp;oacute;dico consistente en el an&amp;aacute;lisis&amp;nbsp;y correcci&amp;oacute;n de los defectos de un sistema software o hardware.&amp;nbsp;Esta sencilla descripci&amp;oacute;n representa una tarea ardua y dificultosa en s&amp;iacute; misma dada la alta complejidad de cualquier sistema computacional de hoy en d&amp;iacute;a.&amp;nbsp;Para poder llevarla a cabo, los ingenieros se sirven de unos programas denominados depuradores (en ingl&amp;eacute;s, &lt;em&gt;debuggers&lt;/em&gt;) que permiten, entre otras cosas,&amp;nbsp;analizar un volcado de memoria,&amp;nbsp;adjuntarse a un proceso (m&amp;aacute;s adelante veremos en qu&amp;eacute; consiste esto exactamente),&amp;nbsp;ejecutar un programa y examinar el estado de la m&amp;aacute;quina (registros, memoria, procesos en ejecuci&amp;oacute;n, etc.), ejecutar&amp;nbsp;paso a paso una aplicaci&amp;oacute;n, parar la ejecuci&amp;oacute;n seg&amp;uacute;n una cierta condici&amp;oacute;n, etc.&lt;/p&gt;
&lt;p&gt;Los depuradores pueden clasificarse en dos grupos bien diferenciados:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Depuradores en modo usuario&lt;/strong&gt;: Este tipo de depuradores son capaces de mostrar el estado de un proceso en un determinado momento (hilos en ejecuci&amp;oacute;n, registros de la m&amp;aacute;quina, contenido de la memoria, etc.), es decir, el depurador tiene exactamente la misma visi&amp;oacute;n de la m&amp;aacute;quina&amp;nbsp;que tendr&amp;iacute;a cada uno de los procesos que se est&amp;eacute;n ejecutando.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Depuradores en modo n&amp;uacute;cleo&lt;/strong&gt;: Este tipo de depuradores disponen de una visi&amp;oacute;n completa de la m&amp;aacute;quina sobre la que se est&amp;aacute;n ejecutando. Suelen utilizarse para detectar errores en controladores de sistema, pero en ciertos casos es necesario recurrir a un depurador en modo n&amp;uacute;cleo para depurar una aplicaci&amp;oacute;n que funcione en modo usuario.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;Qu&amp;eacute; es Windbg?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Windbg es un completo depurador&amp;nbsp;de Microsoft, tanto en modo usuario como en modo n&amp;uacute;cleo, con una intuitiva interfaz&amp;nbsp;gr&amp;aacute;fica y&amp;nbsp;descargable de forma gratuita desde la p&amp;aacute;gina &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;http://www.microsoft.com/whdc/devtools/debugging/default.mspx&lt;/a&gt;. El paquete Debugging Tools for Windows&amp;nbsp;incorpora un buen n&amp;uacute;mero de depuradores y utilidades relacionadas, y&amp;nbsp;aunque este tutorial solo se vaya a centrar en el depurador gr&amp;aacute;fico&amp;nbsp;Windbg mi recomendaci&amp;oacute;n personal es que se instale el paquete completo de Debugging Tools for Windows.&lt;/p&gt;
&lt;p&gt;Una vez finalizada la instalaci&amp;oacute;n, podemos ejecutar Windbg desde &lt;em&gt;Inicio&lt;/em&gt;, &lt;em&gt;Todos los programas&lt;/em&gt;, &lt;em&gt;Debugging Tools for Windows (x86)/(x64)&lt;/em&gt;, &lt;em&gt;Windbg&lt;/em&gt;. La pantalla principal tendr&amp;aacute; un aspecto similar al de&amp;nbsp;la siguiente imagen:&lt;/p&gt;
&lt;p&gt;&lt;img height="461" width="709" src="http://msmvps.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dmartin/Windbg.PNG" alt="Pantalla principal de Windbg" style="vertical-align:middle;" /&gt;&lt;/p&gt;
&lt;p&gt;Lo primero que se debe hacer es configurar el depurador. El aspecto de configuraci&amp;oacute;n m&amp;aacute;s importante de Windbg es quiz&amp;aacute; la informaci&amp;oacute;n referente a los s&amp;iacute;mbolos del c&amp;oacute;digo del programa que vayamos a depurar. Antes de proseguir, vamos a describir lo que es un s&amp;iacute;mbolo:&lt;/p&gt;
&lt;p&gt;Durante la fase de construcci&amp;oacute;n de un fichero ejecutable a partir de su&amp;nbsp;c&amp;oacute;digo fuente, se genera informaci&amp;oacute;n referente a las funciones, variables, estructuras de datos, etc.&amp;nbsp;usadas en dicho c&amp;oacute;digo. Dependiendo de los intereses del programador, esta informaci&amp;oacute;n puede acabar embebida en el propio ejecutable o bien proporcionarse de manera separada en la forma de ficheros con extensi&amp;oacute;n .pbd (si se ha usado alg&amp;uacute;n compilador de Microsoft). Embeber dicha informaci&amp;oacute;n en el ejecutable tiene como consecuencia que su tama&amp;ntilde;o se vea incrementado de manera considerable, adem&amp;aacute;s por informaci&amp;oacute;n que solo es de utilidad para programadores&amp;nbsp;o profesionales de soporte. Por lo tanto, la gran mayor&amp;iacute;a de compa&amp;ntilde;&amp;iacute;as de software proporcionan los s&amp;iacute;mbolos para la depuraci&amp;oacute;n de manera separada. Sin embargo, es muy probable que existan multitud de versiones de una determinada DLL o ejecutable, en cuyo caso, &amp;iquest;c&amp;oacute;mo sabe el depurador qu&amp;eacute; s&amp;iacute;mbolos escoger? La primera alternativa supondr&amp;iacute;a indicar individualmente&amp;nbsp;la ruta que apunte a los s&amp;iacute;mbolos de cada una de estas versiones, algo inviable. Para dar soluci&amp;oacute;n a este y otros problemas,&amp;nbsp;se ide&amp;oacute; el concepto de servidor de s&amp;iacute;mbolos, una m&amp;aacute;quina cuyo cometido es proporcionar los s&amp;iacute;mbolos de depuraci&amp;oacute;n conforme el depurador los vaya necesitando. Y lo que es m&amp;aacute;s importante, el servidor de s&amp;iacute;mbolos mantiene una lista de s&amp;iacute;mbolos indizada por nombre, tama&amp;ntilde;o, versi&amp;oacute;n o cualquier otro par&amp;aacute;metro, por lo&amp;nbsp;que es capaz de ofrecer la versi&amp;oacute;n apropiada de un s&amp;iacute;mbolo de manera c&amp;oacute;moda y r&amp;aacute;pida.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;C&amp;oacute;mo configurar la informaci&amp;oacute;n referente a los s&amp;iacute;mbolos de depuraci&amp;oacute;n en Windbg?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hay que precisar que si se configura Windbg para que consiga los s&amp;iacute;mbolos de depuraci&amp;oacute;n desde un servidor de s&amp;iacute;mbolos, es necesario que el sistema tenga conexi&amp;oacute;n a Internet durante todo el periodo que dure la depuraci&amp;oacute;n. Si esto no fuera posible, existe la alternativa de descargarse un paquete de s&amp;iacute;mbolos acorde con la versi&amp;oacute;n del sistema operativo que est&amp;aacute; siendo depurado desde una web de Microsoft, &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx#d"&gt;http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx#d&lt;/a&gt;. Sin embargo, esta opci&amp;oacute;n tiene el inconveniente de que los s&amp;iacute;mbolos suelen estar actualizados solo hasta el Service Pack m&amp;aacute;s reciente que haya salido. Si Windows Update hubiera actualizado alg&amp;uacute;n ejecutable o DLL con motivo de una actualizaci&amp;oacute;n de seguridad, por ejemplo, es posible que el depurador no disponga de la&amp;nbsp;informaci&amp;oacute;n simb&amp;oacute;lica pertinente. En particular, si faltan los s&amp;iacute;mbolos de Ntoskrnl.exe (depuraci&amp;oacute;n en modo n&amp;uacute;cleo) o bien Ntdll.dll, Shell32.dll o alguna otra DLL muy usada del sistema operativo (depuraci&amp;oacute;n en modo usuario), el an&amp;aacute;lisis que hagamos no servir&amp;aacute; para nada. Es, por tanto, muy importante que configuremos correctamente la informaci&amp;oacute;n simb&amp;oacute;lica en Windbg.&lt;/p&gt;
&lt;p&gt;Para configurar Windbg para que acceda al servidor de s&amp;iacute;mbolos de Microsoft se pueden seguir estos pasos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abrir el men&amp;uacute; &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Symbol File Path&lt;/em&gt; (o pulsar Ctrl+S).&lt;/li&gt;
&lt;li&gt;Introducir en la caja de texto &lt;em&gt;Symbol path&lt;/em&gt; lo siguiente:&lt;/li&gt;
&lt;p&gt;&lt;strong&gt;SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols&lt;/strong&gt;&lt;/p&gt;
&lt;li&gt;Pulsar &lt;em&gt;OK&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img height="207" width="571" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/dmartin/Simbolos.PNG" alt="Configurar s&amp;iacute;mbolos de depuraci&amp;oacute;n" style="vertical-align:middle;" /&gt;&lt;/p&gt;
&lt;p&gt;T&amp;eacute;ngase&amp;nbsp;en cuenta que se ha configurado como carpeta de descarga de los s&amp;iacute;mbolos la carpeta &lt;em&gt;C:\websymbols&lt;/em&gt;, pero se podr&amp;iacute;a indicar cualquier otra. A continuaci&amp;oacute;n podemos salvaguardar la configuraci&amp;oacute;n que hemos realizado para que no se pierda en sucesivas depuraciones haciendo clic sobre el men&amp;uacute; &lt;em&gt;File&lt;/em&gt;, &lt;em&gt;Save Workspace&lt;/em&gt; (o &lt;em&gt;Save Workspace As&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Si estamos en una sesi&amp;oacute;n de depuraci&amp;oacute;n (algo que se describir&amp;aacute; en un posterior art&amp;iacute;culo), podemos usar comandos para configurar los s&amp;iacute;mbolos adecuadamente:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.sympath&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando muestra la ruta que est&amp;eacute; configurada para el servidor de s&amp;iacute;mbolos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.sympath &lt;em&gt;&amp;lt;Ruta&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando establece la ruta &amp;lt;Ruta&amp;gt; como ruta del servidor de s&amp;iacute;mbolos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.sympath+ &lt;em&gt;&amp;lt;Ruta&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando es similar al anterior pero respeta cualquier otra ruta de servidor de s&amp;iacute;mbolos que pueda haber configurada con anterioridad.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.symfix &lt;em&gt;&amp;lt;Carpeta&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando nos evita tener que aprender de memoria la direcci&amp;oacute;n del servidor de s&amp;iacute;mbolos de Microsoft. Tan solo tenemos que indicarle la carpeta en la que queremos que se descarguen los s&amp;iacute;mbolos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.symfix+ &lt;em&gt;&amp;lt;Carpeta&amp;gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este comando es similar al anterior pero respeta cualquier otra ruta de servidor de s&amp;iacute;mbolos que pueda haber configurada con anterioridad.&lt;/p&gt;
&lt;p&gt;Ya hemos configurado uno de los aspectos m&amp;aacute;s importantes de Windbg, la informaci&amp;oacute;n simb&amp;oacute;lica de depuraci&amp;oacute;n. En el siguiente art&amp;iacute;culo veremos otros aspectos menores de configuraci&amp;oacute;n del depurador y aprenderemos a depurar una aplicaci&amp;oacute;n o proceso en modo usuario.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1684673" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Windbg/default.aspx">Windbg</category><category domain="http://msmvps.com/blogs/dmartin/archive/tags/Debugging/default.aspx">Debugging</category></item></channel></rss>