17 バグ・レポートの提出

この章では、バグ・レポートを提出する方法を示します。これには、レポートを提出する前に試すこと、およびレポート用に収集するデータに関する提案が含まれています。

この章の構成は、次のとおりです。

更新リリースに含まれる修正のチェック

各リリースへの定期的にスケジュールされた更新には、そのプラットフォームの初期リリース以降に確認された一連のクリティカルなバグの修正が含まれています。

更新リリースが利用可能になると、Java SEダウンロード・ページにあるデフォルトのダウンロードになります。

このダウンロード・サイトには、そのリリースにおけるバグ修正のリストを示すリリース・ノートへのリンクが含まれています。リストにある各バグは、バグ・データベース内のバグの説明にリンクされています。リリース・ノートには、以前の更新リリースにおける修正のリストも含まれています。問題が発生した場合やバグの疑いがある場合には、診断の初期ステップとして、最新の更新リリースで使用可能な修正のリストをチェックしてください。

ある問題が、すでに修正されたバグと同じものであるか明確でない場合があります。

バグ・レポートの提出の準備

次に、バグ・レポートを提出するための推奨手順を示します。

バグ・レポートを提出する前に、次の推奨事項を検討してください。

  • できるだけ多くの関連データを収集します。たとえば、デッドロックが発生した場合はスレッド・ダンプを生成し、クラッシュが発生した場合はコア・ファイル(該当する場合)とhs_errファイルを見つけます。いずれの場合も、環境と、問題が発生する直前に実行されていたアクションを文書化することが重要です。「バグ・レポート用のデータの収集」を参照してください。
  • 適用可能な場合は、元の状態を復元し、文書化したステップを使って問題を再現してみます。これにより、その問題が再現可能なものであるか、間欠的なものであるかを判断できます。
  • 問題が再現可能な場合は、問題を絞り込んでみてください。場合によっては、小規模なスタンドアロンのテスト・ケースを使ってバグを再現できます。小規模なテスト・ケースで再現されるバグは通常、大規模で複雑なアプリケーションで構成されているテスト・ケースに比べて診断が容易です。
  • Javaバグ・データベースを検索して、この問題または同様の問題が報告されているかどうかを確認します。問題がすでに報告されている場合は、次のような詳細情報がバグ・レポートに記載されている可能性があります。
    • 問題がすでに修正されている場合、それが修正されたリリース。

    • 問題の回避策。

    • 問題が発生する環境についてさらに詳しく説明する、評価内のコメント。

  • 問題がまだ報告されていないと判断した場合は、「バグをレポート」または機能の要求で報告します。

問題を報告する前に、問題が発生した環境が、サポートされている構成であることを確認します。Oracle JDK 17の動作保証済システム構成を参照してください。

システム構成のほかに、サポート対象のロケールのリストも確認します。JDK 17でサポートされているロケールを参照してください。

バグ・レポート用のデータの収集

次の各項に、コマンドの一覧またはデータを取得するための一般的な推奨手順を示します:

問題の詳細な説明

問題の説明を作成するときは、できるだけ多くの関連情報を含めるようにしてください。

アプリケーション、環境、そして問題が発生した時点につながる最も重要なイベントを記述します。

すでに行ったすべてのトラブルシューティングのステップと結果を報告します

複雑なアプリケーション環境でしか問題を再現できない場合があります。その場合は、ログ、コア・ファイル、およびその他の関連情報を伴う説明が問題を診断する唯一の手段になる可能性があります。このような状況では、提出者が問題の発生しているシステムでさらなる診断を行ったり、テスト・バイナリを実行したりする意志があるかどうかをその説明で示すようにしてください。

  • 問題が自由に再現可能な場合は、その問題を再現するために必要なステップの一覧を示します。
  • 問題を小さなテスト・ケースで再現できる場合は、そのテスト・ケースと、そのテスト・ケースをコンパイルして実行するためのコマンドを含めます。
  • テスト・ケースまたは問題にサード・パーティのコード(商用またはオープン・ソースのライブラリやパッケージなど)が必要な場合は、そのライブラリの場所と入手方法についての詳細を提供します。

ハードウェアの詳細

