Trik Debugging IntelliJ

1. Ikhtisar

Dalam tutorial ini, kita akan melihat beberapa fasilitas debugging IntelliJ tingkat lanjut .

Diasumsikan bahwa dasar-dasar debugging sudah diketahui (cara memulai debugging, Step Into , Step Over actions, dll). Jika tidak, silakan merujuk ke artikel ini untuk detail lebih lanjut tentang itu.

2. Langkah Cerdas Ke

Ada situasi ketika beberapa metode dipanggil pada satu baris kode sumber, seperti doJob (getArg1 (), getArg2 ()) . Jika kita memanggil tindakan Langkah Ke (F7), debugger masuk ke metode dalam urutan yang digunakan oleh JVM untuk evaluasi: getArg1 - getArg2 - doJob .

Namun, kami mungkin ingin melewati semua pemanggilan perantara dan melanjutkan ke metode target secara langsung . Smart Step Into action memungkinkan melakukan itu.

Ini terikat ke Shift + F7 secara default dan terlihat seperti ini saat dipanggil:

Sekarang kita dapat memilih metode target untuk melanjutkan. Juga, perhatikan bahwa IntelliJ selalu menempatkan metode terluar di urutan teratas daftar. Itu berarti kita dapat dengan cepat pergi ke sana dengan menekan Shift + F7 | Masuk .

3. Jatuhkan Bingkai

Kami mungkin menyadari bahwa beberapa pemrosesan yang kami minati telah terjadi (misalnya, kalkulasi argumen metode saat ini). Dalam kasus ini, dimungkinkan untuk menjatuhkan kerangka tumpukan JVM saat ini untuk memprosesnya kembali.

Pertimbangkan situasi berikut:

Misalkan kita tertarik untuk men- debug pemrosesan getArg1 , jadi kita menjatuhkan frame saat ini ( metode doJob ):

Sekarang kita berada di metode sebelumnya :

Namun, argumen panggilan sudah dihitung pada titik ini, jadi, kita juga perlu menghapus frame saat ini :

Sekarang kita dapat menjalankan kembali pemrosesan dengan memanggil Step Into .

4. Titik Henti Lapangan

Terkadang bidang non-privat dimodifikasi oleh kelas lain, tidak melalui penyetel tetapi secara langsung (hal ini terjadi pada pustaka pihak ketiga di mana kami tidak mengontrol kode sumbernya).

Dalam situasi seperti itu, mungkin sulit untuk memahami kapan modifikasi dilakukan. IntelliJ memungkinkan membuat breakpoint tingkat bidang untuk melacaknya.

Mereka disetel seperti biasa - klik kiri pada selokan editor kiri di baris bidang. Setelah itu, dimungkinkan untuk membuka properti breakpoint (klik kanan pada tanda breakpoint) dan konfigurasikan jika kita tertarik pada bidang membaca, menulis, atau keduanya :

5. Penebangan Breakpoints

Terkadang kita tahu bahwa ada kondisi balapan di aplikasi tapi tidak tahu persisnya dimana. Mungkin sulit untuk memahaminya, terutama saat bekerja dengan kode baru.

Kita dapat menambahkan pernyataan debugging ke sumber program kita. Namun, tidak ada kemampuan seperti itu untuk pustaka pihak ketiga.

IDE dapat membantu di sini - ini memungkinkan pengaturan breakpoint yang tidak memblokir eksekusi setelah ditemukan, tetapi menghasilkan pernyataan logging .

Perhatikan contoh berikut:

public static void main(String[] args) { ThreadLocalRandom random = ThreadLocalRandom.current(); int count = 0; for (int i = 0; i < 5; i++) { if (isInterested(random.nextInt(10))) { count++; } } System.out.printf("Found %d interested values%n", count); } private static boolean isInterested(int i) { return i % 2 == 0; }

Misalkan kita tertarik untuk mencatat parameter panggilan isInterested yang sebenarnya .

Mari buat breakpoint non-pemblokiran dalam metode target ( Shift + klik kiri pada selokan editor kiri). Setelah itu mari buka propertinya (klik kanan pada breakpoint) dan tentukan ekspresi target ke log :

Saat menjalankan aplikasi (perhatikan bahwa masih perlu menggunakan mode Debug), kita akan melihat hasilnya:

isInterested(1) isInterested(4) isInterested(3) isInterested(1) isInterested(6) Found 2 interested values

6. Titik Pemutusan Bersyarat

Kami mungkin memiliki situasi di mana metode tertentu dipanggil dari beberapa utas secara bersamaan dan kami perlu men-debug pemrosesan hanya untuk argumen tertentu.

IntelliJ memungkinkan pembuatan breakpoint yang menjeda eksekusi hanya jika kondisi yang ditentukan pengguna terpenuhi .

Berikut contoh yang menggunakan kode sumber di atas:

Sekarang debugger akan berhenti pada breakpoint hanya jika argumen yang diberikan lebih besar dari 3.

7. Tanda Objek

Ini adalah fitur IntelliJ yang paling kuat dan paling tidak dikenal. Intinya cukup sederhana - kita dapat melampirkan label khusus ke objek JVM .

Mari kita lihat aplikasi yang akan kita gunakan untuk mendemonstrasikannya:

public class Test { public static void main(String[] args) { Collection tasks = Arrays.asList(new Task(), new Task()); tasks.forEach(task -> new Thread(task).start()); } private static void mayBeAdd(Collection holder) { int i = ThreadLocalRandom.current().nextInt(10); if (i % 3 == 0) { holder.add(i); } } private static class Task implements Runnable { private final Collection holder = new ArrayList(); @Override public void run() { for (int i = 0; i < 20; i++) { mayBeAdd(holder); } } } }

7.1. Membuat Tanda

Sebuah objek dapat ditandai saat aplikasi dihentikan pada breakpoint dan target dapat dijangkau dari tumpukan bingkai.

Pilih itu, tekan F11 ( Tandai tindakan Objek ) dan tentukan nama target:

7.2. Lihat Marks

Sekarang kita dapat melihat label objek khusus kita bahkan di bagian lain aplikasi:

Hal yang keren adalah bahwa meskipun objek yang ditandai tidak dapat dijangkau dari tumpukan frame saat ini, kita masih dapat melihat statusnya - buka dialog Evaluate Expression atau tambahkan jam tangan baru dan mulailah mengetik nama tanda tersebut.

IntelliJ menawarkan untuk melengkapinya dengan akhiran _DebugLabel :

Saat kami mengevaluasinya, status objek target ditampilkan:

7.3. Ditandai sebagai Kondisi

Ini juga memungkinkan untuk menggunakan tanda dalam kondisi breakpoint:

8. Kesimpulan

Kami memeriksa sejumlah teknik yang sangat meningkatkan produktivitas saat men-debug aplikasi multi-utas.

Ini biasanya merupakan tugas yang menantang, dan kami tidak dapat mengecilkan pentingnya bantuan perkakas di sini.