Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

89
Depuración Avanzada con WinDbg y VS 2010 Pablo Álvarez Doval Debugging & Optimization Team Lead (@Plain Concepts) [email protected]

description

Slides empleadas para la sesión de Depuración Avanzada con WinDbg y VS2010 en el CodeCamp de Tarragona. Esta es la versión extendida.

Transcript of Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Page 1: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Depuración Avanzada con WinDbg y VS 2010

Pablo Álvarez DovalDebugging & Optimization Team Lead (@Plain Concepts)

[email protected]

Page 2: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Agenda

• Depuración Avanzada:– Introducción a la Depuración Nativa con WinDbg– Depuración de Código .NET con WinDbg– Depuración con Visual Studio 2010

Page 3: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Arquitectura de Windows

• Modo usuario vs. modo kernel• Aplicaciones, procesos y threads• Manejo de memoria de Windows• Call Stacks

Page 4: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Modo usuario vs. modo kernel

User ModeKernel Mode

Hardware Abstraction Layer (HAL)

Controladores de Dispositivos Microkernel

Controlador

Gráfico

Object Manager

Executive Services

FS

I/O IPC Memoria

Procesos

Seguridad WMPNP

UNIXLSA Shell

Lsass.exe

Client/Server

csrss.exe

Notepadnotepad.e

xe

Windows on Windows

wowexec.exe

Virtual DOS Machine

ntvdm.exe

Win32

Interix

Page 5: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Aplicaciones, procesos y threads

• Una aplicación está formada por uno o más procesos• Un proceso es un ejecutable (.exe) que está en

memoria y que está formado por uno o más threads (hilos de ejecución) y sus propios recursos– Piensa en un proceso como en un contenedor de threads

• Un thread es la unidad básica de ejecución para la que el sistema operativo reserva tiempo de procesador para llevar a cabo una tarea– Un thread es lo que la CPU ejecuta. Todo proceso vivo ha

de tener al menos un thread, y a menudo tiene varios

Page 6: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Manejo de memoria Win 32 bit (I)

• Sistema de memoria Virtual• Drivers y aplicaciones almacenan información en direcciones

virtuales, que el Windows Memory Manager convierte a una posición de memoria física

Paginación (PF)

RAM

notepad.exe0x00000000

0x7FFFFFFF

0x80000000

0xFFFFFFFF

0x7C900000

Windows Memory Manager

Memoria Física

Page 7: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Manejo de memoria Win 32 bit (II)

Kernel

Proceso 1

Thread 1

Thread 2

Thread n

:

Proceso 2

Thread 1

Thread 2

Thread n

:

sqlsrv.exe

Thread 1

Thread 2

Thread n

:

Proceso n

Thread 1

Thread 2

Thread n

:…

4 G

b

2 G

b2

Gb

Page 8: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Manejo de memoria Win 32 bit (III)

Page 9: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Thread Call Stacks

• Foto de un thread en un instante de tiempo• Muestra la historia de llamadas a funciones• Cada thread tiene su propio Call Stack• Ejemplo:

ntdll!KiFastSystemCallRetUSER32!NtUserGetMessage+0xcnotepad!WinMain+0xe5notepad!WinMainCRTStartup+0x174kernel32!BaseProcessStart+0x23

Page 10: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Call Stacks (I)

• Cada hilo de un proceso tiene su Call Stack independiente:

Page 11: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Call Stacks (II)

• Cada frame tiene el siguiente call stack:Frame

Parámetros

Dirección de Retorno

Frame Pointer

Manejador de Excepciones

Variables Locales

Registros

Page 12: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Depuradores y símbolos

• Debugging Tools for Windows• Otros depuradores• Diferencias entre depuradores• Símbolos y Servidores de Símbolos

Page 13: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Debugging Tools for Windows

• Descarga gratuita:– http://www.microsoft.com/whdc/devtools/debuggin

g• Actualizadas cada pocos meses• Contiene depuradores, extensiones para los

depuradores, herramientas y una extensa ayuda:– windbg.exe, kd.exe, cdb.exe– gflags.exe, tlist.exe, etc– debugger.chm

