2009-09-28 16 views
7

Para probar este problema, he escrito una aplicación de Windows mínima. Si fuerzo una infracción de acceso en el controlador WM_PAINT, esta excepción nunca llega al depurador. Si se inició sin depurador, la infracción de acceso tampoco aparece. Por lo general, debe obtener el cuadro de diálogo Informes de errores de Windows.violación de acceso en WM_PAINT no detectada

excavar un poco más profundo que parece que algo en user32.dll captura todas las excepciones entrantes. ¿Es este comportamiento normal? ¿Puedo controlar esto de alguna manera? ¿No está atrapando todas las excepciones un riesgo de seguridad? Al menos es tan molesto como el infierno.

esto es con una aplicación de 32 y 64 bits en Vista 64. En XP excepción parece ser manejados como se esperaba. Otros mensajes de Windows tienen el mismo problema. Quizás todos ellos?

El manejador WM_PAINT:

case WM_PAINT: 
    hdc = BeginPaint(hWnd, &ps); 
    *(int*)0 = 0; 
    EndPaint(hWnd, &ps); 
    break; 

Respuesta

5

Como solución elimino todos los controladores de excepciones registradas en mi procedimiento de ventana. Bastante feo.

 
LRESULT CALLBACK window_proc( 
    HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    // get thread information block 
    NT_TIB* tib; 
    __asm { 
     mov EAX, FS:[18h] 
     mov [tib], EAX 
    } 
    // old exception handler list 
    _EXCEPTION_REGISTRATION_RECORD* old_exception_handler = tib->ExceptionList; 
    // remove all exception handler with exception of the default handler 
    while(tib->ExceptionList->Next != (_EXCEPTION_REGISTRATION_RECORD*)-1) { 
     tib->ExceptionList = tib->ExceptionList->Next; 
    } 

    LRESULT result = DefWindowProc(hwnd, uMsg, wParam, lParam); 

    // restore old exception handler 
    tib->ExceptionList = old_exception_handler; 

    return result; 
} 
0

excepción será lanzada en WinXP y Vista. Acabo de probar esto en Vista en las configuraciones de depuración y liberación. ¿Tiene el mismo problema en el nuevo proyecto de aplicación Win32?

3

DispatchMessage parece contener ahora un bloque catch SEH try que inhibe excepciones generadas por procsos ventana.

Todavía puede detectar estas excepciones en el depurador, dependiendo de la versión de su estudio visual, necesita abrir el diálogo de depuración y excepciones y marcar la columna "Salir cuando se lanza una excepción" para todas las excepciones de Win32, o al menos excepción 0xc0000005

+0

sé, pero esto es sólo una solución si se utiliza un depurador. ¿Y qué pasa con todas las demás excepciones que pueden producirse al manejar mensajes de Windows? ¿Tiene alguna documentación o razonamiento oficial (o no oficial) para este cambio? –

0

Me he dado cuenta de que, cuando tiene habilitado Aero (que es por defecto en Vista), cambiar el tamaño de ventanas tiende a crear muchas, muchas fallas de página. Estas tampoco son fallas normales de memoria virtual que necesita ser paginada. Sospecho (aunque es solo una teoría), que Aero redirige la salida de gráficos a un trozo de memoria protegido y detecta las fallas para saber qué partes de la superficie visible deben recomponerse en el escritorio. Quizás eso también es comer otras violaciones de acceso.

+0

A partir de la memoria de video Vista se virtualiza. Esto no debe correlacionarse con ninguna excepción en las aplicaciones. Al menos, Aero habilitado o no, no cambia nada con el manejo de excepciones en los mensajes de Windows. –

+0

Tienes razón. La excepción se descarta independientemente de si la composición del escritorio está habilitada o no. –

0

A partir de XP, la funcionalidad de control de excepciones vector puede usarse. Tiene prioridad sobre todos los demás tipos de excepciones. En mi ejemplo, capturó correctamente la Infracción de acceso en el mensaje WM_PAINT. Desafortunadamente, también capta todos los otros tipos de excepciones, que probablemente debería resolver comprobando el código de excepción.

Cuestiones relacionadas