web-dev-qa-db-ja.com

Valgrindは、ほぼすべてに対してエラーを出します(警告:クライアントスイッチングスタック?)

プログラムがランダムな場所でエラーなしにクラッシュするため、メモリが破損しています。

Valgrindを_--leak-check=full_で使用し、_-O0 -g_でコンパイルしています。最初に検出される問題は、int main()の最初の行です。

_cout << "reading file" << endl;
_

_==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
_

それは続く

_==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
_

これは

_ifstream config_file("file");
_

ほぼすべての行にエラーがあります。

これの原因は何ですか?

20
user1382306

私は最初のスタックを吹き飛ばしたと思います!

から ここ

「アドレスはスレッド1のスタックにあります」というメモを含む「無効な読み取り/書き込み」などの多くのエラーメッセージが続き、原因は非常に単純です。スタックに大きすぎる変数を割り当てているだけです。私の場合、関数の1つにローカル変数として大きすぎる配列がありました。

サイズを小さくすると問題が解決しました。

19
user1382306

明らかなことを指摘するために、valgrindが提案することを行うこともできます。それは、--max-stackframe=4728552を使用して最大スタックフレームを変更することです。問題を直接解決しましたが、これにより、これらの「無効な読み取り」エラーも抑制されます。

5
Mark Lakata

Linuxでは、プログラムをvalgrindingしていて、スタックをオーバーランしていないことを確信していました。ここに示されているclient switching stacks?エラーを抑制するために、私は以下を使用しました。

ulimit -s unlimited

...これでvalgrindが希望どおりに実行されます!

5
Alex D