domingo, 20 de febrero de 2011

Debugging I parte

En este articulo quiero hablar del Debugging en Windows, más abajo vamos a ver las definiciones de las Aplicaciones, Procesos, Threads y CallStacks una vez que ya sabemos estas definiciones nos podemos defender con las aplicaciones de Debugging.
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.
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!KiFastSystemCallRet
USER32!NtUserGetMessage+0xc
notepad!WinMain+0xe5
notepad!WinMainCRTStartup+0x174
kernel32!BaseProcessStart+0x23
Cada hilo(Thread) de un proceso tiene su Call Stack independiente. Con el Windbg (Debugging Tools for Windows) podemos ver los call stack de alguna aplicación común, como notepad.exe o calc.exe por ejemplo.
Aquí os dejo un procedimiento que habría que seguir para determinar la causa y ubicar el fallo de nuestro Sistema Operativo.
Procedimiento a seguir para resolver problemas:
Determinar el tipo de fallo: Access Violation, resultado inesperado…
Documentar los síntomas: Memory Leak, 100% CPU, Crash…
Elegir las herramientas y técnicas adecuadas:
  - Habilitar tracing en la aplicación.
  - Usar logs de debug o “checked builds”.
  - Perfmon, EventLogs, Netmon, Filemon, logs de IIS, MSDN, etc.
  - Conseguir dumps y analizarlos.
  - y analizarlo: examinar el stack, evaluar parámetros y variables, desensamblar y entender el código, poner breakpoints antes del fallo, examinar/modificar la memoria y loAdjuntarse al proceso con un depurador s registros, editar el código o los datos, etc.
Bien, una vez que tenemos claro todo esto, podemos empezar a hablar de las herramientas de Debbuging.
Para analizar el archivo de volcado que se genera al "colgarse" el sistema operativo necesitaremos un depurador y los símbolos pertenecientes al sistema operativo en el que se ha producido ese dump.
Windbg es una herramienta de depuración tanto en modo kernel como en modo usuario, con ella analizaremos los volcados.
Cuando pasa un error en modo kernel Windows nos saluda con una pantalla azul y la info sobre el código de stop. Esto puede modificarse, de manera que:
- Se puede asignar un depurador (como windbg o KD).
- Se grabe el archivo de volcado de memoria (dump).
- Se produzca un reinicio automático del sistema.
- Se grabe el volcado y reinicie el sistema inmediatamente después.
Los volcados.
Modo-kernel:
Completo: volcado de tamaño más grande, contendrá la memoria física del equipo en el momento del error. Lo que implica que el archivo de paginación deba tener al menos el tamaño de la memoria real + 1MB.
El volcado se guarda en la raíz del sistema  %systemroot%\Minidump con el nombre de memory.dmp, y en el caso de volcados posteriores, irían sustituyendo al existente.
Memoria Kernel: Con un tamaño significativamente menor contiene la memoria ocupada por el kernel en el momento del error. Es decir, ni memoria no asignada ni la que está asignada a aplicaciones en modo usuario, sólo la usada por el kernel, HAL, y la asignada a controladores y programas en modo kernel.
En general es el volcado más útil y se guarda en la raíz del sistema con el nombre memory.dmp. Los volcados posteriores, sean memoria kernel o completo, sustituyen al existente.
Volcado pequeño: Con un tamaño de 64KB es el más pequeño de todos y por tanto sólo requiere un archivo de paginación de ese tamaño.
Su contenido es:
- Mensaje del código de stop y sus parámetros.
- El contexto del procesador que ha cascado.
- La información del proceso y el contexto kernel, del proceso que ha petado.
- La información del hilo y el contexto kernel, del proceso que ha petado.
- La pila de llamadas en modo kernel para el hilo que ha petado. Sólo hasta 16KB, los de arriba de la pila.
- Una lista de los controladores cargados.
Además, si es Windows XP o posterior:
- Una lista de módulos cargados y descargados.
- El bloque de datos del depurador (información de depuración básica del sistema).
- Cualquier página de memoria que Windows crea que es útil en la depuración de errores. (Las páginas de datos a qué apuntan los registradores en el momento del pete y otras que hayan sido solicitadas específicamente por el componente que falla).
Después de esta pequeña explicación, vamos a descargar e instalar la herramienta, le tenemos que descargar los símbolos desde el servidor de descarga:
SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Para eso tendríamos que crear un directorio en C$ con el mismo nombre "websymbols" o poner el nombre que os convengan, en mi caso es"DebuggingToolsSymbols". Una vez que ya hemos creado el directorio, abrimos la aplicación y entramos en File>Symbol File Path... o con Ctrl+S y se nos abrirá esta misma ventana donde debemos que pegar la ruta a utilizar en el Windbg:
Una vez que ya tenemos esta parte hecha ya podemos abrir el  archivo .dmp (DUMP) en  File>Open Crash Dump y cuando se abre la ventana tenemos que ir a  %systemroot%\Minidump (en este directorio el sistema guarda los volcados de memoria) para seleccionar el archivo .dmp.
Se abrirá el archivo dump (al abrir el primer archivo dump va tardar un poco por el motivo de que se está descargando los Symbolos de la url que le hemos configurado antes)
Podemos empezar con el comando:
!analyze –v
Con este comando podemos ver todos los detalles de archivo dump.
0: kd> !analyze -v
PFN_LIST_CORRUPT (4e)
Typically caused by drivers passing bad memory descriptor lists (ie: calling
MmUnlockPages twice with the same list, etc).  If a kernel debugger is
available get the stack trace.
Arguments:
Arg1: 00000099, A PTE or PFN is corrupt
Arg2: 0004d4f9, page frame number
Arg3: 00000002, current page state
Arg4: 0004d4ee, 0

