views:

182

answers:

5

I am compiling my application with a third party lib and there seems to be some weird behaviour that suggests a stack overflow issue (this is just a guess).

But when I add a print statement after the line that's crashing the application runs fine. If I remove the print statement (a simple cout << "print something" << endl; statement) the application crashes on a

0x00007f48f2027276 in free () from /lib64/libc.so.6

I tried adding the following char array in place of the print statement and this stopped the crash as well, I then attempted to print the contents of the char array:

char ben[8000] = {0};
memset(&ben, 0, sizeof (ben));

for (int y = 0; y < 8000; ++y)
{
if (ben[y] != 0)
  PRINT ("CHAR[%d]=%d", y, ben[y]);
}

to see if anything in the array gets corrupted, but this approach did not work. So I was wondering if there are better ways to detect whether or not this is a stack overflow problem?

I recompiled the application with -fstack-protector-all (both the lib and my code) and this did not turn up anything. I also tried valgrind and it did not give me anything that looked suspicious.

It seems like it's crashing because I'm trying to free an invalid pointer, but I have no idea why the pointer is invalid since it's freeing a local variable (i.e. when it falls out of scope). The pointer is getting corrupted for a reason, but it's a bit like looking for a needle in a haystack. Are there any good techniques to try and converge on this type of problem? Thanks a lot!

+1  A: 

You should give valgrind's Memcheck tool a go. It's a memory debugger that will let you know if you access memory you shouldn't (case of stack overflow, double-free, access to freed pointers, array overflow, ...)

Romain
I tried it in Valgrind and I got nothing with a simple --tool=memcheck and so I was not sure what else valgrind could offer?
bbazso
That's odd. My C/C++ is a bit dusty, bit I think your memset is in cause. `ben` is an array and thus the variable is already a pointer, so you should say `memset(ben,0,sizeof(ben))`. I'm not 100% confident though.
Romain
Porculus
@Porculus: Thanks for the correction. So I was right on the fact my C/C++ is dusty :)
Romain
+3  A: 

Compiling with -fstack-protector-all will have the program let you know if the stack is being smashed.

Ignacio Vazquez-Abrams
Straight-to-the-point.
Romain
Thanks! I tried this, but it did not give anything :(
bbazso
Sounds like it's not a stack overflow problem then.
Ignacio Vazquez-Abrams
A: 

That smells like a pointer corruption problem, not a stack overflow. If the application is large, try inserting return at the top of major functions to limit the amount of code executing.

Once the range of suspect code is constrained, carefully desk check pointer management. Especially be sure that any pointer sent to free() or a destructor hasn't been trashed beforehand.

wallyk
The pointer may well be corrupt, but is there a better way to find out where it may be corrupted? I already tried returning and the application crashes on the free when the variables within a function go out of scope, but I can't see where the pointer gets corrupt.
bbazso
You might get lucky with a tool, but there's no substitute for checking every line of code without the distractions of a debugger or IDE.
wallyk
On the contrary. There are many great substitutes. Stepping through every line _with_ a debugger for instance. Staring blindly at page after page of code quickly numbs your brain.
John
Perhaps it's all mindset then. However you do it, consider every line of code a suspect—until proven innocent.
wallyk
A: 

If memcheck/valgrind don't turn up anything, you can always fire up gdb and look at the assembly.

Some other things to check for are uninitialized variables, these have been known to cause unexpected errors. Also use -Wall if you aren't already, it may turn something up.

It really does sound like a bad pointer problem. See this site for some good tips.

zdav
A: 
tommieb75
really - why -1?. sizeof(ben) = 8000, ben has 8000 slots
pm100
@pm100: It did look that memset went over the array and overstepped the boundary... :)
tommieb75
@tommieb75 : memset can safely write the full size of ben with zeroes.
andreas buykx
@andreas: hmmm...ok...then why did he have the initializer in there char ben[8000] = {0};
tommieb75
You know that's funny....that is a char array, so shouldn't that 0 have been '\x0' and not zero... as in char 0 which is ascii code 30???
tommieb75
@tommieb: char is in integer type, setting it to 0 (note, not `0`) is entirely legitimate
Hasturkun
There's nothing wrong with the line, but it's completely unnecessary, since `={0}` already guarantees that the memory will be filled with zeroes.
Porculus
@Hasturkan: that is a dangerous assumption imho! never rely on that!
tommieb75
@Tommieb75: not so long as you are using a C compiler. (btw, previous comment should have read "setting to 0 (as in `'\0'`, the NUL character) and not `'0'`", I messed up the formatting)
Hasturkun