Violação de acesso em wm_paint não pego
-
18-09-2019 - |
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;
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.