10

今日、最初のセグメンテーション違反に遭遇しました(初心者プログラマー)。セグメンテーション違反が何であるかを読んだ後(このサイトのすべての役立つ情報とウィキペディアの長い説明に感謝します)、私は自分の障害が発生している場所を見つけるための最も簡単な方法を見つけようとしています。これはCで記述されており、エラーは* NIXベースのシステムで発生しています(どちらが正直かわかりません... 99%はLinuxであると確信しています)。コンパイルしているファイルが非常に長いため、コードを正確に投稿できません。私はあなたがすべて観察したいくつかのベストプラクティスを望んでいました。ご協力いただきありがとうございます。

PSエラーは、NULLポインターの逆参照、または初期化されていないポインターの使用が原因であると考えています。しかし、私は間違いなく間違っている可能性があります。

4

4 に答える 4

19

セグメンテーション違反が発生した場所をより正確に把握するためのツールなど、gdbまたは該当しない場合はデバッガーを使用します。strace

を使用する場合はgcc、必ず-gswitchを使用してコンパイルし、デバッグ情報を含めてください。次に、gdbsegfaultが発生するソースコード内の正確な場所が表示されます。

たとえば、この明らかなsegfaultyプログラムがある場合:

new.c

#include <stdio.h>

int main()
{
        int *i = 0x478734;
        printf("%d", *i);
}

でコンパイルしてから、次のコマンドでセッションをgcc -g new.c -o new実行します。gdbgdb new

runインタラクティブセッションでコマンドを発行し、それ以外は明確です。

(gdb) run
Starting program: /home/Tibor/so/new
[New Thread 9596.0x16a0]
[New Thread 9596.0x1de4]

Program received signal SIGSEGV, Segmentation fault.
0x0040118a in main () at new.c:6
6               printf("%d", *i);
(gdb)

DasMoehとnetcoderが指摘しているように、セグメンテーション違反が発生した場合はbacktrace、対話型セッションでコマンドを使用して、コールスタックを出力できます。これは、セグメンテーション違反の場所をさらに特定するのに役立ちます。

于 2012-07-11T18:55:57.263 に答える
5

最も簡単な方法はを使用することvalgrindです。無効なアクセスが発生した場所(およびクラッシュを引き起こさなかったがまだ無効であったその他の問題)を特定します。もちろん、実際の問題はコード内の別の場所(例:無効なポインター)にある可能性があるため、次のステップはソースを確認し、それでも混乱する場合はデバッガーを使用することです。

于 2012-07-11T19:07:13.057 に答える
2

Tiborsの答えは+1。

大規模なプログラムの場合、または追加のライブラリを使用する場合は、gdbのバックトレースを確認することも役立つ場合があります:ftp://ftp.gnu.org/pub/old-gnu/Manuals/gdb/html_node/gdb_42.html

于 2012-07-11T19:53:06.277 に答える
0

gccを使用して作成したセグメンテーション違反を修正したばかりなので、ここを通過する人々のためにこの投稿を再開します。

フラグ-fsanitize=addressの使用を検討する必要があります。これにより、セグメンテーション違反を高精度で強調表示できる場合があります。

于 2020-03-29T16:30:53.010 に答える