Pergunta

Para testar esse problema, escrevi um aplicativo mínimo do Windows. Se eu forçar uma violação de acesso no WM_PAINT Manipulador Esta exceção nunca chega ao depurador. Se iniciado sem o depurador, a violação do acesso também não aparece. Normalmente, você deve obter a caixa de diálogo Relatórios de erro do Windows.

Cavando um pouco mais profundamente, parece que algo no usuário32.dll pega todas as exceções recebidas. Isso é comportamento normal? Posso controlar isso de alguma forma? Não capturar todas as exceções não é um risco de segurança? Pelo menos é irritante como o inferno.

Isso é com um aplicativo de 32 e 64 bits no Vista 64. No XP, a exceção parece ser tratada conforme o esperado. Outras mensagens do Windows têm o mesmo problema. Talvez todos eles?

o WM_PAINT manipulador:

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

Solução

Como solução alternativa, removo todos os manipuladores de exceção registrados no meu procedimento de janela. Muito feio.

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;
}

Outras dicas

É um defeito conhecido. Verifique o hotfix.http://support.microsoft.com/kb/976038

O DispatchMessage parece agora conter um bloco de pet de tentativa do SEH que inibe exceções geradas pelo Window Procs.

Você ainda pode capturar essas exceções no depurador - dependendo da sua versão do Visual Studio, você precisa abrir a depuração-> Caixa de diálogo Exceções e marcar a coluna "Break quando uma exceção é lançada" para todas as exceções do Win32, ou pelo menos exceção 0xc00005

A exceção será lançada no WinXP e no Vista. Acabei de testar isso no Vista em configurações de depuração e lançamento. Você tem o mesmo problema no novo projeto de aplicativo Win32?

Percebi que, quando você tem aero ativado (que é por padrão no Vista), o redimensionamento do Windows tende a criar muitas, muitas falhas de página. Estes não são falhas normais de memória virtual também. Suspeito (embora seja apenas uma teoria), que aero redirecre a saída gráfica para um pedaço de memória protegido e pega as falhas para saber quais bits da superfície visível precisam ser recompostos na área de trabalho. Talvez isso esteja comendo outras violações de acesso também.

A partir do XP, a funcionalidade de manuseio de exceção do vetor pode ser usada. Tem prioridade sobre todos os outros tipos de exceções. No meu exemplo, ele pegou corretamente a violação de acesso na mensagem WM_PAINT. Infelizmente, ele também captura todos os outros tipos de exceções, que eu provavelmente deveria resolver verificando o código de exceção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top