致命的なエラーが発生すると、エラー・ログにハードウェアの詳細が保存されます。

特定のハードウェア構成でのみバグが発生したり再現できたりすることがあります。致命的なエラーが発生した場合は、エラー・ログにハードウェアの詳細が含まれている可能性があります。エラー・ログを入手できない場合は、マシンのプロセッサの番号と種類、クロック速度、および該当する場合かつ既知の場合は、そのプロセッサの機能に関するいくつかの詳細をバグ・レポートにまとめます。たとえばIntelプロセッサの場合、ハイパースレッディングが使用可能であることがそれに該当します。

オペレーティング・システムの詳細

オペレーティング・システムには、オペレーティング・システムの詳細を取得するために使用できるコマンドが用意されています。

Linuxでは、使用されているディストリビューションとバージョンを知ることが重要です。/etc/*releaseファイルがリリース情報を示している場合がありますが、コンポーネントとパッケージは個別にアップグレードできるため、必ずしもそれが信頼できる構成を示しているとはかぎりません。そのため、*releaseファイルからの情報に加えて、次の情報も収集してください。

  • カーネル・バージョン: これは、uname -aコマンドを使用して取得できます。
  • glibcバージョン: rpm -q glibcコマンドは、glibcのパッチ・レベルを示します。
  • スレッド・ライブラリ: Linuxには、LinuxThreadsおよびNPTLという2つのスレッド・ライブラリがあります。LinuxThreadsライブラリは2.4以前のカーネルで使用され、固定スタックと浮動スタックのバリアントがあります。Native POSIX Thread Library (NPTL)は2.6カーネルで使用されます。一部のLinuxリリース(RHEL3など)には、NPTLの2.4カーネルへのバックポートが含まれています。使用されているスレッド・ライブラリを確認するには、コマンドgetconf GNU_LIBPTHREAD_VERSIONを使用します。getconfコマンドが、その変数が存在しないことを示すエラーを返す場合は、古いカーネルをLinuxThreadsライブラリとともに使用している可能性があります。

Java SEのバージョン

java -versionコマンドを使用して、Java SEのバージョン文字列を取得します。

同じマシン上にJava SEのバージョンが複数インストールされている可能性があります。したがって、失敗したアプリケーションで使用されるjavaコマンドのバージョンを使用してください。これは、ユーザーのPATH環境変数に含まれるデフォルトのjavaコマンドとは異なる可能性が非常に高くなります。

コマンド行オプション

バグ・レポートに致命的エラー・ログが含まれていない場合は、コマンド行全体とそのすべてのオプションを文書化することが重要です。これには、ヒープ設定を指定するオプション(-Xmxオプションなど)やHotSpot固有のオプションを指定する-XXオプションが含まれます。

問題を自由に再現でき、JVMの標準出力(stdout)を読み取ることができる場合は、-XX:+PrintCommandLineFlagsオプションを追加して、アプリケーションで使用されるコマンド行オプションの完全なリストを取得できます。このオプションは、次回JVMを再起動したときにアクティブになります。

次のようにjcmdコマンドを実行して、実行中のVMのコマンド行オプションを取得することもできます。

jcmd <process ID for the Java process> VM.command_line

また、実行中のJVMのフラグは、jcmdを使用して変更できます。VM.set_flagコマンドを参照してください。

環境変数

環境変数の設定が原因で問題が発生する場合があります。バグ・レポートの作成時に、次のJava環境変数の値(設定されている場合)を記入してください。

  • JAVA_TOOL_OPTIONS

  • _JAVA_OPTIONS

  • CLASSPATH

  • JAVA_COMPILER

  • PATH

  • USERNAME

ノート:

障害が発生したアプリケーションのコンテキストから環境変数の値を取得する必要があります。さらに、1つ以上の構成ファイルで、障害が発生したアプリケーションに対してこれらの環境変数の値を設定できます。

また、次のオペレーティング・システム固有の環境変数も収集してください。

  • Linuxオペレーティング・システムでは、次の環境変数の値を収集します:
    • LD_LIBRARY_PATH

    • LD_PRELOAD

  • Windowsでは、次の環境変数の値を収集します:
    • OS

    • PROCESSOR_IDENTIFIER

    • _ALT_JAVA_HOME_DIR

致命的エラー・ログ

致命的エラーが発生すると、エラー・ログが作成されます。「致命的エラー・ログ」を参照してください。

このエラー・ログには、致命的エラーの発生時に得られた情報(バージョンや環境の情報、クラッシュを引き起こしたスレッドの詳細など)が含まれています。

致命的エラー・ログが生成される場合は、必ずそれをバグ・レポートに含めるか、サポート・コール時に報告してください。

コア・ダンプおよびクラッシュ・ダンプ

報告された問題が原因でコア・ファイルまたはクラッシュ・ダンプが作成された場合は、それをバグ、サイズ許可とともに含めます。

Linuxコア・ファイルまたはWindowsクラッシュ・ダンプには、コアまたはダンプが作成された時点のアプリケーションまたはオペレーティング・システムのメモリー状態が含まれます。システムの構成によっては、クラッシュが発生したときにコア・ダンプまたはクラッシュ・ダンプが自動的に作成される場合があります。システム管理者に問い合せて、コア・ファイルが自動的に生成されるかどうか、およびどこに生成されるかを判断してください。

ハングアップ・プロセスの場合、ダンプを生成する手順については、「コア・ダンプの収集」を参照してください。

ログおよびトレース

ログまたはトレース出力が問題の原因を迅速に特定するのに役立つ可能性があります。

たとえば、パフォーマンスの問題の場合、-verbose:gcオプションの出力が問題の診断に役立つ可能性があります。このオプションは、ガベージ・コレクタからの出力を有効にします。

それ以外の場合は、Javaフライト・レコーダおよびJDK Mission Controlを使用して、問題に至るまでの期間の統計情報を取得できます。

VMのデッドロックまたはハングの場合は、スレッド・スタックが問題の診断に役立つ可能性があります。スレッド・スタックを取得するには、Linuxでは[Ctrl]+[\]、Windowsでは[Ctrl]+[Break]を押します。または、jcmdコマンドでThread.dump_to_fileオプションを使用します。

通常は、関連のあるすべてのログ、トレース、およびその他の出力をバグ・レポートまたはサポート・コール時に提供します。

バグをレポート

問題がまだ報告されておらず、それに関するデータが収集されていないと判断した場合は、「バグをレポート」または機能の要求で報告します。

コア・ダンプの収集

コア・ダンプまたはクラッシュ・ダンプとは、プロセスのメモリー・スナップショットです。

コア・ダンプは、致命的エラーまたは処理できないエラーの発生時にオペレーティング・システムによって自動的に作成されることがあります。また、コア・ダンプはシステム提供のコマンド行ユーティリティを使用して強制的に取得することもできます。ハングアップしているように見えるプロセスを診断する際にコア・ダンプが役立つ場合があります。つまり、コア・ダンプによってハングアップの原因に関する情報が明らかになることがあります。

次の項では、コア・ダンプの収集シナリオについて説明します。

Linuxでのコア・ダンプの収集

デフォルトでは、コア・ダンプはプロセスの現在の作業ディレクトリに作成されます。コア・ダンプ・ファイルの名前はcore.pidで、pidはクラッシュしたJavaプロセスのプロセスIDです。

すべてのシステムがコア・ファイルの作成を許可するように構成されているわけではありません。ulimitユーティリティは、現在のシェルとその子孫で利用できるシステム・リソースへの制限を設定または取得するために使用されます。コア・ファイルのサイズ制限をチェックまたは設定するには、ulimit -cコマンドを使用します。その制限が必ずunlimitedに設定されるようにしてください。そうしないと、コア・ファイルが切り詰められたり生成されない可能性があります。

ノート:

ulimitはBashシェルの組込みコマンドです。Cシェルでは、limitコマンドを使用してください。

VMまたはアプリケーションの起動に使用されるスクリプトがコア・ダンプの作成を無効にしないようにしてください。

gcoreコマンドをgdb (GNUデバッガ)インタフェースで使用すると、実行中のプロセスのコア・イメージを取得できます。このユーティリティは、コア・ダンプを強制的に作成させるプロセスのpidを受け入れます。

マシン上で実行されているJavaプロセスのリストを取得するには、次のいずれかのコマンドを使用できます。

  • jcmd
  • ps -ef | grep java
  • pgrep java

ShowMessageBoxOnErrorオプションを使用して、Linuxでコア・ダンプを収集できます。-XX:+ShowMessageBoxOnErrorコマンド行オプションを使用してJavaプロセスを起動します。致命的エラーが発生すると、そのプロセスは標準エラーにメッセージを出力し、標準入力からの「yes」または「no」の応答を待ちます。

コア・ファイルを取得しない理由

次のリストでは、Linuxでコア・ファイルが生成されない可能性がある理由を示します:

  • アプリケーション・ユーザーに、そのプロセスの現在の作業ディレクトリへの書込み権がありません。

  • アプリケーション・ユーザーには現在の作業ディレクトリへの書込み権がありますが、読取り専用の権限を持つcoreという名前のファイルがすでに存在しています。

  • 現在のディレクトリに十分な空き領域がありません。

  • 現在のディレクトリに、coreという名前のサブディレクトリがあります。

  • 現在の作業ディレクトリがリモートです。ネットワーク・ファイル・システム(NFS)にマップされている可能性があり、コア・ダンプが作成されようとしているときにNFSが失敗しました。

  • プロセスがsetuidプログラムを実行しているため、オペレーティング・システムは、明示的に構成されないかぎり、コアをダンプしません。

  • Java固有: プロセスがSIGSEGVまたはSIGILLを受信してもコア・ファイルが生成されなかった場合、プロセスがそれを処理した可能性があります。たとえば、HotSpot VMはSIGSEGVシグナルを、正当な目的(NullPointerExceptionのスローや最適化解除など)のために使用します。Java VMによってシグナルが処理されないのは、現在の命令(PC)がJava VM生成コードから外れる場合だけです。これらが、HotSpotでコアがダンプされる唯一の場合になります。

  • Java固有: VMの作成に、JNI呼び出しAPIが使用されました。標準のJavaランチャは使用されませんでした。カスタムJavaランチャ・プログラムが、シグナルを消費してその処理をすませ、ログ・エントリを暗黙のうちに生成しました。この状況は、特定のアプリケーション・サーバーやWebサーバーで発生しました。これらのJava VM埋め込みプログラムは、異常終了後にシステムの再起動(フェイルオーバー)を透過的に試行します。この場合、コア・ダンプが生成されないという事実は、機能であってバグではありません。

Windowsでのクラッシュ・ダンプの収集

Windowsオペレーティング・システムでは、ワトソン博士ログ・ファイル、ユーザー・ミニダンプおよびワトソン博士フル・ダンプの3種類のクラッシュ・ダンプがあります。

  • ワトソン博士のログ・ファイル。これは、障害時のスタック・トレースとその他のいくつかの詳細を含むテキスト・エラー・ログ・ファイルです。

  • ユーザーのミニダンプ。これは部分的なコア・ダンプと見なされます。このダンプにはプロセスの有用なメモリー・ページがすべて含まれているわけではないため、完全なコア・ダンプではありません。

  • ワトソン博士の完全ダンプ。これは、UNIXコア・ダンプと同等のものです。このダンプには、コード・ページを除くプロセスのほとんどのメモリー・ページが含まれています。

Windowsで予期しない例外が発生した場合、実行されるアクションは次のレジストリ・キーの2つの値によって異なります。

\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug

それらの2つの値には、DebuggerおよびAutoという名前が付いています。Auto値は、アプリケーション・エラーが発生したときに、Debuggerエントリの値で指定されたデバッガが自動的に起動するかどうかを示します。

  • Auto値が0の場合は、アプリケーション・エラーが発生したときにシステムがメッセージ・ボックスを表示してユーザーに知らせることを示します。

  • Auto値が1の場合は、デバッガが自動的に起動することを示します。

Debuggerの値は、プログラム・エラーのデバッグに使用されるデバッガ・コマンドです。

Windowsでは、プログラム・エラーが発生すると、Auto値を調べて、その値が0,の場合に、Debugger値に含まれるコマンドを実行します。Debuggerの値が有効なコマンドである場合は、「OK」「キャンセル」の2つのボタンを含むメッセージ・ボックスが作成されます。ユーザーが「OK」をクリックすると、プログラムが終了します。ユーザーが「キャンセル」をクリックすると、指定されたデバッガが開始されます。Autoエントリの値が1に設定され、Debuggerエントリの値が有効なデバッガを表すコマンドを指定している場合、システムはそのデバッガを自動的に起動し、メッセージ・ボックスを生成しません。

次は、Windowsでクラッシュ・ダンプを収集するための2つの方法です。

  • ワトソン博士の構成:

    ワトソン博士のデバッガは、クラッシュ・ダンプ・ファイルの作成に使用されます。デフォルトでは、ワトソン博士のデバッガ(drwtsn32.exe)はWindowsシステム・フォルダ(%SystemRoot%\System32)にインストールされます。

    ワトソン博士をポストモーテム・デバッガとしてインストールするには、次のコマンドを実行します。

    drwtsn32 -i
    

    クラッシュ・ダンプ・ファイルの名前と場所を構成するには、オプションを付けずにdrwtsn32を実行します。

    ワトソン博士のGUIウィンドウで、「クラッシュ・ダンプ・ファイルの作成」チェック・ボックスが選択されていること、およびクラッシュ・ダンプ・ファイル・パスとログ・ファイル・パスがそれぞれのテキスト・フィールドに構成されていることを確認します。

    レジストリを使用すると、フル・ダンプを作成するようにワトソン博士を構成できます。レジストリ・キーを次の例に示します。

    System Key: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson]
    Entry Name: CreateCrashDump
    Value: (0 = disabled, 1 = enabled)
    

    ノート:

    アプリケーションが例外を処理する場合は、レジストリで構成されたデバッガは呼び出されません。その場合は、-XX:+ShowMessageBoxOnErrorコマンド行オプションを使用することで、致命的エラーの状態ではユーザーが介入するまで待つようにプロセスを強制するのが適切である可能性があります。
  • クラッシュ・ダンプの強制:

    userdumpコマンド行ユーティリティを使用して実行中のプロセスのDr. Watsonダンプを強制できます。userdumpユーティリティはWindowsに同梱されていません。OEM Support Toolsパッケージのコンポーネントとして提供されています。

    クラッシュ・ダンプを強制する別の方法は、windbgデバッガを使用することです。windbgを使用することの主な利点は、非侵入的な方法(つまり読取り専用)でプロセスに接続できることです。通常、Windowsはクラッシュ・ダンプの取得後にプロセスを終了させますが、非侵入型の接続ではクラッシュ・ダンプの取得後もプロセスを続行できます。デバッガを接続するには、「Attach to Process」オプションを選択し、「Noninvasive」チェック・ボックスを選択します。

    デバッガが接続されたら、次の例に示されたコマンドを使用してクラッシュ・ダンプを取得できます。

    .dump /f crash.dmp
    

    windbgデバッガは、Debugging Tools for Windowsのダウンロードに含まれています。

    このダウンロードに含まれる追加のdumpchk.exeユーティリティは、メモリー・ダンプ・ファイルが正しく作成されたことを検証できます。

    userdump.exewindbgのどちらにも、プロセスのpidが必要です。userdump -pコマンドは、すべてのプロセスのプロセスとプログラムを一覧表示します。これは、アプリケーションがjava.exeランチャで起動されることがわかっている場合に役立ちます。ただし、カスタム・ランチャが使用される場合(埋込みVM)、プロセスの認識が困難である可能性があります。その場合は、JavaプロセスのPIDのみを一覧表示するjpsコマンド行ユーティリティを使用できます。

    Windowsでは-XX:+ShowMessageBoxOnErrorコマン行オプションを使用することもできます。致命的エラーが発生すると、そのプロセスはメッセージ・ボックスを表示し、ユーザーからの「yes」または「no」の応答を待ちます。

    「はい」または「いいえ」をクリックする前に、userdump.exeユーティリティを使用して、そのJavaプロセスのワトソン博士のダンプを生成できます。このユーティリティは、プロセスがハングアップしているように見える場合にも使用できます。