Domanda

Stiamo usando DevPartners boundchecker per rilevare problemi di perdita di memoria. Si sta facendo un ottimo lavoro, anche se non trova overflow stringa come il seguente

char szTest [1] = "";

for (i = 0; i < 100; i ++) {

    strcat (szTest, "hi");
}

Domanda-1:? È il loro qualsiasi modo, posso fare BoundsChecker per rilevare questo

Domanda-2:? È il loro qualsiasi altro strumento in grado di rilevare tali questioni

È stato utile?

Soluzione

ho provato nella mia DevPartner (msvc6.6) (DevPartner 7.2.0.372)

che confermo il vostro comportamento osservato. Ottengo una violazione di accesso dopo circa 63 passi del ciclo.

Che cosa significa Compuware hanno da dire sulla questione?

CppCheck rileverà questo problema.

Altri suggerimenti

Una possibilità è quella di vietare semplicemente l'uso delle funzioni di stringa che non hanno informazioni sul buffer di destinazione. Un insieme di macro come il seguente in un colpo di testa universalmente incluso può essere utile:

#define strcpy  strcpy_is_banned_use_strlcpy
#define strcat  strcat_is_banned_use_strlcat
#define strncpy strncpy_is_banned_use_strlcpy
#define strncat strncat_is_banned_use_strlcat
#define sprintf sprintf_is_banned_use_snprintf

Quindi, qualsiasi uso tentativi di routine 'vietati' si tradurrà in un errore di linker che ti dice anche ciò che si dovrebbe usare invece. MSVC ha fatto qualcosa di simile che può essere controllato tramite le macro come _CRT_SECURE_NO_DEPRECATE.

Lo svantaggio di questa tecnica è che se si dispone di un grande insieme di codice esistente, può essere un enorme lavoro di routine per ottenere le cose spostati verso utilizzando i nuovi, le routine più sicure. Si può farvi impazzire fino a quando hai ottenuto liberarsi delle funzioni considerate pericolose.

valgrind rileverà la scrittura passato i dati allocati dinamicamente, ma non credo che possa farlo per gli array automatiche come nel tuo esempio. Se si utilizza strcat, strcpy, ecc, è necessario assicurarsi che la destinazione è abbastanza grande.

Modifica : ero ragione su valgrind , ma c'è qualche speranza:

  

Purtroppo, MemCheck non fa controllo dei limiti su array statici o pila. Ci piacerebbe, ma non è solo possibile fare in modo ragionevole che si adatta con il funzionamento MemCheck. Siamo spiacenti.

     

Tuttavia, lo strumento sperimentale Ptrcheck in grado di rilevare gli errori di questo tipo. Eseguire Valgrind con l'opzione --tool=exp-ptrcheck di provarlo, ma attenzione che non è così robusta come MemCheck.

Non ho usato Ptrcheck.

È possibile che il compilatore può aiutare. Ad esempio, in Visual Studio 2008, controllare le proprietà del progetto - C ++ C / - pagina Generazione di codice. C'è un "cuscinetto di sicurezza Check" opzione.

La mia ipotesi è che si riserva un po 'di memoria in più e scrive una sequenza conosciuta in là. Se tale sequenza viene modificata, assume un sovraccarico del buffer. Non sono sicuro, anche se - Ricordo di aver letto da qualche parte, ma non ricordo con certezza se si trattava di VC ++

.

Dato che avete codificato questo ++ C, perché usare un puntatore a char a tutti?

std::stringstream test;
std::fill_n(std::ostream_iterator<std::string>(test), 100, "hi");

Se si attiva l' / RTCs interruttore compilatore , può aiutare i problemi di cattura di questo tipo. Con questo interruttore, il test ha causato una violazione di accesso quando si esegue il strcat una sola volta.

Un altro programma di utilità utile che aiuta con problemi come questo (più heap-oriented di pila ma estremamente utile) è Application verifier . E 'gratuito e può prendere un sacco di problemi legati alla heap overflow.

In alternativa: il nostro Memoria Checker sicurezza . Penso che sarà gestire questo caso.

Il problema è che per impostazione predefinita, il sottosistema di convalida API non è abilitato, ei messaggi che erano interessati a venire da lì.

Non posso parlare per le versioni precedenti di BoundsChecker, ma la versione 10.5 non ha particolari problemi con questo test. Esso riporta i risultati corretti e BoundsChecker per sé non va in crash. L'applicazione di test, tuttavia, perché questo particolare caso prova corrompe completamente lo stack di chiamate che ha portato alla funzione in cui il codice di prova era, e non appena terminata tale funzione, l'applicazione fatto troppo.

I risultati: 100 messaggi su scrittura overrun a una variabile locale, e 99 messaggi circa la stringa di destinazione non viene nulla terminata. Tecnicamente, che secondo messaggio non è giusto, ma BoundsChecker ricerca solo per la terminazione nullo entro i limiti della stringa di destinazione stessa, e dopo la prima chiamata strcat, non è più contiene un byte zero all'interno dei suoi confini.

Disclaimer: io lavoro per MicroFocus come sviluppatore che lavora su BoundsChecker

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top