Debug dengan jdb

T: Bagaimana Anda menggunakan jdb (termasuk dalam paket JDK 1.2) secara efektif untuk men-debug program Java?

Saya sudah mencoba berkali-kali, tetapi saya hanya berhasil memuat file kelas ke jdb; Saya tidak bisa men-debugnya. The helpperintah tidak banyak digunakan.

J: Anda mengajukan pertanyaan yang menarik. Sejujurnya, saya tidak pernah menggunakannya jdb. Saya selalu menggunakan debugger yang disediakan oleh lingkungan IDE saya. Jadi untuk menjawab pertanyaan Anda, saya harus melakukan sedikit riset sendiri.

Ternyata Sun menganggap jdbbukti konsep untuk Java Debugger API. Java Debugger API memungkinkan kita untuk benar-benar mengintip ke dalam runtime dan men-debug kode kita. Ini jdbhanyalah salah satu implementasi debugger yang menggunakan API. Dibandingkan dengan debugger visual yang saya kenal (ya, saya rasa saya pengecut), ini bukan debugger termudah untuk digunakan - meskipun mirip dengan debugger baris perintah lainnya, seperti gdb.

Bagaimanapun, untuk pertanyaan Anda. Sebelum mencoba men-debug kode Anda, pastikan untuk menggunakan -gopsi ini saat mengompilasi kelas Anda. Opsi ini memberi tahu kompiler untuk menyertakan informasi debugging dalam file kelas Anda.

Mari tentukan kelas yang dibuat untuk pengujian:

public class TestMe {private int int_value; private String string_value; public static void main (String [] args) {TestMe testMe = new TestMe (); testMe.setInt_value (1); testMe.setString_value ("test"); int integer = testMe.getInt_value (); String string = testMe.getString_value (); String toString = testMe.toString (); } TestMe publik () {} public int getInt_value () {return int_value; } string publik getString_value () {return string_value; } public void setInt_value (nilai int) {int_value = nilai; } public void setString_value (Nilai string) {string_value = value; } public String toString () {return "String value:" + string_value + "int value:" + int_value; }}

Mulai debugger:

> jdb TestMe 

Anda harus melihat:

> Menginisialisasi jdb ...> 0xaa: class 

Mari kita lihat beberapa perintah dasar. Untuk menyetel breakpoint, kita perlu mengetahui nomor baris atau nama metode dari tempat yang ingin kita hentikan. Untuk mendapatkan daftar metode, cukup gunakan methodsperintah:

> metode TestMe void main (java.lang.String []) void () int getInt_value () java.lang.String getString_value () void setInt_value (int) void setString_value (java.lang.String) java.lang.String toString ( ) 

Menyetel breakpoint itu sederhana. Gunakan sintaks berikut:

mampir. [] 

Atau:

berhenti di: 

Kita harus mulai men-debug di awal metode utama:

> berhenti di TestMe.main Breakpoint yang disetel di javaworld.TestMe.main 

Sekarang kita memiliki breakpoint, kita bisa memulai eksekusi. Untuk menjalankan breakpoint, cukup gunakan runperintah:

> jalankan jalankan javaworld.TestMe berjalan ... utama [1] Breakpoint hit: javaworld.TestMe.main (TestMe: 10) 

Pada titik ini, debugger menghentikan eksekusi pada baris pertama dari metode utama. Perhatikan bahwa kursor telah berubah untuk mencerminkan metode yang kita gunakan saat ini.

The listperintah akan menampilkan kode di breakpoint. Tanda panah menunjukkan tempat debugger menghentikan eksekusi.

