「デバッグ」の版間の差分
(→アプリケーションが落ちる場合: 同期) |
(→バグの報告: 同期) |
||
(同じ利用者による、間の3版が非表示) | |||
2行目: | 2行目: | ||
[[Category:システム管理]] |
[[Category:システム管理]] |
||
[[en:Step-by-step debugging guide]] |
[[en:Step-by-step debugging guide]] |
||
+ | [[ru:Debugging]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
{{Related|一般的なトラブルシューティング}} |
{{Related|一般的なトラブルシューティング}} |
||
27行目: | 28行目: | ||
$ gdb ''appname'' core |
$ gdb ''appname'' core |
||
− | bt full |
||
− | |||
− | === gdb の出力を改善する === |
||
− | |||
− | まず '''-g''', '''-O0''', '''-fbuiltin''' フラグを付けて問題のアプリケーションを[[Arch Build System|リコンパイル]]してください。PKGBUILD の options に "!strip" があることを確認して、パッケージをインストールして上述のように gdb を再度実行します。 |
||
− | |||
− | options 行は以下のようになります: |
||
− | |||
− | options=('!strip') |
||
− | |||
− | '''-g''', '''-O0''', '''-fbuiltin''' を有効にするには PKGBUILD の build() 関数の一番始めに以下の二行を記述します: |
||
− | |||
− | export CFLAGS="$CFLAGS -O0 -fbuiltin -g" |
||
− | export CXXFLAGS="$CXXFLAGS -O0 -fbuiltin -g" |
||
− | |||
− | フラグの意味は次のとおりです: '''-g''' はデバッグシンボルを有効にして '''-O0''' は最適化を無効にします ('''-O2''' が最もよく使われる最適化レベルです。[http://funroll-loops.info/ '''-O3''' は過剰] で [https://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there '''-O4''' 以上は '''-O3''' と全く同じ] です)。 |
||
− | |||
− | "core" ファイルが存在する場合、gdb と一緒に使うことでバックトレースを取得できます: |
||
− | |||
− | $ gdb appname core |
||
bt full |
bt full |
||
67行目: | 48行目: | ||
=== Strace === |
=== Strace === |
||
− | {{Pkg|strace}} はアプリケーションが実際に何を |
+ | {{Pkg|strace}} は、アプリケーションが実際に何を行っているかを詳細に調べます。アプリケーションが存在しないファイルを開こうとした場合、strace によってそのファイルを検出できます。 |
− | ''appname'' という名前のプログラムが開こうとし |
+ | ''appname'' という名前のプログラムが開こうとしているファイルを見つけるには: |
$ strace -eopen appname |
$ strace -eopen appname |
||
75行目: | 56行目: | ||
出力を保存して、[[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]]に投稿して URL をメモしてください。 |
出力を保存して、[[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]]に投稿して URL をメモしてください。 |
||
− | {{Tip|strace からの出力を grep したい場合、次のコマンドを試してみてください: {{ic|strace -o /dev/stdout appname <nowiki>|</nowiki> grep ''string''}} |
+ | {{Tip|strace からの出力を grep したい場合、次のコマンドを試してみてください: {{ic|strace -o /dev/stdout appname <nowiki>|</nowiki> grep ''string''}}}} |
=== LD_DEBUG === |
=== LD_DEBUG === |
||
111行目: | 92行目: | ||
== バグの報告 == |
== バグの報告 == |
||
+ | まず、問題のバグがパッケージングのバグであるかどうかを確認します。Arch Linux がこのアプリケーションをパッケージ化する方法が原因でバグが発生した場合は、https://gitlab.archlinux.org/groups/archlinux/packaging/-/issues に報告してください。これには、ライブラリまたは依存関係に関する問題も含まれます (たとえば、それらの 1 つが必要な特定の機能を備えて構築されていない場合) |
||
− | バグは https://bugs.archlinux.org に報告してください。さらにアプリケーションの開発者に直接報告して、Arch Linux のバグレポートにリンクを張っても良いでしょう。 |
||
+ | パッケージの PKGBUILD を検査して ([[Arch build system]] で)、どのようにパッケージ化されているかを確認します。 |
||
+ | 詳細については、[[バグ報告ガイドライン#上流か Arch か?]] を参照してください。 |
||
+ | バグが Arch Linux に関連しておらず、他の場所でも再現できる場合は、上流にのみ報告してください。Arch Linux は上流のバグを魔法のように修正することはできません。Arch バグトラッカーに報告しても役に立たず、バグ管理者の時間を無駄にする傾向があるため、逆効果になる可能性さえあります。 |
||
− | ただし、パッケージングとは無関係の問題がアプリケーション自体に何かあると考えられる場合、上流 (アプリケーションの開発者) に直接バグを報告してください。基本的に、ソフトウェアは開発者からパッケージ作成者・メンテナを介してユーザーに届けられます。上流とはアプリケーションの開発者を示します。 |
||
== 参照 == |
== 参照 == |
2024年3月24日 (日) 21:32時点における最新版
このページはバグレポートに関連する情報を集める方法を主題にしています。"デバッグ"という言葉を使ってはいますが、開発においてプログラムをデバッグする方法を解説するガイドではありません。
目次
コアダンプが利用可能か確認
コアダンプは、プロセスが予期せず終了した時のプロセスのアドレス空間 (メモリ) の内容を記録したファイルです。アプリケーションがデバッグしやすい方法でコンパイルされている場合、どこで上手く動作しなくなったのかを見つけ出すためにコアファイルを使うことができます。
コアダンプの場所はオペレーティングシステムの設定によって異なることがあります。システムでコアダンプの出力が有効化されているかどうか、そしてそれがどこに出力されるかを見つけるには、コアダンプを見てください。
セグメンテーション違反
何が間違っているのか見つけ出すのに使用できるテクニックがいくつかあります。鹿撃ち帽をかぶりましょう。
Gdb
gdb は、アプリケーションをデバッグするための古くからある十分にテストされたアプリケーションです。これを使用してトレースを取得する方法の詳細については、デバッグ/トレースを取得#トレースの取得 を参照してください。 gdb
からの実行中に、セグメンテーション違反が発生するまで待機する必要があります。その後、トレース Pastebin クライアント に URL を含めてバグレポートを投稿して下さい。
"core" ファイルがある場合は、それを gdb と一緒に使用してバックトレースを取得できます:
$ gdb appname core bt full
Valgrind
インライン展開された関数が無く strip されていないバイナリであるならば、大抵の場合 valgrind を使ってそのプログラムを実行することもよいアイデアといえます。valgrind は CPU をエミュレートし、大抵の場合、どこでおかしくなったかを表示したり、gdb に加えてさらなる情報を提供してくれるツールです。
$ valgrind appname
プログラムがクラッシュした場合、これによって多くの有益なデバッグ出力が得られます。さらに詳しい情報を得るには -v
と --leak-check=full
を使うとよいでしょう。
または、次を使います:
$ valgrind --tool=callgrind appname
そして、kcachegrind を使って出力ファイルを実行し、プログラムが使っている関数を視覚的に調査します。プログラムがハングした場合、これによって問題箇所の特定が楽になります。
欠けているファイルやライブラリ
Strace
strace は、アプリケーションが実際に何を行っているかを詳細に調べます。アプリケーションが存在しないファイルを開こうとした場合、strace によってそのファイルを検出できます。
appname という名前のプログラムが開こうとしているファイルを見つけるには:
$ strace -eopen appname
出力を保存して、Pastebin クライアントに投稿して URL をメモしてください。
LD_DEBUG
LD_DEBUG=files
を設定することでアプリケーションがどのようなファイルを必要としているのか確認できます。例えばアプリケーションの名前が appname の場合:
LD_DEBUG=files appname > appname.log 2>&1
出力は appname.log
に書き込まれます。
詳しくは ld-linux(8) を見てください。
Readelf
アプリケーションを実行した時に "no such file or directory" と表示される場合は、次のコマンドを実行してみてください (/usr/bin/appname
は実行可能ファイルの場所に置き換えてください):
$ readelf -a /usr/bin/appname | grep interp
インタプリタ (/lib/ld-linux-x86-64.so.2 など) が存在することを確認してください。必要であれば AUR から ld-lsb をインストールしてください。
C や C++ ではなく Python で書かれている場合
実行ファイルに対して file を使って情報を取得してください ("appname" は実行ファイルに置き換えてください):
$ file /usr/bin/appname
"ELF" と出力される場合、ファイルはバイナリ実行ファイルであり、大抵は C あるいは C++ などで書かれています。"Python script" と出力される場合、Python で書かれたアプリケーションです。
シェルスクリプトの場合、テキストエディタでシェルスクリプトを開いて実際に呼ばれるアプリケーション (ELF ファイル) の名前がないか確認してください (大抵はファイルの末尾に存在します)。シェルスクリプトの中で実行ファイルの名前の前に "gdb" を追加することでデバッグできます。gdb については上のセクションを参照してください。実行ファイルが引数を必要とする場合はコマンドの前に gdb --args
を付けます。
純粋なシェルスクリプトの場合、bash -x script_name
や bash -xv script_name
でデバッグすることが可能です。
Python アプリケーションの場合、クラッシュが発生した行番号やファイルなどが出力されます。Python に精通しているのであれば、修正できるか試してみてバグレポートに修正内容を加えても良いでしょう。
バグの報告
まず、問題のバグがパッケージングのバグであるかどうかを確認します。Arch Linux がこのアプリケーションをパッケージ化する方法が原因でバグが発生した場合は、https://gitlab.archlinux.org/groups/archlinux/packaging/-/issues に報告してください。これには、ライブラリまたは依存関係に関する問題も含まれます (たとえば、それらの 1 つが必要な特定の機能を備えて構築されていない場合) パッケージの PKGBUILD を検査して (Arch build system で)、どのようにパッケージ化されているかを確認します。 詳細については、バグ報告ガイドライン#上流か Arch か? を参照してください。
バグが Arch Linux に関連しておらず、他の場所でも再現できる場合は、上流にのみ報告してください。Arch Linux は上流のバグを魔法のように修正することはできません。Arch バグトラッカーに報告しても役に立たず、バグ管理者の時間を無駄にする傾向があるため、逆効果になる可能性さえあります。