問題タブ [jdb]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 内部で Java デバッグが実際にどのように機能するかを理解する
私の質問はデバッグに関連しています-特にJava/jvmで。
Java でのデバッグが内部でどのように機能するかを知りたいです。
- Java ソースコードに設定されたブレークポイントを、現在実行中のバイト
jdb/jvm
コードに一致させる方法を教えてください。
誰かが上記の質問に答えたり、jvm のデバッグに関連するドキュメント/仕様とその仕組みを教えてくれませんか?
name-mangling - JDB の内部および無名クラスのメソッドにブレークポイントを設定する
プログラムで JDB を操作しようとしています。正常なデバッガとは異なり、JDB はソース ファイル名の代わりにクラス名を使用してソース コードを参照します。バイトコードを単一のファイルではなく複数の .class ファイルに格納することに関連していると思います(-g
フラグを使用してコンパイルすると、ソースファイルへの参照が生成されると予想されますが、物事を簡単にするのはJavaの方法ではありません... )
JDB がクラスを参照する場合、通常は文字列操作をいくつか行い、ソース ファイル名を調べて、どのソース ファイルが関連するクラスを宣言しているかを判断します。ブレークポイントのクラス名を指定する必要がある場合は、ファイルを読み取ってパッケージ名を取得し、そのファイル名をクラス名として使用して、その方法で完全なクラス名を生成できます。これらの2つのケースは、私がそれらを機能させました。
問題は内部クラスと匿名クラスから始まります。それらは独自のクラス ファイルに存在し、それらの名前はそれらを含むクラスのマングル バージョンです。そこにブレークポイントを設定するには、マングルされた名前が必要です。
例-これはMain.java
(+行番号)です:
を使用してコンパイルしjavac -g Main.java
、 を取得Main.class
しMain$1.class
ました。私は走っていjdb
ます:
(その部分をロードする必要がありました。Main.class
そうしないと、すべてのブレークポイント設定の試行に対して、「クラスがロードされた後に設定されます。 」と表示されます。)
8 行目にブレークポイントを設定すると、正しく動作します。
匿名クラスの一部である 5 行目にブレークポイントを設定すると、エラーが発生します。
行 5 には明らかにコードが含まれています。問題は、コードが にコンパイルされていないことです。コードは にコンパイルされMain.class
てMain$1.class
いるため、代わりに次のように記述する必要があります。
さて、Java がバイトコードを .class ファイルに分割する方法は決定論的であり、この単純な例では、人間の目で調べると、何がどこにあるのかを簡単に把握できますが、マングルされたクラス名をプログラムで把握する方法が必要です( VimScript を使用) 実際のソース ファイルの場合。ソース ファイルを構文的に分析し、どれが複雑すぎるのかを突き止めようとしています。もっと簡単な方法があるはずです。
おそらく、.class ファイルからその情報を抽出するか、それについて JDB に質問するか、JDB に、正常な言語の正常なデバッガーのようにソース ファイル名を使用させることさえできます...
java - jdb でデバッグするときに Android アプリケーションを一時停止して、キャッチポイントを設定できるようにする
エミュレーターで開発者ツールを使用して、アプリケーションを開始する前にデバッガーを待機させますが、jdb がアタッチされた直後に、望ましくないまだ処理された例外がアプリケーションに発生します。jdb が停止しないため、この例外をデバッグできません。catch java.lang.Exception
したがって、アプリケーションを続行する前に設定できる必要があります。どうやってやるの?
私はjdbを次のように使用します:
scala - jdb と sbt を使用してブレークポイントを設定できない
sbt にアタッチするときに、ブレークポイントを jdb でヒットさせるのに問題があります。次の scala コードを書き、test.scala というファイルに入れました。
次に、test.scala を含むディレクトリで sbt を起動し、プログラムを 1 回実行して、すべてが正常に機能していることを確認します。
別のターミナル (同じディレクトリ) で、jdb を起動します。
次に、sbt で「run」と入力すると、プログラムは停止せずに完了します。ただし、jdb はブレークポイントを設定できるほどコードについて十分に認識しているようです。もう一度実行して、「サスペンド」で jdb のすべてのスレッドを中断すると、「スレッド」の出力を確認できます。
テストを実行するスレッドを選択します。
そのため、jdb はコードの行番号だけでなく、クラスとメソッドの名前も認識しているように見えますが、ブレークポイントで停止しません。存在しない関数にブレークポイントを設定すると、次のようになります。
test.foo のブレークポイントを理解していることを示していますか? test.foo または test$.foo に対して stop in、on、または at のいずれを使用するかは問題ではありません。他の質問をグーグルで検索すると、メソッド名が間違っている可能性が最も高いようですが、その場合はどうなるかわかりません。
Eclipse や IntelliJ に切り替えることなく、既存の開発環境に簡単なデバッグを追加できることを望んでいました。私が間違っていること、またはまったくしていないことはありますか、またはこれを機能させる簡単な方法はありませんか?
バージョン情報:
- Linux: Ubuntu 12.04.4 LTS (正確)
- jdb: 1.6 (Java SE バージョン 1.6.0_31)
- sbt: 0.13.5
- スカラ: 2.10.4
- Java バージョン「1.6.0_31」
- OpenJDK ランタイム環境 (IcedTea6 1.13.3) (6b31-1.13.3-1ubuntu1~0.12.04.2)
- OpenJDK 64 ビット サーバー VM (ビルド 23.25-b01、混合モード)