2012-04-17 10 views
7

Ich arbeite mit einer großen C-Bibliothek, wo einige Array-Indizes mit int berechnet werden. Ich muss einen Weg finden, Integer-Überläufe zur Laufzeit so zu fangen, dass sie sich auf problematische Codezeilen beschränken. Libc Handbuch heißt es:Detect Integer-Überlauf

FPE_INTOVF_TRAP Integer Überlauf (nicht in einem C-Programm, wenn Sie Überlauf ermöglichen, in einer Hardware-spezifische Art und Weise Trapping).

jedoch GCC-Option -ffpe-trap schlägt vor, dass diese nur für FP-Nummern gelten?
So wie ich Integer Overflow Trap aktivieren? Mein System ist Xeon/Core2, gcc-4.x, Linux 2.6

Ich habe ähnliche Fragen durchgesehen, aber sie alle kochen, um den Code zu ändern. Ich muss jedoch wissen, welcher Code überhaupt problematisch ist.
Wenn Xeons Überläufe nicht abfangen können, welche Prozessoren können? Ich habe auch Zugriff auf Nicht-Emt64-Maschinen.

Ich habe inzwischen ein Tool für llvm gefunden: http://embed.cs.utah.edu/ioc/ Es scheint aber kein Äquivalent für gcc/icc zu sein?

+0

Soweit ich weiß, unterstützt kein x86-Prozessor Trapping auf Integer-Überlauf. Viele RISC-CPUs (mindestens Power und Sparc), sowie ältere Mini/Mainframe-CPUs (wie VAX) –

+0

könnte ich Power ausprobieren, keine VAX herumliegen. – Anycorn

Antwort

3

Ok, ich muss vielleicht meine eigene Frage beantworten.

Ich fand gcc hat -ftrapv Option, ein kurzer Test bestätigt, dass zumindest auf meinem System Überlauf gefangen ist. Ich werde detailliertere Informationen veröffentlichen, da ich mehr lerne, da es sehr nützliches Werkzeug scheint.

+0

Siehe auch: http://StackOverflow.com/a/5005792/462335 – nibot

2

Vorzeichenlose Integer-Arithmetik überläuft natürlich nicht.

Bei vorzeichenbehafteten Ganzzahlarithmetik führt Überlauf zu undefiniertem Verhalten; alles könnte passieren. Und Optimierer werden aggressiv bei der Optimierung von Überläufen. Also, am besten ist es, den Überlauf zu vermeiden, anstatt ihn zu erfassen, wenn es passiert. Erwägen Sie die Verwendung des CERT 'Secure Integer Library' (die dort referenzierte URL scheint AWOL/404 zu sein; ich bin mir nicht sicher, was noch passiert ist) oder Googles 'Safe Integer Operation' Bibliothek.

Wenn Sie einen Überlauf auffangen müssen, müssen Sie angeben, an welcher Plattform Sie interessiert sind (O/S einschließlich Version, Compiler einschließlich Version), da die Antwort sehr plattformspezifisch ist.

+1

Ich muss wissen * welche * Operationen zu ersetzen (mit size_t). Ich habe System/Compiler in der Frage angegeben. – Anycorn

2

Wissen Sie genau, auf welcher Linie der Überlauf auftritt? Wenn dies der Fall ist, können Sie möglicherweise das Carry-Flag des Assemblers anzeigen, wenn die betreffende Operation einen Überlauf verursacht hat. Dies ist das Flag, das die CPU zur Berechnung großer Zahlen verwendet. Wenn es auf C-Ebene nicht verfügbar ist, kann es Ihnen helfen, das Problem zu beheben - oder Ihnen zumindest die Möglichkeit zu geben, etwas zu tun.

BTW, gefunden this Link für gcc (-ftrapv), die über eine Ganzzahl-Trap spricht. Könnte sein, wonach Sie suchen.

+0

Nein, das Problem besteht darin, wo der Überlauf passiert – Anycorn

+2

Gibt es eine Chance, einen Schreibvorgang in den Speicherhaltepunkt auf dem Zähler fallen zu lassen, um Ihnen zu helfen? –

+0

Ich glaube nicht. Es gibt mehrere Stellen, an denen "int" anstelle von "size_t" verwendet wird, das manuelle Debuggen ist sehr schwierig. Ich hätte vielleicht eine Lösung gefunden. – Anycorn

0

Sie können mit Inline-Assembler in gcc eine Anweisung verwenden, die einen Überlauf erzeugen könnte und dann testen Sie den Überlauf-Flag, um zu sehen, ob es tatsächlich tut:

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 diesem Fall ist es versucht a hinzuzufügen und b, und wenn es so ist, geht es auf das overflow Etikett. Wenn es keinen Überlauf gibt, geht es weiter, indem Sie den Befehl erneut ausführen und ihn zurückgeben.

Dies führt zu der GCC-Beschränkung, dass ein Inline-Asm-Block nicht sowohl einen Wert ausgeben als auch verzweigen kann - wenn dies nicht der Fall wäre, würden Sie keine zweite Addition benötigen, um das Ergebnis zu erhalten.