Ответ 1
Для большой базы кода Coverity
- хороший инструмент. Я не уверен, что обнаружит переполнение целых чисел all
или нет, но стоит попробовать.
Я работаю над большим проектом, который обычно работает очень хорошо, но показывает серьезные проблемы, когда размер входных данных превышает некоторые ограничения.
Эти проблемы (предположительно) возникают только из-за подписанных целых переполнений, таких как:
int a, o;
// Initialize a and o
int x = (a+o) >> 1);
Очевидно, как только сумма переполнений a и o (становится больше 2 ^ 31-1), x уже не является средним для a и o.
Есть ли общий способ найти все эти целые переполнения в запущенной программе?
Я имею в виду такой инструмент, как Valgrind или расширение GDB, которое разбивается на каждую целочисленную арифметическую команду, принимает параметры и сравнивает правильный результат (рассчитанный с использованием более крупного типа данных или арифметики произвольной точности) с фактическим результатом. Если результаты отличаются друг от друга, он должен выдать предупреждение, вызвать разрыв отладки или что-то вроде этого.
Я знаю, как проверить одну арифметическую инструкцию для переполнения (например, проверку знака для дополнений), однако из-за большого количества кода это не жизнеспособное решение для меня, чтобы пройти весь проект и вставить проверочный код везде вручную.
Для большой базы кода Coverity
- хороший инструмент. Я не уверен, что обнаружит переполнение целых чисел all
или нет, но стоит попробовать.
Вам нужно проработать весь код и выяснить, какой предел для входа пользователя и проверить вход. Вам также может потребоваться перезаписать некоторые алгоритмы, чтобы уменьшить проблемы с переполнением.
В качестве примера, который вы даете, не работает для отрицательных значений, вы все равно должны использовать unsigned int
, предоставляя вам дополнительный порядок.
Edit:
gcc имеет параметр -ftrapv
, но этот обычно ничего не делает работает только с -O0
. Если вы используете подход переполнения ловушек, когда они происходят, вам все еще нужно хорошее знание кода, чтобы полностью его протестировать.
Как насчет script, который проходит через код и заменяет все "a + b" на DEBUGADD (a, b) - где вы можете сделать:
#ifdef DEBUG
int addFn(int a, int b) {
long long m;
int n;
m = (long long)a + (long long)b;
n = a + b;
if (m != (long long)n)
printf("PANIC!\n");
return n;
}
#define DEBUGADD(a,b) addFn(a,b)
#else
#define DEBUGADD(a,b) ((a)+(b))
#endif