22

I'm corrupting memory somehow because my program crashes without error at random places.

I'm using valgrind with --leak-check=full, compiling with -O0 -g, and the very first problem it detects is the first line in int main()

cout << "reading file" << endl;

with

==5089== Warning: client switching stacks?  SP change: 0x7ff0004f8 --> 0x7feb7de10
==5089==          to suppress, use: --max-stackframe=4728552 or greater
==5089== Invalid write of size 8
==5089==    at 0x41E107: main (Dgn.cpp:2833)
==5089==  Address 0x7feb7de08 is on thread 1's stack

It goes on with

==5089== Invalid read of size 8
==5089==    at 0x5DE6E10: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==5089==    by 0x67AEDE4: (below main) (libc-start.c:260)
==5089==  Address 0x7feb7de08 is on thread 1's stack
==5089== 
==5089== Invalid write of size 8
==5089==    at 0x5DBF8F2: std::ios_base::ios_base() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==5089==    by 0x5E06BFF: std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18)
==5089==    by 0x41E131: main (Dgn.cpp:2834)
==5089==  Address 0x7feb7e1e8 is on thread 1's stack

which points to

ifstream config_file("file");

Nearly every line has an error.

What causes this?

  • @MattMcNabb Which part would you like me to post? There's a lot. I was giving `spsc_queue`s tons of capacity, like 16k, lol. That's what I reduced. Now, my program doesn't crash. –  Apr 26 '14 at 14:14
  • `0x7ff0004f8 --> 0x7feb7de10` could indicate the stack is being aligned for SSE operations on x86. Is it followed by a `0x7feb7de10 --> 0x7ff0004f8` to readjust the stack pointer? You should probably provide some of the code, like some of `dgn.cpp`. Does it include inline assembly with SSE operations? Does it use a large `alloca`? (Large allocations should occur on the heap). – jww Sep 10 '18 at 04:09

3 Answers3

25

I think I blew my first stack!

From here

Followed by many error messages like "Invalid read/write" containing a note: "Address is on thread 1's stack" then the cause is very simple. You are just allocating too large variables on stack - in my case I had too large array, as local variable, in one of functions.

Reducing sizes fixed the problem.

8

To point out the obvious, you could also do what valgrind suggests, and that is to change the maximum stack frame using --max-stackframe=4728552. You solved your problem directly, but this would also suppress those "Invalid read" errors.

Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
  • I don't see this gcc option. Wouldn't this only affect valgrind? Edit: I do see the CRIS option `mmax-stackframe`. – young_souvlaki Nov 19 '20 at 21:41
  • 1
    @young_souvlaki This is a `valgrind` option, not `gcc`. One thing you can try is setting `--main-stacksize=` and `--max-stackframe=` to large values, perhaps twice as large as the default stack (in Linux, type `ulimit` to display the default stack size). If the problem goes away, then your program is using too much stack. – Mark Lakata Aug 10 '21 at 20:51
5

On Linux, I was valgrinding a program, and was very sure that it was not overrunning its stack. To suppress the client switching stacks? error shown here, I used:

ulimit -s unlimited

...Now valgrind runs as desired!

Alex D
  • 29,755
  • 7
  • 80
  • 126
  • Why would that help? It doesn't do anything about the warning message for me. – Björn Lindqvist May 12 '16 at 14:21
  • The Valgrind error here occurs if Valgrind sees the stack pointer going outside the area which it *thinks* should be used for the stack. This could be for a variety of reasons, but one reason is simply because a program uses a lot of stack space. `ulimit -s` sets the default amount of memory which is allocated for each process' stack. I haven't read the Valgrind source, but I presume it may look at the `ulimit` value when determining how large the stack is "supposed" to be. – Alex D May 14 '16 at 17:56
  • In my case, the program was *not* blowing the stack, it was just using more stack space than Valgrind expected. If your program *is* blowing its stack, or if something else is setting the stack pointer to some bogus value, then this answer will not help you. You need to find out *why* your stack pointer value is unusual. – Alex D May 14 '16 at 17:59
  • I would think that a program that uses to much stack space would segfault? That segfault would happen before valgrind has a chance to warn about it. – Björn Lindqvist May 19 '16 at 12:24
  • Nope. Valgrind *can* catch stack overruns and print a warning message. I suggest you read up on how it works; it's quite interesting. – Alex D May 19 '16 at 12:50