• No necesita ser “instalado” para funcionar

Page 14: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Otros depuradores

• Visual Studio– Genial cuando depuras tu propio código o depuras

código manejado (.NET)• DebugDiag (Debug Diagnostics Tool)– Descarga gratuita:

IIS Diagnostics Toolkit http://www.microsoft.com/windowsserver2003/iis/diagnostictools/default.mspx

Page 15: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Diferencias entre depuradores

Ventajas Desventajas

Visual Studio GUI Depura con código fuente Familiar

En ppio no diseñado para dumps Uso de memoria No es fácil de automatizar

WinDBG GUI Depura con código fuente Diseñado para depurar Gratuito

Comandos no familiares Uso de memoria

CDB Línea de comandos Ligero Diseñado para depurar Gratuito Fácil de automatizar (Ej. AD+)

Comandos no familiares No depura con código fuente

DebugDiag GUI Funciona como un servicio de Windows Contiene un motor de análisis Análisis y detección de leaks Gratuito

No depura “en vivo”

Page 16: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Símbolos

• Los símbolos hacen que el call stack sea útil:

– Sin símbolos:

– Con símbolos:

kernel32!+136aa

kernel32!CreateFileW+0x35f

Page 17: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Formatos de símbolos

• Formato Actual: .PDB• Formato Antiguo: .DBG• Retail vs. Debug (Free vs. Checked) builds• Símbolos privados vs. públicos

Page 18: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Servidores de Símbolos

• Utiliza el sistema de ficheros como base de datos para símbolos – organizados por nombre y un identificador único– Estructura de directorios:

\\SymSrv\file_name.pdb\unique_number\____• Ejemplos:

\\Symbols\ntdll.pdb\3B5EDCA52\ntdll.pdb\\Symbols\ntdll.pdb\380FCC4F2\ntdll.pdb

Page 19: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Laboratorio 1: Escenario

Page 20: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 1: Escenario

• Un cliente tiene un problema con su SQL Server 2000, manifestado con errores 17883 en el log del SQL Server

• Al producirse los errores 17883, SQL Server genera automáticamente un volcado de memoria para su posterior estudio

2004-05-27 13:01:40.10 server Error: 17883, Severity: 1, State: 0

2004-05-27 13:01:40.10 server Process 59:0 (834) UMS Context 0x125ABD80 appears to be non-yielding on Scheduler 1.

Page 21: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Agenda

• Depuración Avanzada:– Introducción a la Depuración Nativa con WinDbg– Depuracion de Código .NET con WinDbg– Depuración con Visual Studio 2010

Page 22: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Depuración de Código .NET

• WinDbg es un depurador Nativo

• Para depurar código .NET hay que usar extensiones:– SOS.dll (hasta framework .NET 3.5)– CLR.dll (framework 4.0)

• Extensión MUY recomendable:– SOSEX v2, de Steve Johnson

Page 23: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Novedades en CLR 4

• Ahora se encuentra en CLR.DDL

• Soporte DML• Nuevas extensiones:– !ThreadState, !DumpSigElem, !FindRoots, !

ListNearObj (lno), !HistRoot, y muchos más…

.loadby sos clr

Page 24: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Laboratorio 2: Depuración con SOS

Page 25: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Para empezar a depurar se tiene que tener claro que algo mal ocurre.

• En los sucesivos ejemplos vamos a depurar una web en ASP.NET con diferentes tipos de errores cometidos durante su desarrollo.

• Identificaremos el problema y trataremos de aislarlo.

Page 26: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Si hacemos una petición a http://localhost/BuggyBits/FeaturedProducts.aspx vemos que la pagina tarda +5 seg en ejecutarse.

• Si hacemos varias peticiones a la web con varios tabs, vemos que la web se bloquea.

Page 27: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Para realizar varias peticiones a la veztinyget -srv:localhost

-uri:/BuggyBits/FeaturedProducts.aspx -threads:30 -loop:50

• Una vez que tenemos todas la peticiones bloqueadas hacemos un dump del proceso (w3wp.exe)

