My compiler DevCpp shows there is "An access Violation (Segmentation Fault)" in my chessprogram Dabbaba.
But it is caused by some wrong input - something has been corrupted earlier in the calculations.
I have made a little test to see if DevCpp can detect such things like this:
char testIdx;
char test50a[50];
char test50b[50];
testIdx=75; // outside the array
// ok to read from outside the array?
test50a[25]=test50a[testIdx];
// ok to write outside the array?
test50a[testIdx]=test50a[25];
But DevCpp does not complain about this - everything happens within the program.
And I think this is the way how some of my data is corrupted.
I have tried CppCheck - and it can spot the errors in my little test.
But in a complex program the index is not set to a wrong value right before it is used.
I wonder if there exists an compiler option, that makes it generate code so the program always checks the index boundaries?
Or is there only the hard way to find the error....
Finding errors where indexes goes beyond their boudaries
Moderators: hgm, Rebel, chrisw
-
- Posts: 267
- Joined: Thu Jul 07, 2011 10:31 pm
- Location: Denmark
-
- Posts: 5258
- Joined: Mon Feb 27, 2006 4:31 pm
- Location: Atlanta, Georgia
Re: Finding errors where indexes goes beyond their boudaries
Can you not use an assert for some reason?
Best
Dan H.
Best
Dan H.
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Finding errors where indexes goes beyond their boudaries
Code: Select all
char testIdx;
char test50a[50];
char test50b[50];
testIdx=75; // outside the array
// ok to read from outside the array?
test50a[25]=test50a[testIdx];
// ok to write outside the array?
test50a[testIdx]=test50a[25];
2. The compiler can only find such array bounds errors if a variable like "testIdx" is declared as "const", or (maybe) if it is "static" and the compiler is able to see that there is no other code in the same compilation unit that changes its value. In almost all other cases the compiler has no chance to detect this kind of array bounds violation since it has no knowledge about the value of the array index when compiling the array access code.
3. I don't know which compiler you are using with "DevCpp". GCC for instance has -Warray-bounds which "warns about subscripts to arrays that are always out of bounds" (but in real programs this is hard to find). The runtime option "-fbounds-check" seems to be for Java and Fortran only. Compilers like MSVC(++) or Intel C(++) have an option to check for array bounds violation at runtime. Typically you switch it off for an optimized version. Still no chance, though, for a compile time detection, at least in a more complex "real world" case.
4. The "right" solution, as already mentioned, is to use something like the standard assert() macro, as in this silly example:
Code: Select all
#include <assert.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
char test50a[50];
char test50b[50];
inline char getTest50A(unsigned int idx)
{
assert(idx < ARRAY_SIZE(test50a));
return test50a[idx];
}
inline char getTest50B(unsigned int idx)
{
assert(idx < ARRAY_SIZE(test50b));
return test50b[idx];
}
5. There are various tools for static code analysis, some of them also open source.
6. Why are you using DevCpp?
Sven
-
- Posts: 1385
- Joined: Fri Jul 14, 2006 7:56 am
- Location: London, England
- Full name: Jim Ablett
Re: Finding errors where indexes goes beyond their boudaries
He's using the new actively maintained, resurrected DevCpp project >6. Why are you using DevCpp? Wink
http://sourceforge.net/projects/orwelldevcpp/
Jim.
-
- Posts: 2949
- Joined: Mon May 05, 2008 12:16 pm
- Location: Bordeaux (France)
- Full name: Julien Marcel
Re: Finding errors where indexes goes beyond their boudaries
No wonder this compiler produces buggy code if their maintainers can't even get the description right ^^Jim Ablett wrote:He's using the new actively maintained, resurrected DevCpp project >6. Why are you using DevCpp? Wink
http://sourceforge.net/projects/orwelldevcpp/
Jim.
This is just an easy joke and I feel quite ashamed. That's indeed an enormous work they're doing!Description
A maintained verison of Dev-C++ which features an updated MinGW compiler and updated code.
"The only good bug is a dead bug." (Don Dailey)
[Blog: http://tinyurl.com/predateur ] [Facebook: http://tinyurl.com/fbpredateur ] [MacEngines: http://tinyurl.com/macengines ]
[Blog: http://tinyurl.com/predateur ] [Facebook: http://tinyurl.com/fbpredateur ] [MacEngines: http://tinyurl.com/macengines ]
Re: Finding errors where indexes goes beyond their boudaries
You could try running your code with an interpreter. For simple code, I have used the EiC interpreter. It catches array bounds violations at runtime, but the program runs much much slower than the compiled version. Also, EiC doesn't support 64-bit integers. Apparently, EiC is no longer being developed, but I found a copy at http://twkm.freeshell.org. I don't have experience with any other interpreters.
-
- Posts: 267
- Joined: Thu Jul 07, 2011 10:31 pm
- Location: Denmark
Re: Finding errors where indexes goes beyond their boudaries
Sven; I have not expressed myself clearly.
Of course the error should be detected at runtime.
The compiler should generate the code to do that with a switch, so it can be turned off in the final compile.
And from what you write it is possible with some compilers.
I do not know about assert(), but it seems to be a possibility?!
But I have +50 arrays in dabbaba to change...
I am only an amateur in C programming - dabbaba is the only program I have written in C.
And all the 12.000 lines of code is in one single file...
My proffession is being a mainframe-programmer, though (cobol, cics, db2, tso...).
Since 2008 I have used the Pelle compiler.
But I think it may produce wrong code, and I have never learnt how to debug with it.
I would also like to try performance profiling.
So I changed to DevCpp a week ago.
And it found the access violation I was not aware of - dabbaba seems to run ok with it...
Could an interpreter detect this?!
DevCpp found the "An access Violation (Segmentation Fault)" here:
void change_to_pili( char *pili, char *sqfr, char *sqto)
{ char *p, p=pili;
loop: if (*p!=*sqfr) {++p; goto loop;}
*p=*sqto; <--------------------------------------------------------------------
}
But the real error is, that pili does not contain the value *sqfr.
I assume it has been overwritten by an index going beyond its boundaries.
It may take some time for the interpreter.
The access violation happens after 500.000 nodes - 5 seconds.
Thanks for your helpful posts!
Of course the error should be detected at runtime.
The compiler should generate the code to do that with a switch, so it can be turned off in the final compile.
And from what you write it is possible with some compilers.
I do not know about assert(), but it seems to be a possibility?!
But I have +50 arrays in dabbaba to change...
I am only an amateur in C programming - dabbaba is the only program I have written in C.
And all the 12.000 lines of code is in one single file...
My proffession is being a mainframe-programmer, though (cobol, cics, db2, tso...).
Since 2008 I have used the Pelle compiler.
But I think it may produce wrong code, and I have never learnt how to debug with it.
I would also like to try performance profiling.
So I changed to DevCpp a week ago.
And it found the access violation I was not aware of - dabbaba seems to run ok with it...
Could an interpreter detect this?!
DevCpp found the "An access Violation (Segmentation Fault)" here:
void change_to_pili( char *pili, char *sqfr, char *sqto)
{ char *p, p=pili;
loop: if (*p!=*sqfr) {++p; goto loop;}
*p=*sqto; <--------------------------------------------------------------------
}
But the real error is, that pili does not contain the value *sqfr.
I assume it has been overwritten by an index going beyond its boundaries.
It may take some time for the interpreter.
The access violation happens after 500.000 nodes - 5 seconds.
Thanks for your helpful posts!
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Finding errors where indexes goes beyond their boudaries
You could write it like this to track the error:JBNielsen wrote:But the real error is, that pili does not contain the value *sqfr.Code: Select all
void change_to_pili( char *pili, char *sqfr, char *sqto) { char *p, p=pili; loop: if (*p!=*sqfr) {++p; goto loop;} *p=*sqto; <-------------------------------------------------------------------- }
I assume it has been overwritten by an index going beyond its boundaries.
Code: Select all
#include <assert.h>
// release version
void change_to_pili(char *pili, char sqfr, char sqto)
{
assert(pili != 0);
char *p = pili;
while (*p != sqfr) {
++p;
}
*p = sqto;
}
// debug version with different signature
bool change_to_pili_safe(char *pili, char sqfr, char sqto, size_t maxlen)
{
assert(pili != 0);
char *p = pili;
size_t len = 0;
while (*p != sqfr && len <= maxlen) {
++p;
++len;
}
if (*p == sqfr) {
*p = sqto;
return true; // OK
} else {
assert(len > maxlen); // just for clarification
return false; // maxlen exceeded but 'sqfr' not found
}
}
Now the real thing: to spot your error I would use the second version of the function for debugging, change the calling code by adding a reasonable value for the additional size parameter (usually the max size of the array), and set a debugger break point on the "return false;" line to see under which conditions you get the failure. It will stop when "sqfr" is not found.
EDIT: this may point you to a situation where the corruption has already occurred. What you actually need is where the corruption happens. But you may get some indication. Setting memory breakpoints might help, too, if your IDE supports them.
Sven
-
- Posts: 267
- Joined: Thu Jul 07, 2011 10:31 pm
- Location: Denmark
Re: Finding errors where indexes goes beyond their boudaries
Hi Sven
Thanks for your helpful advices. I will be more aware of asserts in the future.
After many hours of debugging I have found the error in something I have restructured recently.
An array was defined too small, and then the index exceeded the boundary.
PS. If you install DevCpp and intend to use gcc, be sure to get at more recent version of gcc.
I had another strange error, and Jim Ablett helped me go get the Ruben-Vb Gcc 4.7.0 version.
He wrote:
"Replace your Gcc installation (4.6.2) in devcpp with this one(4.7.0) (just overwrite it - it's a direct replacement) >
http://sourceforge.net/projects/mingw-w ... z/download
This is what I use and it compiles correctly."
Thanks for your helpful advices. I will be more aware of asserts in the future.
After many hours of debugging I have found the error in something I have restructured recently.
An array was defined too small, and then the index exceeded the boundary.
PS. If you install DevCpp and intend to use gcc, be sure to get at more recent version of gcc.
I had another strange error, and Jim Ablett helped me go get the Ruben-Vb Gcc 4.7.0 version.
He wrote:
"Replace your Gcc installation (4.6.2) in devcpp with this one(4.7.0) (just overwrite it - it's a direct replacement) >
http://sourceforge.net/projects/mingw-w ... z/download
This is what I use and it compiles correctly."