「デバッグ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
 
(5人の利用者による、間の19版が非表示)
1行目: 1行目:
 
[[Category:開発]]
 
[[Category:開発]]
  +
[[Category:システム管理]]
 
[[en:Step-by-step debugging guide]]
 
[[en:Step-by-step debugging guide]]
  +
[[ru:Debugging]]
 
{{Related articles start}}
 
{{Related articles start}}
 
{{Related|一般的なトラブルシューティング}}
 
{{Related|一般的なトラブルシューティング}}
9行目: 11行目:
 
このページはバグレポートに関連する情報を集める方法を主題にしています。"デバッグ"という言葉を使ってはいますが、開発においてプログラムをデバッグする方法を解説するガイドではありません。
 
このページはバグレポートに関連する情報を集める方法を主題にしています。"デバッグ"という言葉を使ってはいますが、開発においてプログラムをデバッグする方法を解説するガイドではありません。
   
== アプリケーションが落ちる場合 ==
+
== 利用可能か確認 ==
   
  +
コアダンプは、プロセスが予期せず終了した時のプロセスのアドレス空間 (メモリ) の内容を記録したファイルです。アプリケーションがデバッグしやすい方法でコンパイルされている場合、どこで上手く動作しなくなったのかを見つけ出すために''コア''ファイルを使うことができます。
=== コマンドラインから実行 ===
 
   
  +
コアダンプの場所はオペレーティングシステムの設定によって異なることがあります。システムでコアダンプの出力が有効化されているかどうか、そしてそれがどこに出力されるかを見つけるには、[[コアダンプ]]を見てください。
アプリケーションが突然クラッシュしたときは、[[アプリケーション一覧#ターミナルエミュレータ|ターミナルエミュレータ]]からアプリケーションを実行してみてください。小文字でアプリケーションの名前を入力します。パッケージの名前しか分からず、アプリケーションの実行可能ファイルの名前を知らない場合、以下のコマンドを実行することで実行可能ファイルの名前を確認できます。''packagename'' はパッケージの名前に置き換えてください:
 
 
for f in `pacman -Ql ''packagename'' | grep "/bin/" | cut -d" " -f2`; do file $f 2>/dev/null | grep -q executable && basename $f; done
 
 
=== アプリケーションがセグメンテーション違反を起こしてないか確認 ===
 
 
"segfault" という単語または "segmentation fault" というフレーズが表示された場合は、"core" という名前のファイルが存在しないか確認してください。
 
 
ls core
 
 
存在する場合、アプリケーションはセグメンテーション違反を起こしています。アプリケーションがデバッグできるようにコンパイルされている場合、"core" ファイルを使ってどこがおかしいのか調べることができます。ときどき、core ファイルがカレントディレクトリではなく、アプリケーションによって開かれたディレクトリのどれかに残ることもあります。
 
 
"core" ファイルが見つけられない場合、おそらくコアダンプがデフォルトで無効にされています。問題のプログラムを実行する前に {{ic|$ ulimit -c unlimited}} を使ってください。{{ic|.bashrc}} に追加すれば後でデバッグするときに役立ちます。
 
   
 
== セグメンテーション違反 ==
 
== セグメンテーション違反 ==
33行目: 23行目:
 
=== Gdb ===
 
=== Gdb ===
   
  +
{{Pkg|gdb}} は、アプリケーションをデバッグするための古くからある十分にテストされたアプリケーションです。これを使用してトレースを取得する方法の詳細については、[[デバッグ/トレースを取得#トレースの取得]] を参照してください。 {{ic|gdb}} からの実行中に、セグメンテーション違反が発生するまで待機する必要があります。その後、トレース [[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]] に URL を含めてバグレポートを投稿して下さい。
{{Pkg|gdb}} は古典的で十分テストされたデバッグ用アプリケーションです。''appname'' をデバッグしたい実行可能ファイルの名前に置き換えてください:
 
 
$ gdb appname
 
r
 
(wait for segfault)
 
bt full
 
 
出力を [[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]]に投稿して URL をバグレポートに含めてください。
 
 
=== 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''' は過剰] で [http://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there '''-O4''' 以上は '''-O3''' と全く同じ] です)。
 
   
"core" ファイルが存在する場合、gdb と一緒に使うことでバックトレースを取得できます:
+
"core" ファイルがる場合それを gdb と一緒に使用してバックトレースを取得できます:
   
$ gdb appname core
+
$ gdb ''appname'' core
 
bt full
 
bt full
   
 
=== Valgrind ===
 
=== Valgrind ===
   
  +
インライン展開された関数が無く strip されていないバイナリであるならば、大抵の場合 {{Pkg|valgrind}} を使ってそのプログラムを実行することもよいアイデアといえます。''valgrind'' は CPU をエミュレートし、大抵の場合、どこでおかしくなったかを表示したり、gdb に加えてさらなる情報を提供してくれるツールです。
Assuming you have an unstripped binary without inlined functions, it's usually a good idea to also run that program through {{Pkg|valgrind}}. ''valgrind'' is a tool that emulates a CPU and usually shows where things go wrong or provide additional info in addition to gdb.
 
   
 
$ valgrind appname
 
$ valgrind appname
   
it will provide a lot of helpful debug output if there is a crash. Consider {{ic|-v}} and {{ic|<nowiki>--leak-check=full</nowiki>}} to get even more info.
+
プログラムがクラッシュした場合、これによって多くの有益なデバッグ出力が得られます。さらに詳しい情報を得るには {{ic|-v}} {{ic|<nowiki>--leak-check=full</nowiki>}} を使うとよいでしょう。
   
  +
または、次を使います:
Alternatively, use:
 
   
 
$ valgrind --tool=callgrind appname
 
$ valgrind --tool=callgrind appname
   
  +
そして、{{Pkg|kcachegrind}} を使って出力ファイルを実行し、プログラムが使っている関数を視覚的に調査します。プログラムがハングした場合、これによって問題箇所の特定が楽になります。
and run the output through {{Pkg|kdesdk-kcachegrind}} to graphically explore the functions the program uses. If a program hangs, this makes it easier to pinpoint the location of the error.
 
   
 
== 欠けているファイルやライブラリ ==
 
== 欠けているファイルやライブラリ ==
80行目: 48行目:
 
=== Strace ===
 
=== Strace ===
   
{{Pkg|strace}} はアプリケーションが実際に何をているかを細かく調査します。アプリケーションが存在しないファイルを開こうとしていた場合、strace そのこと発見できます。
+
{{Pkg|strace}} はアプリケーションが実際に何を行っているかを調ます。アプリケーションが存在しないファイルを開こうとした場合、strace によってそのファイル検出できます。
   
''appname'' という名前のプログラムが開こうとしファイルを調査するには:
+
''appname'' という名前のプログラムが開こうとしているファイルを見つけるには:
   
 
$ strace -eopen appname
 
$ strace -eopen appname
88行目: 56行目:
 
出力を保存して、[[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]]に投稿して URL をメモしてください。
 
出力を保存して、[[アプリケーション一覧#Pastebin_クライアント|Pastebin クライアント]]に投稿して URL をメモしてください。
   
  +
{{Tip|strace からの出力を grep したい場合、次のコマンドを試してみてください: {{ic|strace -o /dev/stdout appname <nowiki>|</nowiki> grep ''string''}}}}
{{Tip|If you wish to grep the output from strace, you can try:
 
{{ic|strace -o /dev/stdout appname <nowiki>|</nowiki> grep ''string''}}
 
}}
 
   
 
=== LD_DEBUG ===
 
=== LD_DEBUG ===
   
Setting {{ic|<nowiki>LD_DEBUG=files</nowiki>}} gives another overview of what files an application is looking for. For an application named ''appname'':
+
{{ic|<nowiki>LD_DEBUG=files</nowiki>}} を設定することでアプリケーションがどのようなファイルを必要としているのか確認できます。例えばアプリケーションの名前が ''appname'' の場合:
   
 
LD_DEBUG=files appname > appname.log 2>&1
 
LD_DEBUG=files appname > appname.log 2>&1
   
The output will end up in {{ic|appname.log}}.
+
出力は {{ic|appname.log}} に書き込まれます。
   
詳しくは {{ic|man ld-linux}} を見てください。
+
詳しくは {{man|8|ld-linux}} を見てください。
   
 
=== Readelf ===
 
=== Readelf ===
   
アプリケーションを実行した時に "no such file or directory" 表示される場合は、次のコマンドを実行してみてください ({{ic|/usr/bin/appname}} は実行可能ファイルの場所に置き換えてください):
+
アプリケーションを実行した時に "no such file or directory" 表示される場合は、次のコマンドを実行してみてください ({{ic|/usr/bin/appname}} は実行可能ファイルの場所に置き換えてください):
   
 
$ readelf -a /usr/bin/appname | grep interp
 
$ readelf -a /usr/bin/appname | grep interp
   
  +
インタプリタ (/lib/ld-linux-x86-64.so.2 など) が存在することを確認してください。必要であれば [[AUR]] から {{Pkg|ld-lsb}} をインストールしてください。
Make sure the interpreter in question (like /lib/ld-linux-x86-64.so.2) actually exists. Install {{AUR|ld-lsb}} from the [[AUR]] if need be.
 
   
 
== C や C++ ではなく Python で書かれている場合 ==
 
== C や C++ ではなく Python で書かれている場合 ==
   
  +
実行ファイルに対して {{Pkg|file}} を使って情報を取得してください ("appname" は実行ファイルに置き換えてください):
Use {{Pkg|file}} on the executable to get more information (replace "appname" with your executable):
 
   
 
$ file /usr/bin/''appname''
 
$ file /usr/bin/''appname''
   
  +
"ELF" と出力される場合、ファイルはバイナリ実行ファイルであり、大抵は C あるいは C++ などで書かれています。"Python script" と出力される場合、Python で書かれたアプリケーションです。
If it says "ELF" it's a binary exectuable and is usually written in C or C++. If it says "Python script" you know you're dealing with an application written in Python.
 
   
  +
シェルスクリプトの場合、テキストエディタでシェルスクリプトを開いて実際に呼ばれるアプリケーション (ELF ファイル) の名前がないか確認してください (大抵はファイルの末尾に存在します)。シェルスクリプトの中で実行ファイルの名前の前に "gdb" を追加することでデバッグできます。gdb については上のセクションを参照してください。実行ファイルが引数を必要とする場合はコマンドの前に {{ic|gdb --args}} を付けます。
If it's a shell script, open up the shell script in a text editor and see (usually at the bottom of the file) if you can find the name of the real application (ELF file). You can then temporarily put "gdb" right in the shellscript, before the name of the executable, for debugging purposes. See the sections about gdb further up. Prefix the command with {{ic|gdb --args}} if the executable in question needs arguments as well.
 
   
For pure shell scripts, you can also use {{ic|bash -x ''script_name''}} or {{ic|bash -xv ''script_name''}}.
+
純粋なシェルスクリプトの場合、{{ic|bash -x ''script_name''}} {{ic|bash -xv ''script_name''}} でデバッグすることが可能です。
   
  +
Python アプリケーションの場合、クラッシュが発生した行番号やファイルなどが出力されます。Python に精通しているのであれば、修正できるか試してみてバグレポートに修正内容を加えても良いでしょう。
For Python applications, the output will often say which file and line number the crash occured at. If you're proficient with Python, you can try to fix this and include the fix in the bug report.
 
   
 
== バグの報告 ==
 
== バグの報告 ==
   
  +
まず、問題のバグがパッケージングのバグであるかどうかを確認します。Arch Linux がこのアプリケーションをパッケージ化する方法が原因でバグが発生した場合は、https://gitlab.archlinux.org/groups/archlinux/packaging/-/issues に報告してください。これには、ライブラリまたは依存関係に関する問題も含まれます (たとえば、それらの 1 つが必要な特定の機能を備えて構築されていない場合)
Please report a bug at https://bugs.archlinux.org and possibly also directly to the developers of the application in question, then include a link in the Arch Linux bug report. This helps us all.
 
  +
パッケージの PKGBUILD を検査して ([[Arch build system]] で)、どのようにパッケージ化されているかを確認します。
  +
詳細については、[[バグ報告ガイドライン#上流か Arch か?]] を参照してください。
   
  +
バグが Arch Linux に関連しておらず、他の場所でも再現できる場合は、上流にのみ報告してください。Arch Linux は上流のバグを魔法のように修正することはできません。Arch バグトラッカーに報告しても役に立たず、バグ管理者の時間を無駄にする傾向があるため、逆効果になる可能性さえあります。
However, if you think there's something wrong with the application itself, and not with how it is packaged, report the bug directly to upstream (which means the developers of the application). Normally, software streams from developers, through packagers/maintainers and down to users. Upstream means the other way, so for this case: directly to the developers of an application.
 
   
 
== 参照 ==
 
== 参照 ==
   
*[http://www.gentoo.org/proj/en/qa/backtraces.xml Gentoo guide for getting useful backtraces]
+
*[https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces Gentoo guide for getting useful backtraces]

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 をメモしてください。

ヒント: strace からの出力を grep したい場合、次のコマンドを試してみてください: strace -o /dev/stdout appname | grep string

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_namebash -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 バグトラッカーに報告しても役に立たず、バグ管理者の時間を無駄にする傾向があるため、逆効果になる可能性さえあります。

参照