How to find (all) integer overflows in a C program?
I am working on a large project that generally works just fine, but shows serious issues once the input data size exceeds some limitations.
These issues are (suspected) only due to signed integer overflows like these:
int a, o;
// Initialize a and o
int x = (a+o) >> 1);
Obviously, once the sum of a and o overflows (gets larger than 2^31-1), x is no longer the mean of a and o.
Is there a generic way to find all of these integer overflows in a running program?
I am thinking of a tool like Valgrind or a GDB extension that breaks at every integer arithmetic instruction, takes the parameters and compares the correct result (calculated with a larger-sized datatype or arbitrary-precision arithmetic) with the actual result. If the results differ, it should output a warning, trigger a debug break or something like this.
I know, how to check a single arithmetic instruction for overflows (e.g. checking the sign for additions), however due to the vast amount of code, it is not 开发者_如何学JAVAviable solution for me to go through the whole project and insert checking code everywhere by hand.
For large code base, Coverity
is a good tool. I am not sure it will detect all
integer overflows or not, but its worth giving a try.
You have to work through all the code and work out what the limit on the user-input is and validate the input. You may also need to re-write some algorithms to reduce overflow issues.
As the example you give doesn't work for negative values, you should be using an unsigned int
anyway, giving you an extra order of magnitude already.
Edit:
gcc has the -ftrapv
option, but this usually doesn't actually do anything only works with -O0
. If you are taking the approach of trapping overflows when they happen, you still need good knowledge of the code in order to test it fully.
How about a script which goes through the code and replaces all "a+b" with DEBUGADD(a,b) - where you can do:
#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
精彩评论