adplus –hang –pn w3wp.exe –quiet

• Ahora es el momento de empezar con WinDBG

Page 28: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Pasos a seguir:~* kb 2000 (pila de todos los threads del proceso)~* e !clrstack (pila .net de todas los threads)

Page 29: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• En casi todas los threads hay llamadas a esté método– System.Threading.Monitor.Enter(System.Object)

• Menos en un thread que hay una llamada a – System.Threading.Thread.SleepInternal(Int32)

• Es muy posible que haya un deadlock (hay que investigar)

Page 30: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Necesitamos mostrar todos los objetos que estan esperando a que se libere un bloqueo (salir de una región critica)– !syncblk

0:028> !syncblkIndex SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 7 018b6c2c 19 1 0ed5f8c8 1058 28 066affdc System.Object-----------------------------Total 53CCW 2RCW 3ComClassFactory 0Free 27

Page 31: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

0:028> !clrstackOS Thread Id: 0x1058 (28)ESP EIP 0ffee0e0 76f89a94 [HelperMethodFrame: 0ffee0e0] System.Threading.Thread.SleepInternal(Int32)0ffee134 0e8c0fc5 DataLayer.GetFeaturedProducts()0ffee170 0e8c0e1f FeaturedProducts.Page_Load(System.Object, System.EventArgs)0ffee1fc 5b46a7ff System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)0ffee20c 59802344 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)0ffee220 597fb864 System.Web.UI.Control.OnLoad(System.EventArgs)0ffee234 597fb8a3 System.Web.UI.Control.LoadRecursive()0ffee24c 597f7954 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)0ffee3a4 597f7584 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)0ffee3dc 597f74b1 System.Web.UI.Page.ProcessRequest()0ffee414 597f7446 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)0ffee420 597f7422 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)0ffee434 0e8c0355 ASP.featuredproducts_aspx.ProcessRequest(System.Web.HttpContext)0ffee438 597fd8f6 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()0ffee46c 597d132c System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)0ffee4ac 59dc494f System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)0ffee4b0 59dbd8e8 [InlinedCallFrame: 0ffee4b0] 0ffee550 59da6981 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)0ffee5c0 59e7a3ca System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)0ffee5c4 59e798e7 [InlinedCallFrame: 0ffee5c4] 0ffeeb18 01792904 [NDirectMethodFrameStandalone: 0ffeeb18] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr,

System.Web.RequestNotificationStatus ByRef)0ffeeb28 59e7a461 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)0ffeebac 59e798e7 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)0ffeecac 01792904 [ContextTransitionFrame: 0ffeecac]

Page 32: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Depuración con SOS

• Efectivamente todos los threads esperan a que se libere el bloqueo de un objeto de tipo Object, podemos ver el código fuente para verificarlo.

• Además podemos asegurarnos de que ese objeto es el que usan todos los threads usando el comando !gcroot de sos, que nos permite ver cuales son los gcroots de un objeto, que son básicamente que objetos lo referencian.– !gcroot 066affdc

Page 33: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 2: Comandos Útiles

• k : muestra la información de la pila nativa actual– b : muestra los tres primero parámetros de las funciones

• .loadby sos mscorwks (carga sos en WinDbg)• !clrstack : muestra la información de la pila

administrada• !syncblk : muestra información sobre los bloqueos– lock(obj) { }

• !gcroot : muestra cuales son los objetos que referencian a este objeto

Page 34: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Laboratorio 3: Crash

Page 35: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• Navegamos por http://localhost/BuggyBits/Reviews.aspx, pulsamos el botón de Refresh. Pasados unos segundos el proceso w3wp.exe se estrella.

• En el registro del sistema encontramos una entrada de porque se ha estrellado.

• Es un problema bastante grave pues puede afectar a otros dominios de aplicación que se encuentren en ese proceso

• Tenemos que crear un dump completo de la aplicación para ver porque se estrella.

Page 36: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• Volvemos a navegamos por http://localhost/BuggyBits/Reviews.aspx, pero ahora no pulsamos en el botón de refresh.

