2012-05-08 11 views
6

He tenido problemas al intentar rastrear una Infracción de acceso en mi programa. Ocurre cuando se llama al destructor por tercera vez, exactamente cuando el destructor parece terminar.C++ ¿Algún consejo sobre cómo rastrear las violaciones de acceso?

He pasado horas intentando rastrear esto, así que estoy buscando más consejos sobre lo que puedo hacer. Estoy creando la instancia de clase con los operadores new y delete. La ventana de resultados de Visual Studio muestra:

First-chance exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab. Unhandled exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.

¿Hay algo que pueda hacer para tratar de averiguar lo que había en esos lugares de memoria?

La ventana de pila de llamadas muestra los siguientes (en orden inverso al que he pegado en el orden cronológico, más temprano que tarde):

Program.exe!Network::`scalar deleting destructor'() + 0x2b bytes C++ 

Program.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >() Line 754 + 0xf bytes C++ 

Program.exe!std::_String_val<wchar_t,std::allocator<wchar_t> >::~_String_val<wchar_t,std::allocator<wchar_t> >() Line 478 + 0xb bytes C++ 

msvcp100d.dll std :: _ Container_base12 :: _Orphan_all() Línea 214 + 0x5 bytes C++

Mi mejor estimación es que existe algún tipo de variable de cadena que causa el problema? ¿Alguien tiene algún consejo sobre la interpretación de esta información?

Cualquier otro consejo también sería útil, gracias de antemano.

Estoy codificando bajo Windows 7 y usando Visual Studio 2010 Professional.

+2

[valgrind] (http://valgrind.org/) – dasblinkenlight

+1

0xABABABAB es utilizado por HeapAlloc como bytes de guardia. Usted puede estar corrompiendo la memoria en alguna parte. http://asawicki.info/news_1292_magic_numbers_in_visual_c.html –

+0

@dasblinkenlight Tan genial como es Valgrind, no es compatible con Windows. – cgmb

Respuesta

3

He tenido éxito en el seguimiento de errores de memoria antes de usar BoundsChecker (now part of Borland DevPartner). Hay una serie de productos similares que también pueden ayudar: HeapAgent y Rational Purify. Estos parecen ser muy parecidos a ValGrind, pero funcionan en Windows.

Aquí hay 3 alternativas de código abierto que podrían ayudar:

  1. DUMA (por el aspecto de la misma, que tendrá que construirlo para Windows sí mismo, pero el Léame contiene algunas notas en hacer eso)

  2. XMEM

  3. elephant

No tengo idea de cómo funcionan, pero suenan muy prometedores, y parece que todos funcionan en Windows de una forma u otra.

Este Microsoft page on managing memory errors también podría ser útil, y también tiene enlaces a la configuración de puntos de interrupción de memoria, que pueden ayudarlo a saber cuándo se borran o se borran por primera vez sus datos. ¡Buena suerte!

+0

Si bien esos enlaces parecen interesantes, preferiría no tener que comprar un nuevo software para resolver esto. – Interminable

+0

Mi proyecto debe entregarse en menos de una semana, quiero tener este código listo en un par de días, no puedo permitirme instalar un sistema operativo con el que no estoy familiarizado e intentar codificarlo en un IDE que no conozco con el fin de utilizar el software de depuración que no está garantizado para resolver el problema que estoy experimentando, lo siento. EDITAR: el comentario al que respondió este comentario parece haberse desvanecido. – Interminable

+0

El enlace de BoundsChecker está muerto – TankorSmash

2

Utilice las cosas de depuración de Microsoft Heap y espere que el suyo sea uno de los casos para los que fue diseñado. Purificar sería el siguiente paso después de eso.

Está integrado en Visual Studio y es útil en algunos casos. Si funciona, es mejor que le dé a IBM dos o tres bolsillos llenos de efectivo para Purify.

Puede encontrar la información here

TL; DR En principal, hace esto

 
int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 
// Turn On (OR) - Keep freed memory blocks in the 
// heap's linked list and mark them as freed 
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF; 

// Turn on memory checking at each heap operation 
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF; 

// Set the new state for the flag 
_CrtSetDbgFlag(tmpFlag); 

se puede cambiar la bandera _CRTDBG_CHECK_ALWAYS_DF en diferentes lugares si se ejecuta demasiado lento. Sin embargo, lo ejecuté varias veces con cada operación de pila revisada para tener una idea de dónde ocurre el problema.

1

de escribir este blog con algunos consejos

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

Lo principal que hay que hacer es conseguir que el choque o excepción a suceder mientras el código con el error está todavía en la pila. Muchas veces se obtiene una Infracción de acceso un tiempo después de que el código con el error se haya ejecutado y devuelto, y en realidad puede ser mucho tiempo después (en tiempo de la computadora). En ese caso, es casi imposible descubrirlo.

En su caso, con el problema marcado en eliminar, es un indicador fuerte de que el montón está dañado, y dos razones comunes en C++ son la eliminación doble y la eliminación de matriz mezclada (utilizando delete cuando debería usar delete [] O al revés).

Si puede reproducirlo con un código simple, buscaría los dos problemas anteriores. De lo contrario, descargue las herramientas de depuración de Microsoft y use gflags +hpa -i program.exe para hacer que el montón sea mucho más sensible a la corrupción (informará el error mucho más rápido).

Cuestiones relacionadas