Debugging Details:
------------------
BUGCHECK_STR:  0x4E_99
CUSTOMER_CRASH_COUNT:  1
DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT
PROCESS_NAME:  Mcshield.exe
CURRENT_IRQL:  2
LAST_CONTROL_TRANSFER:  from 82b066dc to 82af9d10
STACK_TEXT: 
aadbba50 82b066dc 0000004e 00000099 0004d4f9 nt!KeBugCheckEx+0x1e
aadbba68 82ac4598 c0006000 aadbbbf0 00000000 nt!MiBadShareCount+0x24
aadbbb7c 82ad6ad4 c0005eb8 c0005f38 855da4a8 nt!MiDeletePteRun+0x66a
aadbbc84 82ad0e41 00bd0000 00c50fff 8c5ea1d1 nt!MiDeleteVirtualAddresses+0x3c1
aadbbd1c 82a6044a ffffffff 02cbf828 02cbf824 nt!NtFreeVirtualMemory+0x60b
aadbbd1c 77a664f4 ffffffff 02cbf828 02cbf824 nt!KiFastCallEntry+0x12a
WARNING: Frame IP not in any known module. Following frames may be wrong.
02cbf75c 00000000 00000000 00000000 00000000 0x77a664f4
STACK_COMMAND:  kb
FOLLOWUP_IP:
nt!MiBadShareCount+24
82b066dc cc              int     3
SYMBOL_STACK_INDEX:  1
SYMBOL_NAME:  nt!MiBadShareCount+24
FOLLOWUP_NAME:  MachineOwner
MODULE_NAME: nt
DEBUG_FLR_IMAGE_TIMESTAMP:  4c1c3fac
IMAGE_NAME:  memory_corruption
FAILURE_BUCKET_ID:  0x4E_99_nt!MiBadShareCount+24
BUCKET_ID:  0x4E_99_nt!MiBadShareCount+24
Followup: MachineOwner

Si nos fijamos en MODULE_NAME y IMAGE_NAME este es el error, que tenemos, los bloques de memoria están corruptos, pero para asegurarnos de que es la memoria física, tenemos que usar este comando:
0: kd> !memusage
Search: READ_PVOID error
InitTypeRead(nt!MmPhysicalMemoryBlock, nt!_PHYSICAL_MEMORY_DESCRIPTOR) error 1
En este caso ya está más que claro, que es lo que está fallando y para detectar cual es el modulo de memoria que nos está fallando (en el caso de que tenemos más de 1 modulo) tenemos que realizar un test de la memoria física.

0 comentarios:

Publicar un comentario