• Hay que iniciar adplus para hacer un dump del proceso cuando se estrelle.– adplus -crash -pn w3wp.exe– Aparece una ventana nueva en la barra de tareas.

• Pulsamos refresh y el proceso se estrella

Page 37: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• El código nativo nos indica que estamos ante el finalizador de la clase, y es aquí donde se ha generado la excepción.

• La pila administrada no proporciona mucha información.

• Se sabe que es un NullReferenceExcepcion, gracias a !pe

Page 38: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• Con el comando !dso, nos permite ver las variables locales de todos los frames de la pila.

• En la lista hay muchos objetos del tipo NullReferenceExcepcion y podemos encontrar un objeto del tipo Review

Page 39: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

0:015> !dso -verifyOS Thread Id: 0xfcc (15)ESP/REG Object Name0e5af904 025e4a88 System.NullReferenceException0e5af908 025e4a88 System.NullReferenceException0e5af950 025e4a88 System.NullReferenceException0e5af968 025e4a88 System.NullReferenceException0e5af9bc 025e4a88 System.NullReferenceException0e5af9cc 025e4a88 System.NullReferenceException0e5afa68 0258c2cc System.NullReferenceException0e5afa6c 025e3cbc System.Byte[]0e5afa88 025e4a88 System.NullReferenceException0e5afa8c 025e3cbc System.Byte[]0e5afa9c 025e3cbc System.Byte[]0e5afbc0 0652f3cc Review

Page 40: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• Obtenemos la información de la excepción a través del comando !pe 0258c2cc, que nos muestra el método que lanzo la excepción.

0:015> !pe 0258c2cc Exception object: 0258c2ccException type: System.NullReferenceExceptionMessage: Object reference not set to an instance of an object.InnerException: <none>StackTrace (generated): SP IP Function 0E5AF860 0E6B0F74 App_Code_etrlku9h!Review.Finalize()+0x14

StackTraceString: <none>HResult: 80004003

Page 41: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• Ya sabemos que la excepción la ha lanzado el objeto Review ahora podemos saber cual es la línea que lanzo la excepción en caso de que no tengamos el código fuente disponible.

• SOS incluye un comando !u, que permite desensamblar la memoria y ver el codigo X86 generado por el JIT con información extra a partir de la información de depuración.

• El comando !u, acepta la dirección de memoria del bloque de código, que la podemos obtener del EIP.

Page 42: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 3: Crash

• ¿Por qué se lanza esta excepción que nadie controla?

• Cual es la mejor manera de finalizar a un objeto

• CriticalFinalizerObject

Page 43: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

Laboratorio 4: Gestión de Memoria

Page 44: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• En este laboratorio vamos a intentar solucionar un problema de fuga de memoria (memory leak) de una pagina ASP.NET.

• Lo más importante para resolver este tipo de problemas es saber que efectivamente nuestra aplicación tiene fugas de memoria.

• La única herramienta que hay para esto es ver la evolución de la memoria a través del tiempo con los contadores de rendimiento

Page 45: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Navegamos por http://localhost/BuggyBits/Links.aspx y vemos que ocurre.

• En principio la aplicación funciona correctamente, tenemos que estresarla de alguna manera para simular un carga alta.

• tinyget -srv:localhost -uri:/BuggyBits/Links.aspx -loop:4000

Page 46: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Ahora si observamos como el proceso reserva mucha memoria.

• Con los contadores de rendimiento podemos observar cual es el tipo de reserva que hace.

• En el resultado de los contadores de rendimiento hay que observar el resultado de la memoria de Win32 así como la memoria de .NET

Page 47: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Con el proceso (w3wp.exe) en este estado hay que hacer un dump para poder analizar el porque de esta fuga de memoria.

• adplus -hang -pn w3wp.exe –quiet

• Es el momento de empezar con WinDbg

Page 48: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Hay que ver el estado de la memoria para el proceso – !address –summary

Page 49: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

0:000> !address -summary ProcessParametrs 001f1588 in range 001f0000 002f0000 Environment 01c16128 in range 01c10000 01d10000

