简体   繁体   中英

Program terminates early with valgrind memcheck

I have a C-programm (a lot of numerics and too long to post) which I compile with

gcc -g -O0 program.c -o program

I am trying to debug it using gdb and valgrind memcheck. After some changes on the code I found that

valgrind --tool=memcheck --log-file=output.log ./program

gives

==15866== Memcheck, a memory error detector
==15866== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==15866== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==15866== Command: ./program
==15866== Parent PID: 3362
==15866== 
==15866== Warning: client switching stacks?  SP change: 0xbe88bcd8 --> 0xbe4e1f70
==15866==          to suppress, use: --max-stackframe=3841384 or greater
==15866== Invalid write of size 4
==15866==    at 0x804B7BE: main (program.c:1396)
==15866==  Address 0xbe4e1f74 is on thread 1's stack
==15866== 
==15866== Invalid write of size 4
==15866==    at 0x804B7C2: main (program.c:1396)
==15866==  Address 0xbe4e1f70 is on thread 1's stack
==15866== 
==15866== Invalid read of size 4
==15866==    at 0x4320011: on_exit (on_exit.c:34)
==15866==    by 0x43064D2: (below main) (libc-start.c:226)
==15866==  Address 0xbe4e1f70 is on thread 1's stack
==15866== 
==15866== Invalid read of size 4
==15866==    at 0x4320022: on_exit (on_exit.c:37)
==15866==    by 0x43064D2: (below main) (libc-start.c:226)
==15866==  Address 0xbe4e1f74 is on thread 1's stack

and many more of this kind.

valgrind --tool=memcheck --max-stackframe=3841384 --log-file=output.log ./program

does not print any errors. But what puzzles me is that with both valgrind calls the program exits early (without error messages) and does not do the computation it is supposed to do. The behaviour with same compiler options but run without valgrind is entirely different and looks pretty normal. I suspect a memory error however and want to use valgrind to find it. My question therefore: What kind of error can make a program bahave so differently when executed with valgrind? And if these are memory related errors how can I identify it? Note that it is clear to me that I can "debug by hand" to locate it. But can I maybe run gdb with valgrind to see where it exits.

I originally answered in the comments:

You're probably causing a stack overflow. Are you allocating "large" arrays on the stack? Eg double myArray[10000000]; If so then you should replace such allocations with heap memory using malloc and free .

I wrote a short c-program to intentionally cause a stack overflow like this and check what valgrind reports:

#include <stdio.h>

int main(){

  // imax*sizeof(double) is too big for the stack.
  int imax = 10000000;
  double test[imax];

  // I do a little math to prevent the stack overflow from being optimized away if -O3 is used.
  test[0]=0;
  test[1]=1;
  for(int i=2; i<imax; i++)
    test[i]=0.5*(test[i-1]+test[i-2]);
  printf("%e\n", test[imax-1]);

}

Sure enough, valgrind comes up with:

==83869== Warning: client switching stacks?  SP change: 0x104802930 --> 0xffbb7520
==83869==          to suppress, use: --max-stackframe=80000016 or greater
==83869== Invalid write of size 8
==83869==    at 0x100000ED0: main (in ./a.out)
==83869==  Address 0xffbb7520 is on thread 1's stack

along with tons of other error messages, and eventually quits with a Segmentation fault: 11

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM