2009-10-25 16 views
10

Hice un programa muy simple que automatiza algunas cosas para mí. Lo escribí en C++ y se ejecuta en Windows. Al depurarlo con GDB desde el Codeblocks IDE, obtengo muchos puntos de ruptura de la nada. No tengo idea de qué podría estar causando este problema. Los puntos de interrupción parecen estar relacionados con problemas de memoria ... ya que cuando arreglé una fuga de memoria que había detectado, el número de puntos de interrupción obtuvo significativamente menos.Puntos de ruptura de la nada cuando se depura con gdb, dentro de ntdll

El exactamente lo que me dice es GDB:

Program received signal SIGTRAP, Trace/breakpoint trap. 
In ntdll!TpWaitForAlpcCompletion() (C:\Windows\system32\ntdll.dll) 

me sale esto muchas veces dentro de mi programa. Creo que podría estar haciendo algo muy mal, aunque el programa parece funcionar bien y logra lo que quiero que haga. ¿Alguien puede decirme cuál es el problema ya que no sé dónde mirar? Además, si no es un problema, ¿alguien sabe cómo desactivarlo, ya que esto me impide llegar a los puntos de interrupción que establecí?

¡Gracias de antemano!

EDITAR: (Agregando la salida del comando GDB's where): ¿Dónde puedo verificar lo que hace cada una de estas funciones, entonces puedo ver lo que estoy haciendo mal?

#0 0x76fefadd in ntdll!TpWaitForAlpcCompletion() from C:\Windows\system32\ntdll.dll 
#1 0x0028e894 in ??() 
#2 0x76fb272c in ntdll!RtlCreateUserStack() from C:\Windows\system32\ntdll.dll 
#3 0x00657fb8 in ??() 
#4 0x00657fb8 in ??() 
#5 0x76f4b76a in ntdll!RtlDowncaseUnicodeChar() from C:\Windows\system32\ntdll.dll 
#6 0x02070005 in ??() 
#7 0x00000b10 in ??() 
#8 0x0028e8dc in ??() 
#9 0x76ff0b37 in ntdll!TpQueryPoolStackInformation() from C:\Windows\system32\ntdll.dll 
#10 0x038b0000 in ??() 
#11 0x00657fb8 in ??() 
#12 0x76f4b76a in ntdll!RtlDowncaseUnicodeChar() from C:\Windows\system32\ntdll.dll 
#13 0x6e6e9a5e in ??() 
#14 0x038b0000 in ??() 
#15 0x038b0000 in ??() 
#16 0x00000000 in ??() 
+0

¿Cómo se ve el resto de la pila de llamadas cuando obtiene un SIGTRAP? Por favor, publique la salida del comando GDB "where". –

+0

Gracias por su respuesta, anexaré el resultado de "dónde" en la pregunta. Editando ahora ... – Lefteris

Respuesta

16

Si bien la cuestión es bastante viejo ahora, he aquí algunos puntos que podrían ayudar a alguien que vendría aquí después de una búsqueda como lo hice:

yo sólo encontré con ese problema durante las pruebas en Win7 una aplicación desarrollada por mí en WinXP. En mi caso, está relacionado tanto con la supervisión de la administración de memoria de Windows 7 como con una mala asignación de memoria en mi aplicación.

Para hacer la historia corta, en el código de la aplicación, un bloque de memoria que se malloced por error (en lugar de utilizar GlobalAlloc()) y fue liberado con una GlobalFree() (que es incorrecto, ya que se accedió a la pila del sistema con un puntero de el grupo de memoria de tiempo de ejecución de C). Si bien esto está causando una fuga de memoria (muy pequeña en ese caso), pasó completamente desapercibido mientras se probaba en WinXP y todo el programa se ejecutaba aparentemente correctamente.

Ahora cuando se ejecuta en Win7, una función de control de memoria llamadas Fault Tolerant Heap (FTH) detecta este error de la aplicación (que está causando una excepción):

  • Al mismo tiempo que se está emitiendo algo de información a través de OutputDebugString() (o tal vez DbgPrint()) que se puede ver utilizando la herramienta DebugView simple, o por cualquier depurador al rastrear la aplicación. Por lo tanto, justo antes de la señal recibida, puede ver algo así en los mensajes:

    advertencia: HEAP [name_of_your.EXE]:

    advertencia: La dirección no especificada a RtlFreeHeap (006B0000, 006A3698)

  • y (en el caso de que se está depurando la aplicación) que da salida a un punto de interrupción que no tiene efecto fuera de un depurador, pero de lo contrario eso debería ayudar a señalar el problema. Ese punto de interrupción se muestra como la señal SIGTRAP por GDB.

En este punto usted tiene 2 alternativas:

  • tratar de caminar la pila de llamadas para encontrar la instrucción defectuosa en su código (por desgracia, en ese caso, los bt o where GDB no pueden demostrar ahora suficiente para ver dónde en mi código el montón fue liberado erróneamente - si alguien sabe cómo mostrar la pila de llamadas correcta desde el módulo de inicio en lugar de ntdll, hágamelo saber)
  • intente continuar ya que FTH tiene la capacidad de automágicamente patc h en la memoria como un intento de evitar el error (que el parche automagic también puede ocurrir con antelación en la próxima ejecución de la aplicación)

Para no detenerse en el momento del problema montón, como dijo Moshe Levi, puede establecer un handle SIGTRAP nostop en el indicador de GDB antes de iniciar la aplicación.

Así que en resumen: sí, usted tiene algo mal en su código en relación con la gestión de memoria, pero en algunos casos se puede ejecutar sin fallar. Pero en el modo de depuración, el núcleo intenta ponerlo en la ruta del problema.

+0

Agregaría que parece que no siempre el código es incorrecto. Tengo un problema bastante similar, y veo una advertencia 'Bloque Heap en 003E5E78 modificado en 003E5EBA pasado tamaño solicitado de 3a'. Incluso estoy atrapado en el lugar equivocado que desencadena la advertencia, y el código se ve bien: he creado «wchar_t» array con «nuevo» y luego lo libero con «delete []». Probablemente un error en MinGW. Por cierto, una cosa lo confirma indirectamente: he probado la aplicación en GNU/Linux con valgrind, y no noté ningún problema. –

2

Recomendaría utilizar WinDBG, el depurador nativo de Windows. Esto proporcionará mejores trazas de pila, especialmente para los símbolos cuando pasa al modo kernel.

7

Vaya, me envió de vuelta a 5 años cuando solía BGF en la plataforma Linux :)