-------------------- Usage SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Pct(Busy) Usage 36c73000 ( 897484) : 42.80% 86.79% : RegionUsageIsVAD 40e1d000 ( 1063028) : 50.69% 00.00% : RegionUsageFree 73b4000 ( 118480) : 05.65% 11.46% : RegionUsageImage 57b000 ( 5612) : 00.27% 00.54% : RegionUsageStack 16000 ( 88) : 00.00% 00.01% : RegionUsageTeb c1a000 ( 12392) : 00.59% 01.20% : RegionUsageHeap 0 ( 0) : 00.00% 00.00% : RegionUsagePageHeap 1000 ( 4) : 00.00% 00.00% : RegionUsagePeb 0 ( 0) : 00.00% 00.00% : RegionUsageProcessParametrs 0 ( 0) : 00.00% 00.00% : RegionUsageEnvironmentBlock Busy: 3f1d3000 (1034060 KB)

-------------------- Type SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 40e1d000 ( 1063028) : 50.69% : <free> 817c000 ( 132592) : 06.32% : MEM_IMAGE 1974000 ( 26064) : 01.24% : MEM_MAPPED 356e3000 ( 875404) : 41.74% : MEM_PRIVATE

-------------------- State SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 38237000 ( 919772) : 43.86% : MEM_COMMIT 40e1d000 ( 1063028) : 50.69% : MEM_FREE 6f9c000 ( 114288) : 05.45% : MEM_RESERVE

Largest free region: Base 3a0a0000 - Size 1e1f0000 (493504 KB)

Page 50: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Se ha visto que casi la mayoría de la memoria del proceso viene de la sección de RegionUsageIsVAD ¿Porque?

• Examinamos los heaps de GC– !eeheap –gc

• Tenemos dos GC Heaps• Comparamos la memoria total del GC Heap con

#Bytes in all Heaps

Page 51: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Ahora queremos saber cuantos objetos hay en el heap, de que tipo son y cuanta memoria ocupan.– !dumpheap –stat

• ¿Cuantos objetos hay en total en los dos heaps?– 140786

• El objeto que más aparece en la pila es System.String– 44375 instancias– 721004504 TotalSize

Page 52: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Después aparece memoria libre, StringBuilders y objetos del tipo Link. Estos objeto de tipo Link (recordar la web que estamos depurando) son los que representar un link.– !dumpheap -type Link– !dumpmt 0e781684 – !do 34d96fb0 – !objsize 34d96fb0

• Observamos que este objeto (Link) tiene dos campos– url (StringBuilder) (offset 4)– name (string) (offset 8)

Page 53: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Observamos que la mayoría de las cadenas estan entre un tamaño de 20000 y 25000 (ensayo y error), así que vamos a ver cuales son esos strings– !dumpheap -mt <string MT> -min 20000 -max 25000

• Cogemos cualquier objeto y vemos el contenido– !do 35458344

0:000> !do 35458344 Name: System.StringMethodTable: 5c9808ecEEClass: 5c73d64cSize: 20018(0x4e32) bytes (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)String: http://blogs.msdn.com/tomFields: MT Field Offset Type VT Attr Value Name5c982b38 4000096 4 System.Int32 1 instance 10001 m_arrayLength5c982b38 4000097 8 System.Int32 1 instance 25 m_stringLength5c9815cc 4000098 c System.Char 1 instance 68 m_firstChar5c9808ec 4000099 10 System.String 0 shared static Empty >> Domain:Value 01cac948:024f01d0 01cddff0:024f01d0 <<5c98151c 400009a 14 System.Char[] 0 shared static WhitespaceChars >> Domain:Value 01cac948:024f0728 01cddff0:064f0964 <<

Page 54: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Resulta que todas las cadenas que se utilizan para generar la lista de string no están siendo recolectadas con el GC, así que tenemos que encontrar que otros objetos hacen referencia a estas cadenas– !gcroot 35458344

• Parece ser que el objeto está referencia por un tipo Link, pero que este se encuentra en la cola de finalización– !finalizequeue

