Nel codice mostrato di seguito ho utilizzato tutti i modi documentati per rilevare un'eccezione e produrre una diagnostica. Utilizza le parole chiave try/catch di C++, rileva un'eccezione SEH con le parole chiave dell'estensione __try/__catch
, utilizza le funzioni winapi di AddVectoredExceptionHandler() e SetUnhandledExceptionFilter() per installare i filtri VEH/SEH.Come segnalare un sovraccarico del buffer dello stack su Windows?
Esecuzione con Visual C++ 2003:
/GS: output "ciao, mondo!" e termina con il codice di uscita 0.
/GS-: uscite "ciao, mondo!" e termina con il codice di uscita 0.
L'esecuzione di questo con Visual C++ 2013:
/GS: nessuna uscita, termina con codice di uscita -1.073,740791 millions
/GS-: "Ciao, mondo" uscite e termina con exit con 0.
Come si produce una diagnostica in un programma compilato VS2013 con/GS in vigore?
#include "stdafx.h"
#include <Windows.h>
#define CALL_FIRST 1
#define CALL_LAST 0
LONG WINAPI MyVectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
printf("MyVectoredHandler\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI MyUnhandledExceptionFilter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
printf("SetUnhandledExceptionFilter\n");
return EXCEPTION_CONTINUE_SEARCH;
}
void f()
{
__try
{
char p[20] = "hello,world!";
p[24] = '!';
printf("%s\n", p);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("f() exception\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AddVectoredExceptionHandler(CALL_FIRST, MyVectoredHandler);
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
try{
f();
}
catch (...){
printf("catched f exception\n");
}
return 0;
}
Il codice causa un comportamento non definito. L'unico modo affidabile per "rilevare" è controllare i limiti prima di eseguire l'accesso fuori limite –
... come quello che verrebbe fatto se si utilizza un tipo di contenitore che esegue il rilevamento. per esempio. usando 'std :: string' per le stringhe e indicizzandolo con la funzione membro' at'. – Hurkyl
I sovraccarichi dello stack sono difficili da rilevare. Si attivano solo quando si sovrascrive il frame dello stack. Prova a passare all'eccezione di runtime * Limiti di array superati *. Potrebbe funzionare. – cup