6

私はsnprintfセグメンテーション違反を起こしている。

このようにコアファイルをgdbにロードしたとき:gdb my_executable core; btバックトレースを取得するために、次のようになりました。

Program terminated with signal 11, Segmentation fault.
#0  0x88207fc2 in memcpy () from /usr/lib/libc.so.6
(gdb) bt
#0  0x88207fc2 in memcpy () from /usr/lib/libc.so.6
#1  0x88205eb6 in __sfvwrite () from /usr/lib/libc.so.6
#2  0x881fbc95 in strchr () from /usr/lib/libc.so.6
#3  0xbfbe6c14 in ?? ()
#4  0xbfbe69d8 in ?? ()
#5  0x881ed91e in localeconv () from /usr/lib/libc.so.6
#6  0x881fec05 in __vfprintf () from /usr/lib/libc.so.6
#7  0x881f7d80 in snprintf () from /usr/lib/libc.so.6  
#8  0x08052b64 in my_function (files=0xbfbed710, filename=<value optimized out>) at myfile.c:1102
#9  0x08053bfb in main (argc=4, argv=0xbfbedd90) at myfile.c:225

セグメンテーション違反の場合、このようなスタックが何度も表示されますが、正しく理解されていません。

呼び出しをトレースで見るだけで、何が問題になっているのかわかりますか?

注:これ以上のコードを要求しないでください。私の動機は、コードに関係なく、このようなスタックトレースが何を意味するのかを理解することです。上部の「memcpy」が失敗していることがわかります。このような状況でそれがいつ起こり得るのかを理解したいと思います。

4

3 に答える 3

7

あなたの関数はで何かをしmyfile.c:1102ます。これにより、標準ライブラリがだまされてメモリに不正にアクセスするようになります。オペレーティングシステムは、プログラムに気づき、を叩きますsigsegv

一般的な理由(Stackoverflowで見られるように:)))は次のとおりです。

  • 読み取り専用メモリへの書き込み
  • 初期化されていないポインタの使用
  • 割り当てられたブロックの終わりを超えてメモリにアクセスする

関数の長いリストは、誰がそれをしたかを示しています。それで:

  • my_functionと呼ばれるsnprintf
  • と呼ばれる__vfprintf
  • ..。
于 2011-07-17T19:17:08.163 に答える
2

Valgrindで実行可能ファイルを実行することをお勧めします。すでに解放されたメモリでの作業など、コードに問題がある場合は、追加の呼び出しトレースを出力することがあります。これは通常、クラッシュの理由を理解するのに役立ちます。

于 2011-07-18T07:50:29.437 に答える
1

それは単なる呼び出しの痕跡です。プログラムの最初の関数呼び出しは下部に表示されます。通常は下部に表示され、その後の( mainmain内からの)他の関数の呼び出しが上部に表示されます。新しい呼び出しが別のサブルーチン(関数)を呼び出す場合、それは一番上にスタックされ、プロセスが続行されます。

GDBは、利用可能であることを考慮して、いくつかの有用な情報を出力します。最初の列はスタック位置(上から下)です。2番目の列には呼び出しのアドレスが含まれ、残りの情報には呼び出された関数の名前とその場所が含まれます。これらは大きく異なることに注意してください。シンボルの名前を取得できず?? ()、スタックトレースの#3および#4のように表示される場合があります。ソースが利用可能になると、関数が定義されている行も。のように表示されますat myfile.c:225

于 2011-07-17T19:22:53.670 に答える