• Parece que todos los objetos están en la cola de finalización pero no se están recolectando.

Page 55: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• Hay que encontrar el thread finalizador para ver que está haciendo. El thread finalizador está marcado con Finalizer– !threads

• Cambiamos al thread finalizador– ~15s– Kb 2000– !clrstack

Page 56: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Laboratorio 4: Gestión de Memoria

• El objeto Link en el finalizador tiene un Thread.Sleep que está haciendo que se bloquee el finalizador durante 5 segundos lo que hace que no se recolecten los objetos con la velocidad deseable.

• Hacer cualquier operación de bloqueo en el finalizador es extremadamente peligroso pues puede hacer que nuestro thread de finalización se bloquee y no podamos ser capaces de recolectar los objetos no utilizados.

Page 57: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Agenda

• Depuración Avanzada:– Introducción a la Depuración Nativa con WinDbg– Depuracion de Código .NET con WinDbg– Depuración con Visual Studio 2010

Page 58: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

¡¿De verdad hemos llegado aquí?!

• No me creo que hayamos llegado aquí con tiempo suficiente…

Page 59: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algunos Truquillos

• Bueno, ya que lo hemos conseguido, veamos algunos truquillos:– SOS desde el VS.NET– Análisis de Volcados de Memoria desde VS2010– Depurador Histórico– Tasks Call Stacks

Page 60: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Recursos

• En Plain Concepts– http://www.geeks.ms/blogs/palvarez– http://www.geeks.ms/blogs/rcorral– http://www.geeks.ms/blogs/luisguerrero

• En MSDN:– http://blogs.msdn.com/tess/

• En papel…– Microsoft Windows Internals, 5th Ed.

[Mark E. Russinovich and David A. Solomon]Microsoft Press.

– Debugging Applications for Microsoft .NET and Microsoft Windows[John Robbins]Microsoft Press.

Page 61: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

¿Preguntas ?

Recuerda que en www.codecamp.es podrás encontrar todo el material de las sesiones del CodeCamp

Page 62: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Slides de Reserva

• Estaba preparado ;)

Page 63: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Gestión de Memoria en el CLR

• Gestión de Memoria:– El CLR usa un Recolector de Basura(GC) para

administrar la memoria– Minimiza errores de pérdida de memoria – La asignación de memoria (new) es más rápida

que en C++, pero la compactación supone una fuerte sobrecarga

– Para minimizar su impacto se recurre a un sistema generacional

Page 64: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

GC – Ubicación de Recursos

• El CLR impone que todos los recursos sean ubicados en el Managed Heap

• Se inicializa un MH por cada proceso• Operador new:

– Se asegura de que tenga espacio– Llama al constructor del objeto– Devuelve el valor del Sig.Obj y lo

actualiza• Si no queda memoria libre, se realiza

una recogida de basura o compactación

• En realidad, esto ocurre solo cuando la Generación 0 (clases mas recientes) esta completa.

Objeto A

Objeto B

Objeto C

Espacio Libre

Sig. Obj.

Page 65: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algoritmo de Recogida (I)

• El GC comprueba si hay memoria que no se este usando (objetos no referenciados). Si la hay realiza la liberación. Si el MH se llena y no se puede liberar (todos los objetos contiene referencias) salta un OutOfMemoryException

• Cada aplicación tiene sus raíces (roots). Estas son las posibles localizaciones de las posiciones de memoria que referencian a objetos en el MH (registros de la CPU, punteros a objetos estáticos y globales, variables locales, parámetros…). Las raíces se almacenan en el JIT y en el CLR.

• Cuando el GC se inicia, asume que todos los objetos en el heap son basura. Comienza a recorrer las raíces, construyendo recursivamente un grafo con todos los nodos alcanzables desde estas.

Page 66: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algoritmo de Recogida (II)

• Si durante la comprobación de todas las raíces el GC se encuentra con un objeto que ya marco previamente, no lo volverá a seguir, por dos razones:– Como optimización– Para evitar caer en bucles infinitos, como seria el caso de las listas circulares.

