2012-04-17 11 views
7

Pracuję z dużą biblioteką C, w której niektóre indeksy tablicowe są obliczane przy użyciu int. Potrzebuję znaleźć sposób przechwytywania przepełnienia liczby całkowitej w czasie wykonywania w taki sposób, aby zawęzić do problematycznych linii kodu. Libc ręczne stany:Wykrywanie przepełnienia liczby całkowitej

FPE_INTOVF_TRAP Integer overflow (niemożliwe w programie C, chyba że włączysz przepełnienie odłowu w sposób sprzętowy specyficzny).

Jednak opcja gcc -ffpe-trap sugeruje, że odnoszą się one tylko do numerów FP?
Więc jak mogę włączyć pułapkę przepełnienia typu integer? Mój system to Xeon/Core2, gcc-4.x, Linux 2.6

Przejrzałem podobne pytania, ale wszystkie one chcą zmodyfikować kod. Muszę jednak wiedzieć, który kod jest problematyczny.
Jeśli Xeons nie może przechwycić przepełnień, które procesory mogą? Mam również dostęp do maszyn innych niż emt64.

Znalazłem narzędzie przeznaczone do llvm tymczasem: http://embed.cs.utah.edu/ioc/ Nie wydaje się jednak być odpowiednikiem dla gcc/icc?

+0

O ile mi wiadomo, żaden procesor x86 nie obsługuje zalewkowania na przepełnieniu całkowitym. Wiele procesorów RISC (przynajmniej power i sparc), a także starsze procesory mini/mainframe (takie jak VAX). –

+0

Mogę wypróbować Power, bez układania VAX. – Anycorn

Odpowiedz

3

Ok, może będę musiał odpowiedzieć na moje własne pytanie.

Znalazłem gcc ma opcję -ftrapv, szybki test potwierdza, że ​​przynajmniej na moim przepełnieniu systemu jest uwięziony. Będę publikować bardziej szczegółowe informacje, ponieważ uczę się więcej, ponieważ wydaje się bardzo przydatnym narzędziem.

+0

Zobacz też: http://stackoverflow.com/a/5005792/462335 – nibot

2

Niepodparta arytmetyczna liczba całkowita nie ulega oczywiście przepełnieniu.

Z arytmetyczną liczbą całkowitą ze znakiem, przepełnienie prowadzi do niezdefiniowanego zachowania; wszystko może się zdarzyć. Optymalizatory stają się coraz bardziej agresywne w kwestii optymalizacji rzeczy, które się przelewają. Najlepszym wyjściem jest uniknięcie przelewu, a nie pułapkowanie go, kiedy to się stanie. Rozważ skorzystanie z CERT 'Secure Integer Library' (adres URL, do którego odesłano, wydaje się, że zniknął AWOL/404, nie jestem pewien, co się stało) lub biblioteki Google 'Safe Integer Operation'.

Jeśli musisz przechwycić przepełnienie, będziesz musiał określić platformę, która Cię interesuje (O/S, w tym wersja, kompilator łącznie z wersją), ponieważ odpowiedź będzie bardzo specyficzna dla platformy.

+1

Muszę wiedzieć * jakie * operacje do zastąpienia (z size_t). W pytaniu podałem system/kompilator. – Anycorn

2

Czy wiesz dokładnie, na której linii pojawia się przelew? Jeśli tak, możesz spojrzeć na flagę Carry asemblera, jeśli dana operacja spowodowała przepełnienie. Jest to flaga używana przez CPU do obliczania dużych liczb i, choć nie jest dostępna na poziomie C, może pomóc w debugowaniu problemu - lub przynajmniej dać ci szansę na zrobienie czegoś.

BTW, znaleziono this link do gcc (-ftrapv), który mówi o pułapce całkowitej. Może być tym, czego szukasz.

+0

nie, problemem jest znalezienie miejsca, w którym nastąpi przepełnienie. – Anycorn

+2

Czy istnieje jakakolwiek szansa na zrzut punktu zapisu do pamięci na liczniku, aby pomóc? –

+0

Nie sądzę. Istnieje wiele miejsc, w których 'int' są używane zamiast' size_t', ręczne debugowanie jest bardzo trudne. Mogłem jednak znaleźć rozwiązanie. – Anycorn

0

Można użyć inline assemblera w gcc użycie instrukcji, które mogą wygenerować przepełnienia, a następnie przetestować flagę przepełnienia, aby sprawdzić, czy to rzeczywiście działa:

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; 
} 

W tym przypadku, próbuje dodać a i b, a jeśli tak, przechodzi do etykiety overflow. Jeśli nie ma przepełnienia, kontynuuje, dodając ponownie i zwracając.

To prowadzi do ograniczenia GCC, że wbudowany blok asm nie może zarówno wyprowadzać wartości, jak i odgałęzienia - gdyby nie to, nie potrzebowałby drugiego dodania, aby faktycznie uzyskać wynik.

Powiązane problemy