puede evitar que GDB para romper al recibir SIGTRAP con el siguiente comando:

handle SIGTRAP nostop 

Pero Estoy aquí con Steve, pruebe con WinDbg. Fue construido especialmente para Windows.

+0

¿Dónde crees que se podría obtener un WinDbg gratis? AFAIK solo se trae con Visual Studio, dudo que alguien vaya a comprarlo solo por un depurador, que ni siquiera es mejor gdb. Pero ⁺¹ de todos modos: no me di cuenta de que un punto de interrupción en las bibliotecas del sistema causa otra señal, diferente de una ruptura habitual. –

+1

WinDbg es gratuito y viene como parte del paquete Debugging Tools for Windows. Puede descargarlo desde http://www.microsoft.com/click/services/Redirect2.ashx?CR_EAC=300135395 –

1

Acabo de experimentar este bloqueo usando gcc/mingw con Qt Creator.

Tuve otros problemas, también, incluyendo variables que parecían estar equivocadas (compensadas por 6 bytes). En mi caso, resultó ser un paquete pragma que causó estragos en el código.

Tenía esta:

#pragma pack(1) 
typedef struct SomeStruct 
{ 
... // structure 
} SomeStruct; 

... pero no terminó con un paquete pragma() para terminar el embalaje de 1 después de la estructura y volver a la alineación de bytes por defecto/embalaje. Agregando que lo arregló:

#pragma pack(1) 
typedef struct SomeStruct 
{ 
... // structure 
} SomeStruct; 
#pragma pack() // <<-- with this line the heap corruption problem was stopped 
Cuestiones relacionadas