• Al finalizar, el grafo contiene todos los objetos, que de un modo u otro son accesibles desde la aplicación. Todos los objetos que no aparezcan en el grafo se consideran basura.

• El GC recorre el heap y va compactando todos los objetos que no son basura, tratando la basura como espacio libre.

• El GC recompone las direcciones de memoria de los objetos en las raíces.

Page 67: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algoritmo de Recogida (III)

Objeto A

Objeto B

Objeto C

Objeto D

Objeto E

Objeto F

Objeto G

Objeto H

Objeto I

Objeto J

Espacio LibreRaíces

(Referencias Fuertes)

Punteros EstáticosPunteros Globales

Punteros de la pila del hilo

Punteros en losRegistros de la CPU

Sig. Obj.

Page 68: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algoritmo de Recogida (IV)

Objeto A

Objeto B

Objeto C

Objeto D

Objeto E

Objeto F

Objeto G

Objeto H

Objeto I

Objeto J

Espacio LibreRaíces

(Referencias Fuertes)

Punteros EstáticosPunteros Globales

Punteros de la pila del hilo

Punteros en losRegistros de la CPU

Sig. Obj.

Page 69: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Algoritmo de Recogida (V)

Objeto B

Objeto C

Objeto D

Objeto F

Objeto H

Espacio Libre

Raíces(Referencias Fuertes)

Punteros EstáticosPunteros Globales

Punteros de la pila del hilo

Punteros en losRegistros de la CPU

Sig. Obj.

Page 70: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

GC - Generaciones (I)

• Son un mecanismo de optimización del GC. Un Recolector de basura generacional se basa en las siguientes suposiciones:– Cuanto mas joven sea un objeto, mas pequeño será su ciclo de

vida– Cuanto mas viejo sea un objeto, mas largo será su ciclo de vida– Los objetos mas jóvenes tienden a tener relaciones mas

fuertes entre ellos, y son frecuentemente accedidos al mismo tiempo

– Compactar un fragmento del heap es mas rápido que compactar todo el heap

Page 71: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

GC - Generaciones (II)

• Cuando se inicializa el GC, los nuevos objetos que se van ubicando en el MH son de generación 0. Esta generación comprende a los objetos mas jóvenes, que aun no han sido analizados por el GC.

• La próxima vez que ocurra una recogida de basura, los miembros de la generacion 0 que sobrevivan a esta se compactaran y quedaran en la parte de abajo del heap, pasando a ser la generación 1, mientras que los nuevos objetos que entren serán la nueva generación 0, y así sucesivamente.

• Actualmente, el CLR implementa un GC de 3 generaciones (0, 1 y 2).

Page 72: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

GC - Generaciones (III)

Objeto A

Objeto B

Objeto C

Objeto D

Objeto E

Objeto F

Objeto G

Objeto H

Objeto I

Objeto J

Objeto B

Objeto C

Objeto D

Objeto F

Objeto H

Objeto K

Objeto L

Objeto M

Objeto N

Objeto O

Gen

. 0

Gen

. 1G

en. 0

Page 73: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Examen

Page 74: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

El Patrón Dispose

• Los tipos que exponen la capacidad de ser eliminados (Disposed) de modo determinista implementan el patrón dispose

Page 75: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Finalización

public sealed class OSHandle {

[System.Runtime.InteropServices.DllImport("Kernel32")]private extern static Boolean CloseHandle(IntPtr handle);

private IntPtr handle;

public OSHandle(IntPtr handle) { this.handle = handle;}

protected override void Finalize() {

try { CloseHandle(handle);}finally { base.Finalize(); }

}

public IntPtr ToHandle() { return handle; }

public static implicit operator IntPtr(OSHandle osHandle) {

return osHandle.ToHandle();}

}

Page 76: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Finalización: Destructores en C#

~Conan() {

CloseHandle(handle);}

Page 77: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

CODE HORROR: ¿Que está mal aqui?

~DocumentoComprobante(){

Dispose(false);}

Page 78: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Problemas de la Finalización

