2011-01-14 8 views
19

Me encuentro con un problema extraño en un generador de perfiles de muestreo en Windows 7 (no hay tales problemas AFAICT en los sistemas operativos Windows anteriores, ya sean de 32 o 64 bits).GetThreadContext falla después de un SuspendThread exitoso en Windows 7

El generador de perfiles funciona suspendiendo periódicamente un hilo con SuspendThread, a continuación, examina el contexto con GetThreadContext, antes de invocar ResumeThread para reiniciar el proceso. Todo esto se hace desde el contexto de la secuencia de un temporizador multimedia (para precisión, a aproximadamente 1 kHz, que en sistemas operativos anteriores a Windows 7 generalmente tiene una penalización de rendimiento insignificante).

En Windows 7 y Windows 7 solamente, a pesar de que las llamadas a SuspendThread (y ResumeThread) todos tienen éxito, las llamadas a GetThreadContext con el error:

ERROR_NOACCESS
998 (0x3E6)
Invalid access to memory location.

con una muy alta verosimilitud, aunque no todos el tiempo.

Con esto quiero decir que para algunas ejecuciones de perfiles, todo funcionará como lo hace en otros sistemas operativos (todas las llamadas GetThreadContext tendrán éxito), pero para otras ejecuciones, casi todas fallarán (excepto una docena, fuera de decenas de milésimas). Está sucediendo con los mismos binarios, los mismos parámetros.

He intentado hacer sugerencias sobre problemas de aspecto vagamente similares para repetir la llamada GetThreadContext, sin más éxito. También he intentado hacer un Sleep entre SuspendThread y GetThreadContext, luego el GetThreadContext tiene más éxito, aunque se traduce en ralentizaciones drásticas.

Sin embargo, sugiere que el sistema operativo Windows 7 está volviendo de SuspendThread mientras que el hilo probablemente no se ha suspendido aún - aunque, si ese es el caso, no tengo idea de cómo esperar adecuadamente la suspensión, haciendo un bucle en el hilo y golpes GetThreadContext no lo hace.

Editar: 16 bytes alineación de la dirección de la estructura de CONTEXTGetThreadContext según lo sugerido por Dan Bartlett parece estar haciendo el truco!

+0

Parece muy específico. Tal vez debería encontrar una compilación comprobada de Windows para encontrar el problema. ¿Describiste este problema en los foros de desarrolladores de MSDN? O tal vez presentar un error en MS directamente. – ChristianWimmer

+3

¿Utilizó la propiedad THREAD_ALL_ACCESS al crear el proceso? Consulte http://msdn.microsoft.com/en-us/library/ms686769(v=vs.85).aspx que indica que "El valor del indicador THREAD_ALL_ACCESS aumentó en Windows Server 2008 y Windows Vista" ... –

+9

CONTEXT se declara con "DECLSPEC_ALIGN (16)" en WinNT.h, ¿quizás es un problema de alineación? –

Respuesta

16

En cuanto a la función GetThreadContext, se menciona que

The CONTEXT structure is highly processor specific. Refer to the WinNt.h header file for processor-specific definitions of this structures and any alignment requirements.

Y mirando a este archivo, _context se declara con

typedef struct DECLSPEC_ALIGN(16) _CONTEXT { 
... 

Así que es posible que podría ser un problema de alineación.

+0

Dato curioso y estúpido: puede llamar a GetThreadContext() en Windows 9x con la estructura CONTEXT desalineada a 16, pero desde NT necesita alinear su ubicación de memoria para que GetThreadContext funcione bien. –