2012-04-17 11 views
7

Sto lavorando con una libreria C di grandi dimensioni in cui alcuni indici di array sono calcolati utilizzando int. Ho bisogno di trovare un modo per intrappolare gli overflow integer in fase di runtime in modo tale da restringere a una riga di codice problematica. Libc manuale afferma:Rileva overflow intero

FPE_INTOVF_TRAP Integer Overflow (impossibili in un programma C a meno che non consentono di overflow intrappolare in modo specifico per l'hardware).

tuttavia l'opzione gcc -ffpe-trap suggerisce che quelli si applicano solo ai numeri FP?
Quindi, come faccio a abilitare il trap trabocco per interi? Il mio sistema è Xeon/Core2, gcc-4.x, Linux 2.6

Ho esaminato domande simili ma tutte si sono decise a modificare il codice. Devo sapere comunque quale codice è problematico in primo luogo.
Se gli Xeon non possono intercettare gli overflow, quali processori possono? Ho accesso anche a macchine non-emt64.

Ho trovato uno strumento progettato per llvm nel frattempo: http://embed.cs.utah.edu/ioc/ Non sembra esserci comunque un equivalente per gcc/icc?

+0

Per quanto ne so, nessun processore x86 supporta il trapping sull'intero overflow. Molti cpus RISC do (almeno lo fanno sia power che sparc), così come le vecchie CPU mini/mainframe (come VAX) –

+0

Potrei provare Power, nessun VAX in giro. – Anycorn

risposta

3

Ok, potrei dover rispondere alla mia stessa domanda.

Ho trovato che gcc ha l'opzione -ftrapv, un test rapido conferma che almeno l'overflow del mio sistema è intrappolato. Pubblicherò informazioni più dettagliate man mano che imparerò di più poiché sembra uno strumento molto utile.

+0

Vedi anche: http://stackoverflow.com/a/5005792/462335 – nibot

2

L'aritmetica dei numeri interi senza segno non trabocca, ovviamente.

Con l'aritmetica con numero intero con segno, l'overflow porta a un comportamento non definito; potrebbe succedere di tutto. E gli ottimizzatori stanno diventando aggressivi sull'ottimizzazione di cose che traboccano. Quindi, la soluzione migliore è evitare l'overflow, piuttosto che intrappolarlo quando ciò accade. Prendi in considerazione l'utilizzo del CERT 'Secure Integer Library' (l'URL a cui si fa riferimento sembra essersi sparito AWOL/404, non sono sicuro di cosa sia ancora successo) o la libreria di Google 'Safe Integer Operation'.

Se è necessario intercettare l'overflow, sarà necessario specificare la piattaforma di interesse (O/S inclusa la versione, il compilatore inclusa la versione), poiché la risposta sarà molto specifica della piattaforma.

+1

Ho bisogno di sapere * quali * operazioni sostituire (con size_t). Ho specificato il sistema/compilatore nella domanda. – Anycorn

2

Sapete esattamente su quale linea si sta verificando l'overflow? Se è così, potresti essere in grado di vedere il flag di Carry dell'assemblatore se l'operazione in questione ha causato un overflow. Questo è il flag che la CPU usa per eseguire un calcolo numerico elevato e, sebbene non disponibile al livello C, potrebbe aiutarti a risolvere il problema, o almeno ti dà la possibilità di fare qualcosa.

BTW, trovato this collegamento per gcc (-ftrapv) che parla di una trappola intera. Potrebbe essere quello che stai cercando.

+0

no, il problema è trovare dove avviene l'overflow – Anycorn

+2

Qualche possibilità di far cadere una scrittura sul breakpoint della memoria sul contatore per aiutarti? –

+0

Io non la penso così. Ci sono più posti in cui 'int' vengono usati al posto di' size_t', il debugging manuale è molto difficile. Potrei aver trovato una soluzione però. – Anycorn

0

È possibile utilizzare assembler inline in gcc di utilizzare un'istruzione che potrebbe generare un troppo pieno e quindi verificare il flag di overflow per vedere se lo fa in realtà:

int addo(int a, int b) 
{ 
    asm goto("add %0,%1; jo %l[overflow]" : : "r"(a), "r"(b) : "cc" : overflow); 
    return a+b; 
overflow: 
    return 0; 
} 

In questo caso, si tenta di aggiungere a e b e, in caso affermativo, passa all'etichetta overflow. Se non ci sono overflow, continua, facendo di nuovo l'add e restituendolo.

Questo si verifica nella limitazione GCC che un blocco asm in linea non può emettere un valore e forse un ramo - se non fosse per quello, non sarebbe necessario un secondo add per ottenere effettivamente il risultato.

Problemi correlati