• Los objetos finalizables se promueven a generaciones más viejas– Incrementa el consumo de memoria– Los objetos referidos de modo indirecto también serán promovidos

y, por tanto, no recolectados• Se ralentiza la reserva de memoria, porque se deben mantener

punteros en la lista de finalización también• Afecta al rendimiento del GC• No controlamos el momento en el que el método de

finalización será invocado• No tenemos garantía sobre el orden en que se finalizarán los

objetos

Page 79: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Problema con Excepciones:• El finalizador se invoca

aunque salte una excepción en la construcción del objeto:– De modo que nunca debemos

hacer asunciones sobre el estado del objeto en el Finalizador

Finalización

class TempFile { String filename = null; public FileStream fs;

public TempFile(String filename) { // Aqui podría saltar una excepción fs = new FileStream(filename, FileMode.Create); this.filename = filename; }

~TempFile() { if (filename != null) File.Delete(filename); }}

Page 80: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Finalización

String filename;public FileStream fs;public TempFile(String filename) {

try {// Puede saltar una excepcion aqui!fs = new FileStream(filename, FileMode.Create);this.filename = filename;

}catch {

// Si algo va mal, pedimos al GC que no invoque al finalizadorGC.SuppressFinalize(this);throw;

}}~TempFile() {

File.Delete(filename);}}

Page 81: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

¡¡Otro Examen!!

• ¿Cuándo debemos usar los finalizadores?

Page 82: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Agenda

• Presentaciones• Objetivos e Ideas Clave• Gestión de Memoria• Gestión de Concurrencia• Herramientas

Page 83: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

¿Por qué usar hilos?

• La Ley de Moore... La maldita Ley de Moore– Escalamos en base a más CPUs

• Para permitir que la interfaz de usuario responda a los eventos de Windows mientras se hace un trabajo

• Para permitir el modelo de programación asíncrona de E/S (APM)

Page 84: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

¿Por qué NO usar hilos?

• Porque es difícil hacerlo bien– No, en serio.. ¡Lo es!

• Produce Heisenbugs muy facilmente• La sincronización de los hilos es complicada• En muchas ocasiones no lo necesitamos• Los hilos no son baratos

Page 85: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Hilos

• Unidad mínima de ejecución• Los hilos no salen gratis• Ocupan 1MB en el VAS para el stack + 12KB en el kernel• Cuando se crea un nuevo hilo, todas las DLLs en el

proceso padre son llamadas para notificar de la creación

• Lo mismo sucede cuando un hilo va a morir• Los cambios de conexto almacenan los registros (700

bytes en x86, 1240 en x64, aún más en IA64) y emplean un spinlock, lo que consume tiempo

Page 86: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Lock y Monitor

private void Metodo(){ lock(this) { // Acceso al object }}

private void Metodo()

{ Object temp=this;

Monitor.Enter(temp);

try

{

// Acceso al objeto

}

finally

{

Monitor.Exit(temp); }

Page 87: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Agenda

• Presentaciones• Objetivos e Ideas Clave• Gestión de Memoria• Gestión de Concurrencia• Herramientas

Page 88: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Herramientas

• FxCop• Contadores de Rendimiento• .NET Memory Profiler• WinDbg + SOS.dll

Page 89: Depuración Avanzada Con Win Dbg Y Vs 2010 (Extendida)

www.codecamp.es

Anexo – Tipos de Bugs

• Heisenbugs (“Principio de Incertidumbre de Heisemberg”): – Desaparece o altera su comportamiento al intentar depurarlo.

• Bohrbugs (“Modelo atómico de Bohr”):– No cambia su comportamiento nunca. Siempre reproducible.

• Mandelbugs (“Conjunto de Mandelbrot”):– Las causas son tan complejas que su comportamiento parece caótico.

• Schroedingbugs (“El Gato de Schrödinger”):– El bug no se manifiesta hasta que alguien, leyendo el código o usando

el programa de forma inusual, lo descubre.– Desde ese momento, deja de funcionar para todo el mundo

• Stotle (“Aristoteles”):– La aplicación esta bien, pero el conjunto de datos de prueba no.