致命的エラーが発生すると、その致命的エラーの発生時に取得された情報や状態を含むエラーログが作成されます。
更新リリースではこのファイルの形式が若干変わる可能性があります。
この付録には、次のセクションがあります。
製品フラグ -XX:ErrorFile=file を使用すると、そのファイルが作成される場所を指定できます。ここで、file はそのファイルの場所へのフルパスを表します。file 変数内の部分文字列 %% は % に変換され、部分文字列 %p はプロセスのプロセス ID に変換されます。
次の例では、エラーログファイルがディレクトリ /var/log/java に書き込まれ、java_errorpid.log という名前が付けられます。
java -XX:ErrorFile=/var/log/java/java_error%p.log
-XX:ErrorFile=file フラグを指定しない場合、ファイル名はデフォルトで hs_err_pidpid.log になります。ここで、pid はプロセスのプロセス ID です。
また、-XX:ErrorFile=file フラグが指定されなかった場合、システムはプロセスの作業ディレクトリにファイルを作成しようとします。(容量不足、権限の問題、またはその他の問題のために) 作業ディレクトリにファイルを作成できない場合は、オペレーティングシステムの一時ディレクトリにファイルが作成されます。Solaris OS および Linux の場合、一時ディレクトリは /tmp です。Windows の場合、一時ディレクトリは TMP 環境変数の値によって指定されます。その環境変数が未定義の場合、TEMP 環境変数の値が使用されます。
エラーログには、可能であれば次の情報を含む、致命的エラーの発生時に取得された情報が含まれています。
致命的エラーを引き起こした操作例外またはシグナル
バージョンおよび構成情報
致命的エラーを引き起こしたスレッドの詳細およびスレッドのスタックトレース
実行中のスレッドとその状態のリスト
ヒープに関するサマリー情報
ロードされているネイティブライブラリのリスト
コマンド行引数
環境変数
オペレーティングシステムおよび CPU の詳細
注 - この情報の一部しかエラーログに出力されない場合があります。これが起こる可能性があるのは、致命的エラーの深刻度が高いため、エラーハンドラが一部の詳細情報しか復元および報告できない場合です。
エラーログは、次のセクションで構成されるテキストファイルです。
クラッシュについて簡単に説明するヘッダー。「C.3 ヘッダー形式」を参照してください。
スレッド情報を含むセクション。「C.4 スレッドセクションの形式」を参照してください。
プロセス情報を含むセクション。「C.5 プロセスセクションの形式」を参照してください。
システム情報を含むセクション。「C.6 システムセクションの形式」を参照してください。
注 - ここで説明している致命的エラーログの形式は JDK 7 に基づいています。その他のリリースでは形式が異なる場合があります。
すべての致命的エラーログファイルの先頭にあるヘッダーセクションには、問題の簡易説明が含まれます。このヘッダーは、標準出力にも出力されるほか、アプリケーションの出力ログに現れる可能性もあります。
ヘッダーには HotSpot 仮想マシンエラー報告ページへのリンクが含まれていますが、そのページではユーザーがバグレポートを提出できます。
クラッシュ時のサンプルヘッダーを次に示します。
# # An unexpected error has been detected by Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x417789d7, pid=21139, tid=1024 # # Java VM: Java HotSpot(TM) Client VM (1.6.0-rc-b63 mixed mode, sharing) # Problematic frame: # C [libNativeSEGV.so+0x9d7] # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp #
この例は、予期しないシグナルによって VM がクラッシュしたことを示しています。その次の行には、シグナルのタイプ、シグナルの原因となったプログラムカウンタ (pc)、プロセス ID、およびスレッド ID についての説明があります (次を参照)。
# SIGSEGV (0xb) at pc=0x417789d7, pid=21139, tid=1024 | | | | +--- スレッド ID | | | +------------- プロセス ID | | +--------------------------- プログラムカウンタ | | (命令ポインタ) | +--------------------------------------- シグナル番号 +---------------------------------------------- シグナル名
その次の行には、VM のバージョン (Client VM または Server VM)、アプリケーションが混合モード、インタプリタモードのどちらで実行されたかを示す情報、およびクラスファイル共有が有効になっていたかどうかを示す情報が含まれます。
# Java VM: Java HotSpot(TM) Client VM (1.6.0-rc-b63 mixed mode, sharing)
その次の情報は、クラッシュの原因となった関数のフレームです (次を参照)。
# Problematic frame: # C [libNativeSEGV.so+0x9d7] | +-- pc と同じですが、ライブラリ名とオフセットとして表されます。 | 位置独立ライブラリ (JVM およびほとんどの共有 | ライブラリ) の場合は、逆アセンブラを使用してオフセットの | 近くの命令をダンプすることで、クラッシュの原因となった | 命令をデバッガやコアファイルを使用しないで | 検査できます。 +----------------- フレームタイプ
この例のフレームタイプ「C」は、ネイティブ C フレームを示しています。次の表に、可能性のあるフレームタイプを示します。
|
内部エラーが発生した場合も、VM エラーハンドラによって似たようなエラーダンプが生成されます。ただし、ヘッダー形式が異なります。内部エラーの例としては、guarantee() の失敗、アサーションの失敗、ShouldNotReachHere() などが挙げられます。内部エラー発生時のヘッダーの例を、次に示します。
# # An unexpected error has been detected by HotSpot Virtual Machine: # # Internal Error (4F533F4C494E55583F491418160E43505000F5), pid=10226, tid=16384 # # Java VM: Java HotSpot(TM) Client VM (1.6.0-rc-b63 mixed mode)
上のヘッダーにはシグナル名やシグナル番号がありません。2 行目には代わりに、「Internal Error」というテキストと長い 16 進文字列が含まれるようになっています。この 16 進文字列は、エラーが検出されたソースモジュールと行番号をエンコードしたものです。この「エラー文字列」は一般に、HotSpot 仮想マシンを操作するエンジニアにしか役に立ちません。
エラー文字列は行番号をエンコードしているため、コード変更やリリースのたびに変わります。あるリリース (1.6.0 など) の特定のエラー文字列を含むクラッシュは、更新リリース (1.6.0_01 など) の同じクラッシュに対応しない可能性があります (文字列が一致する場合でも)。
注 - 特定のエラー文字列に関連する状況で動作した回避方法や解決方法が、その同じエラー文字列に関連する別の状況でも動作するとは考えないでください。次の事実に注意してください。
エラーの根本的原因が同じでも、エラー文字列は異なることがあります。
エラーのエラー文字列が同じでも、根本的原因は完全に異なることがあります。
したがって、バグのトラブルシューティングを行う際に、エラー文字列を唯一の基準として使用すべきではありません。
このセクションには、クラッシュしたばかりのスレッドに関する情報が含まれます。複数のスレッドが同時にクラッシュした場合、1 つのスレッドのみが出力されます。
スレッドセクションの最初の部分では次のように、致命的エラーを引き起こしたスレッドが示されます。
Current thread (0x0805ac88): JavaThread "main" [_thread_in_native, id=21139] | | | | +-- ID | | | +------------- 状態 | | +-------------------------- 名前 | +------------------------------------ タイプ +-------------------------------------------------- ポインタ
スレッドポインタは、Java VM 内部のスレッド構造体へのポインタです。ライブ Java VM やコアファイルのデバッグを行なっているのでないかぎり、これは一般に役に立ちません。
次の一覧は、可能性のあるスレッドタイプを示したものです。
JavaThread
VMThread
CompilerThread
GCTaskThread
WatcherThread
ConcurrentMarkSweepThread
次の表に重要なスレッドの状態を示します。
|
出力に含まれるスレッド ID は、ネイティブスレッド識別子です。
Java スレッドがデーモンスレッドの場合、スレッドの状態の前に daemon という文字列が出力されます。
エラーログ内のその次の情報は、VM が終了する原因となった予期しないシグナルの説明です。Windows システムの場合、出力は次のようになります。
siginfo: ExceptionCode=0xc0000005, reading address 0xd8ffecf1
上の例では、例外コードは 0xc0000005 (ACCESS_VIOLATION) であり、スレッドがアドレス 0xd8ffecf1 を読み取ろうとしたときに例外が発生しました。
Solaris OS および Linux システムでは次のように、例外を識別するためにシグナル番号 (si_signo) とシグナルコード (si_code) が使用されます。
siginfo:si_signo=11, si_errno=0, si_code=1, si_addr=0x00004321
エラーログ内のその次の情報は、致命的エラー発生時のレジスタコンテキストを示します。この出力の実際の形式はプロセッサに依存します。次の例は、Intel (IA32) プロセッサの出力を示したものです。
Registers: EAX=0x00004321, EBX=0x41779dc0, ECX=0x080b8d28, EDX=0x00000000 ESP=0xbfffc1e0, EBP=0xbfffc1f8, ESI=0x4a6b9278, EDI=0x0805ac88 EIP=0x417789d7, CR2=0x00004321, EFLAGS=0x00010216
レジスタの値は、次に説明する命令と組み合わせると、役立つ可能性があります。
エラーログにはレジスタ値のあとに、システムがクラッシュした際のスタックの先頭と、プログラムカウンタ (PC) 付近の 32 バイト分の命令 (操作コード) が含まれています。これらの操作コードを逆アセンブラでデコードすれば、クラッシュの場所の近くにあった命令を生成できます。IA32 および AMD64 命令は可変長であるため、常にクラッシュ PC の前の命令を間違いなくデコードできるとはかぎりません。
Top of Stack: (sp=0xbfffc1e0) 0xbfffc1e0: 00000000 00000000 0818d068 00000000 0xbfffc1f0: 00000044 4a6b9278 bfffd208 41778a10 0xbfffc200: 00004321 00000000 00000cd8 0818d328 0xbfffc210: 00000000 00000000 00000004 00000003 0xbfffc220: 00000000 4000c78c 00000004 00000000 0xbfffc230: 00000000 00000000 00180003 00000000 0xbfffc240: 42010322 417786ec 00000000 00000000 0xbfffc250: 4177864c 40045250 400131e8 00000000 Instructions: (pc=0x417789d7) 0x417789c7: ec 14 e8 72 ff ff ff 81 c3 f2 13 00 00 8b 45 08 0x417789d7: 0f b6 00 88 45 fb 8d 83 6f ee ff ff 89 04 24 e8
可能な場合、エラーログ内のその次の出力はスレッドスタックになります。これには、スタックのベースと先頭のアドレス、現在のスタックポインタ、およびスレッドで使用可能な未使用スタックの量が含まれます。このあとに可能であればスタックフレームが続き、最大 100 件のフレームが出力されます。C/C++ フレームの場合、ライブラリ名も出力される可能性があります。ここで注意する必要があるのは、致命的エラーの状態によってはスタックが破損している可能性があり、その場合にはこの詳細情報が利用できない可能性がある、という点です。
Stack: [0x00040000,0x00080000), sp=0x0007f9f8, free space=254k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [jvm.dll+0x83d77] C [App.dll+0x1047] j Test.foo()V+0 j Test.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub V [jvm.dll+0x80f13] V [jvm.dll+0xd3842] V [jvm.dll+0x80de4] C [java.exe+0x14c0] C [java.exe+0x64cd] C [kernel32.dll+0x214c7] Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j Test.foo()V+0 j Test.main([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub
ログには 2 つのスレッドスタックが含まれます。
最初のスレッドスタックであるネイティブフレームでは、ネイティブスレッドが出力され、すべての関数呼び出しが表示されます。ただし、このスレッドスタックでは、ランタイムコンパイラによってインライン化された Java メソッドは考慮されません。インライン化されたメソッドは、親のスタックフレームの一部として表示されます。
ネイティブフレームのスレッドスタックの情報は、クラッシュの原因に関する重要な情報を提供します。リスト内のライブラリを上から順に分析すれば、通常は、問題の原因となったライブラリを特定し、そのライブラリを担当する適切な組織に問題を報告することができます。
2 番目のスレッドスタックである Java フレームでは、Java フレーム (インライン化されたメソッドを含む) が出力され、ネイティブフレームはスキップされます。クラッシュによっては、ネイティブスレッドスタックを出力できなくても、Java フレームを出力できる可能性があります。
VM スレッド内やコンパイラスレッド内でエラーが発生した場合には、追加の詳細情報が出力される可能性があります。たとえば VM スレッドの場合、致命的エラーの発生時に VM スレッドが VM 操作を実行していた場合、その VM 操作が出力されます。次の出力例の場合、致命的エラーを引き起こしたのはコンパイラスレッドです。タスクはコンパイラタスクであり、HotSpot Client VM がメソッド hs101t004Thread.ackermann をコンパイルしています。
Current CompileTask: HotSpot Client Compiler:754 b nsk.jvmti.scenarios.hotswap.HS101.hs101t004Thread.ackermann(IJ)J (42 bytes)
HotSpot Server VM の場合はコンパイラタスクの出力が若干異なりますが、やはり完全なクラス名とメソッドを含んでいます。
プロセスセクションはスレッドセクションのあとに出力されます。ここには、プロセスのスレッドリストやメモリー使用状況など、プロセス全体に関する情報が含まれます。
スレッドリストには、VM が認識しているスレッドが含まれます。これには、すべての Java スレッドや一部の VM 内部スレッドが含まれますが、ユーザーアプリケーションによって作成されたネイティブスレッドのうち、VM に接続しなかったスレッドは含まれません。出力形式は次のとおりです。
=>0x0805ac88 JavaThread "main" [_thread_in_native, id=21139] | | | | | +----- ID | | | | +------------------- 状態 | | | | (JavaThread のみ) | | | +--------------------------------- 名前 | | +------------------------------------------ タイプ | +---------------------------------------------------- ポインタ +------------------------------------------------------ "=>" 現在のスレッド
この出力の例を次に示します。
Java Threads: ( => current thread ) 0x080c8da0 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=21147] 0x080c7988 JavaThread "CompilerThread0" daemon [_thread_blocked, id=21146] 0x080c6a48 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=21145] 0x080bb5f8 JavaThread "Finalizer" daemon [_thread_blocked, id=21144] 0x080ba940 JavaThread "Reference Handler" daemon [_thread_blocked, id=21143] =>0x0805ac88 JavaThread "main" [_thread_in_native, id=21139] Other Threads: 0x080b6070 VMThread [id=21142] 0x080ca088 WatcherThread [id=21148]
スレッドタイプやスレッド状態については、「C.4 スレッドセクションの形式」を参照してください。
その次の情報は VM の状態で、これは仮想マシン全体の状態を示します。次の表では一般的な状態を説明します。
|
VM 状態の出力は次のように、エラーログ内で 1 行になります。
VM state:not at safepoint (normal execution)
エラーログ内のその次の情報は、現在スレッドによって所有されている相互排他ロックとモニターのリストです。これらの相互排他ロックは、Java オブジェクトに関連付けられたモニターではなく、VM 内部のロックです。VM ロックが保持された状態でクラッシュが発生した場合の出力を示す例を次に示します。ログにはロックごとに、ロックの名前、所有者、VM 内部の相互排他ロック構造体のアドレス、およびその OS ロックのアドレスが含まれます。この情報は一般に、HotSpot VM にきわめて習熟したユーザーにしか役に立ちません。所有者スレッドはスレッドリストと相互参照できます。
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])[0x007357b0/0x0000031c] Threads_lock - owner thread: 0x00996318 [0x00735978/0x000002e0] Heap_lock - owner thread: 0x00736218
その次の情報はヒープのサマリーです。出力はガベージコレクション (GC) の構成に依存します。この例ではシリアルコレクタが使用され、クラスデータ共有が無効にされ、Tenured 世代が空になっています。これはおそらく、初期段階や起動中に致命的なエラーが発生し、GC がまだどのオブジェクトも Tenured 世代に昇格させていなかったことを示しています。この出力の例を次に示します。
Heap def new generation total 576K, used 161K [0x46570000, 0x46610000, 0x46a50000) eden space 512K, 31% used [0x46570000, 0x46598768, 0x465f0000) from space 64K, 0% used [0x465f0000, 0x465f0000, 0x46600000) to space 64K, 0% used [0x46600000, 0x46600000, 0x46610000) tenured generation total 1408K, used 0K [0x46a50000, 0x46bb0000, 0x4a570000) the space 1408K, 0% used [0x46a50000, 0x46a50000, 0x46a50200, 0x46bb0000) compacting perm gen total 8192K, used 1319K [0x4a570000, 0x4ad70000, 0x4e570000) the space 8192K, 16% used [0x4a570000, 0x4a6b9d48, 0x4a6b9e00, 0x4ad70000) No shared spaces configured.
ログ内のその次の情報は、クラッシュ時の仮想メモリー領域のリストです。大きなアプリケーションの場合、このリストが長くなる可能性があります。メモリーマップは一部のクラッシュをデバッグする際に非常に役立つ可能性がありますが、それは、実際に使用されていたライブラリやそのメモリー内での場所はもちろん、ヒープ、スタック、およびガードページの場所もわかるからです。
メモリーマップの形式はオペレーティングシステムに固有です。Solaris オペレーティングシステムではベースアドレスとライブラリ名が出力されます。Linux システムではプロセスメモリーマップ (/proc/pid/maps) が出力されます。Windows システムでは各ライブラリのベースアドレスと終了アドレスが出力されます。次の出力例は Linux/x86 上で生成されたものです。この例では簡潔にするために、ほとんどの行が省略されています。
Dynamic libraries: 08048000-08056000 r-xp 00000000 03:05 259171 /h/jdk6/bin/java 08056000-08058000 rw-p 0000d000 03:05 259171 /h/jdk6/bin/java 08058000-0818e000 rwxp 00000000 00:00 0 40000000-40013000 r-xp 00000000 03:0a 400046 /lib/ld-2.2.5.so 40013000-40014000 rw-p 00013000 03:0a 400046 /lib/ld-2.2.5.so 40014000-40015000 r--p 00000000 00:00 0 Lines omitted. 4123d000-4125a000 rwxp 00001000 00:00 0 4125a000-4125f000 rwxp 00000000 00:00 0 4125f000-4127b000 rwxp 00023000 00:00 0 4127b000-4127e000 ---p 00003000 00:00 0 4127e000-412fb000 rwxp 00006000 00:00 0 412fb000-412fe000 ---p 00083000 00:00 0 412fe000-4137b000 rwxp 00086000 00:00 0 Lines omitted. 44600000-46570000 rwxp 00090000 00:00 0 46570000-46610000 rwxp 00000000 00:00 0 46610000-46a50000 rwxp 020a0000 00:00 0 46a50000-46bb0000 rwxp 00000000 00:00 0 46bb0000-4a570000 rwxp 02640000 00:00 0 Lines omitted.
上のメモリーマップの 1 行の形式を次に示します。
40049000-4035c000 r-xp 00000000 03:05 824473 /jdk1.5/jre/lib/i386/client/libjvm.so |<------------->| ^ ^ ^ ^ |<----------------------------------->| メモリー領域 | | | | | | | | | | アクセス権 --- + | | | | r:読み取り | | | | w:書き込み | | | | x:実行 | | | | p:非公開 | | | | s:共有 | | | | | | | | ファイルオフセット ---+ | | | | | | ファイルが存在するデバイスの ---+ | | メジャー ID とマイナー ID | | (i.e. /dev/hda5) | | | | i ノード番号 ------------------------+ | | ファイル名 -------------------------------------------------------+
メモリーマップの出力では、ライブラリごとに仮想メモリー領域が 2 つずつあります。1 つはコード用、もう 1 つはデータ用です。コードセグメントのアクセス権は r-xp (読み取り可能、実行可能、非公開) でマークされ、データセグメントのアクセス権は rw-p (読み取り可能、書き込み可能、非公開) になります。
Java ヒープはすでに出力の前のほうのヒープサマリーに含まれていますが、ヒープ用に予約された実際のメモリー領域がヒープサマリーの値と一致することや、属性が rwxp に設定されていることを確認することは、有用である可能性があります。
スレッドスタックは通常、メモリーマップ内で連続する 2 つの領域、具体的にはアクセス権が ---p の領域 (ガードページ) とアクセス権が rwxp の領域 (実際のスタック領域) として表示されます。さらに、ガードページサイズやスタックサイズを知ることは有用です。たとえばこのメモリーマップでは、スタックの場所は 4127b000 から 412fb000 です。
Windows システムでは以下の例のように、メモリーマップの出力は、ロードされた各モジュールのロードアドレスと終了アドレスになります。
Dynamic libraries: 0x00400000 - 0x0040c000 c:\jdk6\bin\java.exe 0x77f50000 - 0x77ff7000 C:\WINDOWS\System32\ntdll.dll 0x77e60000 - 0x77f46000 C:\WINDOWS\system32\kernel32.dll 0x77dd0000 - 0x77e5d000 C:\WINDOWS\system32\ADVAPI32.dll 0x78000000 - 0x78087000 C:\WINDOWS\system32\RPCRT4.dll 0x77c10000 - 0x77c63000 C:\WINDOWS\system32\MSVCRT.dll 0x08000000 - 0x08183000 c:\jdk6\jre\bin\client\jvm.dll 0x77d40000 - 0x77dcc000 C:\WINDOWS\system32\USER32.dll 0x7e090000 - 0x7e0d1000 C:\WINDOWS\system32\GDI32.dll 0x76b40000 - 0x76b6c000 C:\WINDOWS\System32\WINMM.dll 0x6d2f0000 - 0x6d2f8000 c:\jdk6\jre\bin\hpi.dll 0x76bf0000 - 0x76bfb000 C:\WINDOWS\System32\PSAPI.DLL 0x6d680000 - 0x6d68c000 c:\jdk6\jre\bin\verify.dll 0x6d370000 - 0x6d38d000 c:\jdk6\jre\bin\java.dll 0x6d6a0000 - 0x6d6af000 c:\jdk6\jre\bin\zip.dll 0x10000000 - 0x10032000 C:\bugs\crash2\App.dll
エラーログ内のその次の情報は、VM 引数のリストと、それに続く環境変数のリストです。次に例を示します。
VM Arguments: java_command: NativeSEGV 2 Environment Variables: JAVA_HOME=/h/jdk PATH=/h/jdk/bin:.:/h/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin: /usr/dist/local/exe:/usr/dist/exe:/bin:/usr/sbin:/usr/ccs/bin: /usr/ucb:/usr/bsd:/usr/etc:/etc:/usr/dt/bin:/usr/openwin/bin: /usr/sbin:/sbin:/h:/net/prt-web/prt/bin USERNAME=user LD_LIBRARY_PATH=/h/jdk6/jre/lib/i386/client:/h/jdk6/jre/lib/i386: /h/jdk6/jre/../lib/i386:/h/bugs/NativeSEGV SHELL=/bin/tcsh DISPLAY=:0.0 HOSTTYPE=i386-linux OSTYPE=linux ARCH=Linux MACHTYPE=i386
この環境変数のリストは、Java VM に適用可能な環境変数の完全なリストではなく、そのサブセットです。
Solaris OS および Linux の場合、エラーログ内のその次の情報はシグナルハンドラのリストです。
Signal Handlers: SIGSEGV: [libjvm.so+0x3aea90], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGBUS: [libjvm.so+0x3aea90], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGFPE: [libjvm.so+0x304e70], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGPIPE: [libjvm.so+0x304e70], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGILL: [libjvm.so+0x304e70], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGUSR2: [libjvm.so+0x306e80], sa_mask[0]=0x80000000, sa_flags=0x10000004 SIGHUP: [libjvm.so+0x3068a0], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGINT: [libjvm.so+0x3068a0], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGQUIT: [libjvm.so+0x3068a0], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGTERM: [libjvm.so+0x3068a0], sa_mask[0]=0xfffbfeff, sa_flags=0x10000004 SIGUSR2: [libjvm.so+0x306e80], sa_mask[0]=0x80000000, sa_flags=0x10000004
エラーログの最後のセクションは、システム情報です。その出力はオペレーティングシステムに固有ですが、一般にオペレーティングシステムのバージョン、CPU 情報、およびメモリー構成に関するサマリー情報を含みます。
次の例は、Solaris 9 OS システムでの出力を示したものです。
--------------- S Y S T E M --------------- OS: Solaris 9 12/05 s9s_u5wos_08b SPARC Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms. Assembled 21 November 2005 uname:SunOS 5.9 Generic_112233-10 sun4u (T2 libthread) rlimit: STACK 8192k, CORE infinity, NOFILE 65536, AS infinity load average:0.41 0.14 0.09 CPU:total 2 has_v8, has_v9, has_vis1, has_vis2, is_ultra3 Memory: 8k page, physical 2097152k(1394472k free) vm_info: Java HotSpot(TM) Client VM (1.5-internal) for solaris-sparc, built on Aug 12 2005 10:22:32 by unknown with unknown Workshop:0x550
Solaris OS および Linux の場合、オペレーティングシステム情報はファイル /etc/*release に含まれます。このファイルは、アプリケーションが実行されているシステムの種類について説明し、場合によっては情報文字列にパッチレベルが含まれることもあります。/etc/*release ファイルには一部のシステムアップグレードが反映されません。ユーザーがシステムの任意の部分を構築し直せる Linux システムの場合は、特にそうなります。
Solaris OS の場合、uname システムコールを使ってカーネルの名前が取得されます。スレッドライブラリ (T1 または T2) も出力されます。
Linux システムの場合も uname システムコールを使ってカーネル名が取得されます。libc のバージョンとスレッドライブラリのタイプも出力されます。次に例を示します。
uname:Linux 2.4.18-3smp #1 SMP Thu Apr 18 07:27:31 EDT 2002 i686 libc:glibc 2.2.5 stable linuxthreads (floating stack) |<- glibc version ->|<-- pthread type -->|
Linux の場合、可能なスレッドタイプは 3 つあります (具体的には linuxthreads (fixed stack)、linuxthreads (floating stack)、および NPTL)。これらは通常、/lib、/lib/i686、および /lib/tls にインストールされます。
スレッドタイプを知ることは有用です。たとえば、クラッシュが pthread に関係しているように見える場合、別の pthread ライブラリを選択すれば問題を回避できる可能性があります。別の pthread ライブラリ (および libc) を選択するには、LD_LIBRARY_PATH または LD_ASSUME_KERNEL を設定します。
glibc のバージョンには通常、パッチレベルは含まれません。コマンド rpm -q glibc を実行すると、より詳しいバージョン情報が得られる可能性があります。
Solaris OS および Linux の場合、その次の情報は rlimit 情報です。VM のデフォルトのスタックサイズは通常、システムの制限より小さくなっています。次に例を示します。
rlimit: STACK 8192k, CORE 0k, NPROC 4092, NOFILE 1024, AS infinity | | | | 仮想メモリー (-v) | | | +--- 最大オープンファイル数 (ulimit -n) | | +-------------- 最大ユーザープロセス数 (ulimit -u) | +------------------------------ コアダンプサイズ (ulimit -c) +------------------------------------------- スタックサイズ (ulimit -s) load average:0.04 0.05 0.02
その次の情報は、起動時に VM によって識別された CPU のアーキテクチャーと機能を指定します (次の例を参照)。
CPU:total 2 family 6, cmov, cx8, fxsr, mmx, sse | | |<----- CPU 機能 ---->| | | | +--- プロセッサファミリ (IA32 のみ):| 3 - i386 | 4 - i486 | 5 - Pentium | 6 - PentiumPro、PII、PIII | 15 - Pentium 4 +------------ CPU の合計数次の表に、SPARC システムで可能な CPU 機能を示します。
|
次の表に、Intel/IA32 システムで可能な CPU 機能を示します。
|
次の表に、AMD64/EM64T システムで可能な CPU 機能を示します。
|
エラーログ内のその次の情報はメモリー情報です (次を参照)。
未使用のスワップ空間 スワップ空間の合計容量 | 未使用の物理メモリー | | 物理メモリーの合計容量 | | | ページサイズ | | | | v v v v v Memory: 4k page, physical 513604k(11228k free), swap 530104k(497504k free)
一部のシステムではスワップ空間が実際の物理メモリーの少なくとも 2 倍であることを要求しますが、そのような要件を持たないシステムもあります。一般に、物理メモリーとスワップ空間の両方がほぼいっぱいになっていれば、クラッシュの原因としてメモリー不足を疑って良いでしょう。
Linux システムではカーネルが、未使用の物理メモリーの大部分をファイルキャッシュに変換する場合があります。追加のメモリーが必要になると、Linux カーネルはキャッシュメモリーをアプリケーションに戻します。この処理はカーネルによって透過的に行われますが、それは、使用可能な物理メモリーがまだ十分存在するにもかかわらず、致命的エラーハンドラが報告する未使用物理メモリーの量がゼロに近くなる可能性があることを意味します。
エラーログの SYSTEM セクション内の最後の情報は vm_info で、これは libjvm.so/jvm.dll に埋め込まれたバージョン文字列です。どの Java VM も一意の vm_info 文字列を持ちます。特定の Java VM によって致命的エラーログが生成されたのかどうかを疑問に思う場合には、バージョン文字列をチェックしてください。