2011-08-30 10 views
15

私のJavaアプリケーションは、SIGSEGVとスタック・データのダンプと情報のロードをテキスト・ファイルに定期的にクラッシュさせ始めました。コード実行時にJVMで発生するSegfaultsをどのようにデバッグできますか?

gdbでCプログラムをデバッグしました。私はIDEからJavaコードをデバッグしました。実行中のJavaプログラムでCのようなクラッシュに近づく方法がわかりません。

私はここでJVMバグを見ていないと仮定しています。他のJavaプログラムもうまく動作し、SunのJVMはおそらく自分のコードよりも安定しています。しかし、私はどのようにJavaコードでsegfaultsを引き起こすことができるかわかりません。利用可能なメモリは十分です。最後にプロファイラをチェックインしたとき、ヒープの使用率は約50%で、時折スパイクが約80%でした。調査できるスタートアップパラメータはありますか?このようなバグに近づくと良いチェックリストは何ですか?

イベントを確実に再現できるわけではありませんが、ランダムでも完全に発生するとは思われません。したがって、テストは完全に不可能ではありません。

ETA:血みどろの詳細

の一部は(私はまだ、私はすでに収集いくつかの情報があります実際の問題は非常に特異的である可能性があるため、一般的なアプローチを探していますし、それがであってもよいですいくつかの値。)

はしばらく前に、私は(詳細はhereを参照してください)私のCIサーバをアップグレードした後に類似に見えるトラブルがあったが、-XX:MaxPermSizeを設定している修正は()この時間を助けていません。

さらに調査したところ、クラッシュログファイルでは、「現在のスレッド」とマークされたスレッドは決して私のものではなく、「VMThread」または「GCTaskThread」のいずれかであることが判明しました。コメントが "(終了)"とマークされている場合、前者の場合、GCTaskThreadはリストにありません。これは、問題がGC操作の終わりを過ぎている可能性があると思います。

+0

スタックトレースを取得できますか?それは同じ場所でSEGVですか?私たちはより多くの情報を取り組むことができますか? –

+0

アプリケーションにネイティブコードがありますか? JVMがバイトコードのコレクションを許可している場合、バイトコードがどのようにバグであっても、segfaultを引き起こすには、実際にJVM(またはJRE)のバグを見つけてください。 –

+0

@Ed - スタックトレースはたくさんありますが、巨大なテキストの壁です。投稿するのに最も役立つ部分は何ですか?私は主にこのタイプの問題にアプローチする一般的な方法を探しているので、ここでは非常に具体的な情報を読み込むことを躊躇しています。 –

答えて

22

私は、ここでJVMのバグを見ていないと仮定しています。他のJavaプログラム は正常に動作し、SunのJVMはおそらく私の コードよりも安定しています。

私はあなたがその仮定をするべきではないと思います。 JNIを使用しないと、SIGSEGVを引き起こすJavaコードを書くことができないはずです(ただし、それは起こることはわかっていますが)。私の主張は、起こったときに、JVMのバグか(予期せぬことです)、またはいくつかのJNIコードのバグです。あなた自身のコードにJNIがない場合は、そのライブラリを使っていないというわけではないので、それを探してください。私がこの種の問題を以前に見たとき、それは画像操作ライブラリにあった。原因があなた自身のJNIコードにない場合、おそらくバグを修正することはできませんが、あなたはまだそれを回避することができます。

まず、同じプラットフォーム上に代替JVMを用意して、それを再現する必要があります。 one of these alternativesを試すことができます。

再現できない場合は、JVMのバグです。それで、特定のJVMまたはsearch the bug databaseを強制するか、それを再現する方法について知っていることを使用して、おそらく推奨される回避策を入手することができます。 (あなたはそれを再現することができたとしても、多くのJVM実装は、Oracleのホットスポットの実装上の単なる微調整があるので、それはまだJVMのバグかもしれません。)

あなたは代替JVMでそれを再現することができた場合は、ことかもしれない障害あなたはいくつかのJNIバグを持っています。どのライブラリを使用しているのか、どのようなネイティブ・コールを使用しているのかを見てください。場合によっては、同じライブラリまたは代替ライブラリのほぼ同じことを行う代替「純粋なJava」構成またはjarファイルがあります。

幸運を祈る!

+4

+1「あなたはたぶんバグを修正できません」というポスターの質問への回答は、「コード実行時にSegfaultがJVMでどのようにデバッグされるのですか? 「あなたはしません」。 – Raedwald

9

ネイティブコードを持たない限り、以下はほぼ確実に役に立たなくなります。しかし、ここに行く。

  1. 可能なsigsegvの前にブレークポイントを持つJavaデバッガでJavaプログラムを起動します。
  2. javaのprocessidを取得するには、psコマンドを使用します。
  3. GDBは/ usr/libに/ JVM /日-Java6の/ binに/ javaのは
  4. をPROCESSID gdbの 'ハンドル' コマンドは、SIGSEGV
  5. に停止するように設定されていることを確認したブレークポイントからJavaデバッガで継続します。
  6. 爆発を待つ。あなたが本当にJVMがあなた自身の任意のネイティブコードなしSIGSEGVを取る作るために管理している場合

を調査する

  • 使用gdbが、あなたは次の表示されるもののいずれかの意味を理解することは非常に可能性は低い、とあなたができることは、テストケースをバグレポートにプッシュすることです。

  • +1

    JVMの特別なバージョンが必要ですか? Cからは、gdbを使いたいときにデバッグシンボルで再コンパイルする必要がありました。 –

    +0

    私の経験のJVMには、常にバックトレース用のシンボルがあります。あなたが本当に詳細にデバッグするつもりなら、openJDKとデバッグビルドをオフにしてください。 – bmargulies

    2

    私はhttp://www.oracle.com/technetwork/java/javase/crashes-137240.htmlで良いリストを見つけました。私はGC中にクラッシュを取得しているので、私はガベージコレクタの切り替えを試みます。

    シリアルとパラレルGC(64ビットLinuxサーバーでは後者がデフォルト)を切り替えようとしましたが、エラーメッセージがそれに応じて変更されました。

    プロファイラーで新しく解析した結果、最大ヒープサイズが16Gから10Gに減少しました(ヒープの使用率が8Gに平坦化されました)ので、「仮想メモリー」フットプリント(16Gではなく、60G)が大幅に低くなりました。しかし、私はそれが何を意味するのかも知らないし、インターネットは問題ではないと言っている。

    現在のところ、JVMはクライアントモード(-client起動オプションを使用して、デフォルト値-serverを上書きしています)で動作しています。これまでのところ、クラッシュはありませんが、パフォーマンスの影響はかなり大きいようです。

    0

    java crash.use valgrindを引き起こしたcプログラムcarshが無効であることを知り、またスタックサイズをクロスチェックするかどうかを確認してください。

    関連する問題