Linuxプログラムにおけるセグメンテーションフォールト(コアダンプ)の一般的な解決方法
以前、v4l-testをコンパイルして実行すると、Segmentation fault (core dumped)というセグメントエラー(コアダンプ)が発生し、コードが異なるため、エラーの原因が異なり、結果として解決方法が異なるため、いろいろ検索したが良い解決方法は見つからず、ようやくあるブログでこの種の問題の一般解を見つけた、そのブログアドレス ブログアドレスは以下の通りである。
https://www.cnblogs.com/kuliuheng/p/11698378.html
1 原因
セグメンテーションフォールト(コアダンプ)は、ほとんどの場合、不適切なメモリ操作によって発生します。Nullポインタ、ワイルドポインタ、読み書き操作、配列への境界外アクセス、定数の破損、など。この問題を回避する良い方法は、各ポインタを宣言した後にNULLに初期化することです。この問題を取り除く最良の方法は、デバッグすることです。
より詳細な原因
(1)領域外メモリアクセス
a) 誤った添え字による境界外配列アクセス
b) 文字列を検索する際、文字列が終了したかどうかを文字列のターミネータに依存しているが、文字列がターミネータを適切に使用していない
c) strcpy, strcat, sprintf, strcmp, strcasecmp などの文字列操作関数を使用して、対象の文字列を読み書きをはじく。strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmpなどの関数は、境界外への読み書きを防ぐために使用する必要があります。
(2) マルチスレッドプログラムでは、スレッドセーフでない関数を使用する。
(3) 複数のスレッドが読み書きするデータは、ロックで保護されない。
複数のスレッドから同時にアクセスされるグローバルデータについては、ロック保護に注意を払わないと、簡単にコアダンプが発生することになる
(4) 不正なポインタ
a) ヌルポインタの使用
b) ポインタの変換をやみくもに使用する。メモリのセクションへのポインタは、そのメモリがもともと構造体や型、またはそのような構造体や型の配列として割り当てられたことが確かでない限り、構造体や型へのポインタに変換してはいけませんが、構造体や型にコピーしてからアクセスすべきなのは確かです。このメモリの開始アドレスがこの構造体や型にアライメントされていないと、アクセス時にバスエラーでコアダンプしやすくなるからです。
(5)スタックオーバーフロー
大きなローカル変数は使わないでください(ローカル変数はスタック上に確保されるため)。スタックオーバーフローを起こしやすく、システムのスタックやヒープ構造が壊れて、不可解なエラーにつながる可能性があります。
2 GDBを使用してコアファイルを表示する
1、デフォルトでコンパイルされたプログラムでは、Segmentation faultが発生してもcore crashファイルが生成されないので、gcc/g++のコンパイル時に-gオプションを追加してください。
例: cc -O2 -Wall -Wextra -g -c -o test_VIDIOC_ENUMSTD.o test_VIDIOC_ENUMSTD.c
2、それでもコアファイルが生成されない場合、システムがコアファイルのサイズを0に設定している可能性があります、これはulimit -a queryで確認できます。実行する ulimit -c 無制限 コマンドを実行すると、コアファイルのサイズが無制限になります。再度プログラムを実行すると、同じレベルのディレクトリにコアファイルが表示されるはずです
3,使用する gdb . /run ファイル core でエラー行の位置を確認し、gdbのコアデバッギングモードに入ることができます。
セグメンテーションフォールトとコード関数呼び出しの場所をトレースします。
(gdb) bt
(gdb)Quitで終了します。
4、分析、それは私が問題のv4l2_test.c行410にいることは明らかであり、さらにcunitコールスタックで、我々は行番号を見ることができない、それができるようにデバッグ情報を持っているようだ、現在gdb動的ぶら下げシンボルファイルにされないので、最初にかかわらず、入力のヘルプと他のコマンドは、次を学ぶためにデバッグ、終了するには、qを入力してください。
CU_register_suites関数を呼び出していますが、関数自体は間違っていないはずで、スイートから渡される引数に問題があるのかもしれません、それは以下のように引数で構築されるコードです。
CU_SuiteInfoの配列なので、ビルドするのに適した型ではない気がしますし、あとは定義されている場所にもよりますね。
ご覧の通り、TestDB.hの712で、以下のようなコードになっています。
コードを見てわかるように、構造体は6つのメンバーを持っていますが、以前のスイートは内部に4つのパラメータを持っていたので、定義に従って追加を修正するだけです。
変更後に再コンパイルすれば、実行されます。
関連
-
すでに#.objで定義されているものを修正する。
-
エラー LNK2005: _main は first.obj で既に定義されています。
-
Cプログラムの単純なエラー [エラー] ldは1終了ステータスを返した
-
デバッグエラー MSB3073: :VCEnd がコード Solution で終了した
-
複数形使用時:'**'の前にイニシャライザを置く解決策を期待。
-
エラーが発生しました。#79: 型指定子が必要です
-
エラーが発生しました。#852: 式は完全なオブジェクト型へのポインタでなければならない
-
free(): 次のサイズが無効 (fast): 0x0000000000aa4430 問題あり
-
c 言語エラー警告: 複数文字文字定数
-
C C++プログラムのランタイムプログラムは、書き込みエラーのためにDebug/1.exeを開くことができません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
undefinedMakefile:***セパレータがありません。
-
struct と typedef struct を徹底的に理解する
-
libstdc++-6.dll が見つからないため、コードの実行を継続できません。プログラムを再インストールすると、この問題が解決する場合があります。
-
Cコンパイル警告:代入がキャストなしで整数からポインタを作成する
-
変数、配列、構造体におけるC言語の代入
-
Cエラー:構造体でも組合でもないものにメンバ 'xxx' を要求しています。
-
0xffffffとは何ですか?
-
警告: 非推奨の文字列定数から 'char *' への変換[-Write-strings] 解決法