2009-09-28 18 views
7

Per verificare questo problema, ho scritto un'applicazione Windows minima. Se imposto una violazione di accesso nel gestore WM_PAINT questa eccezione non arriva mai al debugger. Se avviato senza debugger, anche la violazione di accesso non viene visualizzata. Di solito dovresti ottenere la finestra di dialogo Segnalazione errori di Windows.violazione di accesso in WM_PAINT non rilevato

Scavando un po 'più in profondità, sembra che qualcosa in user32.dll rilevi tutte le eccezioni in arrivo. Questo comportamento normale? Posso controllare questo in qualche modo? Non sta prendendo tutte le eccezioni un rischio per la sicurezza? Almeno è fastidioso da morire.

Questo è con un'applicazione a 32 e 64 bit su Vista 64. Su XP l'eccezione sembra essere gestita come previsto. Altri messaggi di Windows hanno lo stesso problema. Forse tutti loro?

Il WM_PAINT gestore:

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

risposta

5

Come soluzione temporanea, rimuovo tutti i gestori di eccezioni registrati nella procedura della finestra. Abbastanza brutto.

 
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

Eccezione sarà gettato in WinXP e Vista. Ho appena provato questo in Vista in debug e versioni di rilascio. Hai lo stesso problema nel nuovo progetto di applicazione Win32?

3

DispatchMessage sembra ora contenere un blocco catch di prova SEH che inibisce le eccezioni generate dai window proc.

Nel debugger si possono ancora rilevare queste eccezioni: a seconda della versione di Visual Studio è necessario aprire la finestra di dialogo debug-> eccezioni e spuntare la colonna "Interrompi quando un'eccezione viene lanciata" per tutte le eccezioni Win32, o almeno eccezione 0xc0000005

+0

Lo so, ma questa è solo una soluzione se si utilizza un debugger. E che cosa è con tutte le altre eccezioni che potrebbero essere generate durante la gestione dei messaggi di Windows? Avete documentazione o ragionamento ufficiale (o non ufficiale) per questo cambiamento? –

0

Ho notato che, quando si dispone di Aero abilitato (che è di default in Vista), il ridimensionamento di finestre tende a creare molti, molti errori di pagina. Non si tratta nemmeno di errori di memoria virtuale, che devono essere impaginati. Sospetto (anche se è solo una teoria), che Aero reindirizza l'output grafico su un blocco protetto di memoria e cattura i difetti per sapere quali bit della superficie visibile devono essere ricomposti sul desktop. Forse sta anche mangiando altre violazioni di accesso.

+0

A partire da Vista la memoria video è virtualizzata. Questo non dovrebbe essere correlato ad alcuna eccezione nelle applicazioni. Almeno abilitato o meno Aero non cambia nulla con la gestione delle eccezioni nei messaggi di Windows. –

+0

Hai ragione. L'eccezione viene eliminata indipendentemente dal fatto che il compositing desktop sia abilitato o meno. –

0

A partire da XP, è possibile utilizzare la funzionalità di gestione delle eccezioni del vettore. Ha la priorità su tutti gli altri tipi di eccezioni. Nel mio esempio, ha rilevato correttamente la violazione di accesso nel messaggio WM_PAINT. Sfortunatamente, rileva anche tutti gli altri tipi di eccezioni, che probabilmente dovrei risolvere controllando il codice di eccezione.

Problemi correlati