main [1] daftar 6 private String string_value; 7 8 public static void main (String [] args) 9 {10 => TestMe testMe = new TestMe (); 11 testMe.setInt_value (1); 12 testMe.setString_value ("test"); 13 14 int integer = testMe.getInt_value (); utama [1]

Selanjutnya, kita akan stepmembahas beberapa baris kode dan melihat apa yang berubah:

utama [1] langkah utama [1] Breakpoint hit: javaworld.TestMe. (TestMe: 20) utama [1] penduduk setempat Argumen metode: Variabel lokal: ini = Nilai string: null nilai int: 0 utama [1] daftar 16 17 String toString = testMe.toString (); 18} 19 20 => TestMe publik () 21 {22} 23 24 public int getInt_value () main [1] langkah utama [1] Breakpoint hit: java.lang.Object. (Object: 27) main [1] list Tidak dapat menemukan Object.java main [1] langkah utama [1] Breakpoint hit: javaworld.TestMe. (TestMe: 22) utama [1] daftar 18} 19 20 publik TestMe () 21 {22 =>} 23 24 int publik getInt_value () 25 {26 return int_value; main [1] langkah utama [1] Breakpoint hit: javaworld.TestMe.main (TestMe: 10) main [1] daftar 6 private String string_value; 7 8 public static void main (String [] args) 9 {10 => TestMe testMe = new TestMe (); 11 testMe.setInt_value (1); 12 testMe.setString_value ("test");13 14 int integer = testMe.getInt_value (); main [1] langkah utama [1] Breakpoint hit: javaworld.TestMe.main (TestMe: 11) main [1] daftar 7 8 public static void main (String [] args) 9 {10 TestMe testMe = new TestMe (); 11 => testMe.setInt_value (1); 12 testMe.setString_value ("test"); 13 14 int integer = testMe.getInt_value (); 15 String string = testMe.getString_value (); main [1] penduduk lokal Argumen metode: Variabel lokal: args = testMe = Nilai string: null nilai int: 0main [1] penduduk lokal Argumen metode: Variabel lokal: args = testMe = Nilai string: null nilai int: 0main [1] penduduk lokal Argumen metode: Variabel lokal: args = testMe = Nilai string: null nilai int: 0

Setelah masing-masing step, saya memanggil listperintah untuk melihat di mana saya berada di kode. Nilai kembali dari perintah mencantumkan nomor baris, tetapi entah bagaimana itu tidak terlalu membantu saya.

Seperti yang kita steplihat, metode utama sedang membangun sebuah TestMeinstance. Setiap langkah membawa kita melalui konstruktor dan akhirnya kembali ke metode utama. The localsperintah daftar semua variabel lokal terlihat di tumpukan saat ini. Kami melihat bahwa pada titik ini dalam metode utama hanya ada dua variabel lokal: argsdan testMe.

Dengan menggunakan step, kita bisa masuk ke salah satu metode untuk melihat apa yang sedang terjadi. Saat kami menggabungkan stepdengan localsperintah, kami dapat melihat variabel kami:

utama [1] langkah utama [1] Breakpoint hit: javaworld.TestMe.setInt_value (TestMe: 36) main [1] daftar 32} 33 34 public void setInt_value (int value) 35 {36 => int_value = value; 37} 38 39 public void setString_value (nilai string) 40 {utama [1] penduduk setempat Metode argumen: Variabel lokal: nilai = 1 ini = Nilai string: null nilai int: 0

Jika kita stepsekali lagi, kita berakhir di setInt_value()metode. Jika kita stepdua kali lagi, metode akan mengatur int_valueanggota menjadi 1dan kembali. (Untuk memeriksa untuk melihat apakah metode menyetel nilainya, gunakan localsperintah.)

Tentu saja, ketika kita step, kita tidak akan selalu ingin menelusuri setiap metode yang kita temui. Beberapa panggilan metode dapat bersarang sangat dalam. Jika kami dipaksa untuk menelusuri seluruh hierarki, kami mungkin tidak akan pernah menyelesaikannya. Untungnya, jdbada cara untuk mengeksekusi metode tanpa menelusuri metode itu: nextperintah.

jdbjuga menyediakan beberapa stepperintah lainnya . The stepiperintah mengeksekusi instruksi saat ini. Dengan kata lain, kode di =>akan dieksekusi tetapi baris saat ini tidak akan maju ke instruksi berikutnya. Anda dapat memanggil stepijutaan kali, tetapi perintah yang =>ditampilkan listtidak akan bergerak.

jdbjuga memberikan step upperintah. The step uppanggilan mengeksekusi sampai metode saat ini kembali ke pemanggil nya. Sederhananya, stepper ini menjalankan metode dan tidak ada yang lain. Ambil segmen kode berikut sebagai contoh:

int integer = testMe.getInt_value (); 

Jika ini adalah baris kami saat ini dan kami jalankan step up, getInt_value()metode ini akan dijalankan. Namun, hanya itu yang akan terjadi. Nilai kembali tidak akan disetel ke integer.

jdbjuga memungkinkan kita untuk mengatur beberapa breakpoint. Untuk beralih dari satu breakpoint langsung ke breakpoint berikutnya, jdbberikan contperintah.

Terakhir, ada kalanya kita ingin melihat semua anggota sebuah instance atau kelas. Untungnya, jdbmenyediakan perintah dumpdan print:

main [1] dump TestMe TestMe = 0xa9: class (javaworld.TestMe) {superclass = 0x2: class (java.lang.Object) loader = (sun.misc.Launcher $ AppClassLoader) 0xaa} main [1] print TestMe TestMe = 0xa9: class (javaworld.TestMe) main [1] dump testMe testMe = (javaworld.TestMe) 0xec {private java.lang.String string_value = test private int int_value = 1} main [1] print testMe testMe = Nilai string: test nilai int: 1 

Saat Anda menjalankan dumpatau printdi kelas, Anda mendapatkan informasi kelas, yang mencakup informasi superclass dan loader. Saat Anda menjalankan dumpdan printpada sebuah instance, Anda mendapatkan informasi instance, seperti anggota data dan nilainya saat ini.

jdbjuga memberikan perintah untuk turun dan kotor di utas dan tumpukan. Namun, perintah ini benar-benar di luar lingkup jdbintro.

Satu poin terakhir: Anda mungkin bertanya, "Bagaimana Anda menggunakan secara efektif jdb?" Efektivitas penggunaan akan tergantung pada tingkat kenyamanan Anda dengan jdb. Saat pertama kali Anda menggunakan jdb, perintah yang paling penting adalah help. The helpdaftar perintah setiap perintah dan menyediakan beberapa informasi dasar untuk membantu Anda memulai. Setelah Anda helpmenguasai perintah, Anda akan menemukan diri Anda menggunakan perintah yang mengatur breakpoint, bersama dengan stepdan list. Kombinasi dari perintah tersebut akan memungkinkan Anda untuk mulai menggunakan jdb. step, list, step, list... akan membantu Anda cepat menemukan kode yang membom keluar pada Anda.

Pelajari lebih lanjut tentang topik ini

  • "Debugging Bahasa Java", dari Situs web Postech ME

    //mech.postech.ac.kr/Java/java.sun.com/products/JDK/debugging/

  • " jdbThe Java Debugger," dari Referensi Pengembang Java, Mike Cohen, dkk. (Sams.net Publishing, 1996)

    //docs.online.bg/PROGRAMMING/JAVA_Developers_Reference/ch15.htm

Artikel ini, "Debug dengan jdb" awalnya diterbitkan oleh JavaWorld.