Strategi debugging klasik kita sejauh ini adalah menaburkan fprintf di sana-sini, menjalankan ulang, lalu memindai output — dan mengulanginya lagi setiap kali tebakan meleset. Debugger MATLAB menghapus siklus tebak-cek itu: eksekusi bisa kita hentikan tepat di baris yang dicurigai, memeriksa variabel apa adanya, lalu melanjutkan baris demi baris sambil menyaksikan nilai berubah. Seluruh perangkatnya berupa perintah db* yang bisa diketik di Command Window atau dipasang lewat Editor. Chapter ini mempraktikkan alurnya dari memasang breakpoint sampai keluar dari mode debug.
Kasus Latihan: Fungsi yang Selalu Galat #
Kita pakai satu kasus yang sama hingga chapter Breakpoints dan Memeriksa Variabel — fungsi jumlah_diskon() berikut punya bug off-by-one klasik: indeks loop berjalan satu langkah terlalu jauh:
function total = jumlah_diskon(harga)
% JUMLAH_DISKON menjumlahkan harga setelah diskon 10 persen.
% total = jumlah_diskon(harga)
diskon = 0.1;
total = 0;
for k = 1:numel(harga) + 1 % bug: +1 melampaui batas
total = total + harga(k) * (1 - diskon);
end
endSaat dipanggil dengan [100 200 300], iterasi ke-4 mengakses harga(4) — elemen yang tidak ada. Galatnya sudah bisa kita baca (chapter sebelumnya); sekarang kita ingin menyaksikan momen sebelum kejatuhan.
Mode K»: Prompt Debug #
Mekanisme di balik layar: dbstop mencatat breakpoint di tabel internal MATLAB; saat eksekusi hendak memasuki baris itu, MATLAB menjeda program, mengaktifkan workspace fungsi yang sedang berjalan, dan mengganti prompt >> menjadi K>>. Di mode ini semua perintah MATLAB tetap sah — menghitung ekspresi, memanggil fungsi, bahkan mengubah nilai variabel — hanya saja efeknya terjadi pada program yang sedang terjeda. Sesi berikut adalah transkripsi Command Window MATLAB; perjalanan lengkapnya dari memasang breakpoint sampai menemukan bug:
>> dbstop in jumlah_diskon at 6
>> totalDiskon = jumlah_diskon([100 200 300])
6 total = total + harga(k) * (1 - diskon);
K>> k
k =
1
K>> dbstep
6 total = total + harga(k) * (1 - diskon);
K>> k
k =
2
K>> total
total =
90
K>> dbcont
6 total = total + harga(k) * (1 - diskon);
K>> k
k =
3
K>> dbcont
6 total = total + harga(k) * (1 - diskon);
K>> k
k =
4
K>> numel(harga)
ans =
3
K>> harga(4)
Index exceeds matrix dimensions.
K>> dbquit
>>Mari kita bedah sesi debug di atas:
dbstop in jumlah_diskon at 6: memasang breakpoint standar di baris 6 — baris yang dicurigai. Bentuk lain yang setara:dbstop in jumlah_diskon(berhenti di baris eksekusi pertama berkas itu).- Pemanggilan fungsi: MATLAB berhenti persis sebelum baris 6 dieksekusi, menampilkan baris sumbernya, lalu menunggu di prompt
K>>. k/total: variabel loop dicetak telanjang —kbernilai 1 pada jeda pertama; setelahdbstepmengeksekusi satu baris, iterasi kedua berjalan dantotalterisi 90 (= 100 × 0.9).dbcont: melanjutkan eksekusi sampai breakpoint berikutnya — karena breakpoint ada di dalam loop, program berhenti lagi di baris 6 setiap iterasi;kmerambat ke 3, lalu 4.numel(harga): membuktikan array hanya berisi 3 elemen, sementaraksudah bernilai 4 — kontradiksi yang menyingkapnumel(harga) + 1di baris 5 sebagai sumber bug.harga(4): galat indexing sengaja dipicu di prompt — dalam mode debug, galat seperti ini hanya dicetak; kita tetap berada diK>>dan tidak terlempar keluar.dbquit: keluar dari mode debug dan membatalkan eksekusi fungsi yang tersisa.
Keluarga Perintah dbstep #
dbstep punya tiga variasi yang mengendalikan seberapa dalam kita mengikuti alur:
| Perintah | Perilaku | Dipakai saat |
|---|---|---|
dbstep | eksekusi satu baris; pemanggilan fungsi dijalankan utuh | mengikuti alur utuh per baris |
dbstep in | seperti dbstep, tetapi masuk ke fungsi yang dipanggil baris itu | curiga fungsi yang dipanggil bermasalah |
dbstep out | jalankan sisa fungsi saat ini, berhenti di titik kembali ke pemanggil | bagian fungsi sudah tidak menarik |
Jika baris berikutnya tidak memanggil fungsi apa pun, dbstep in berperilaku sama dengan dbstep.
Debugger atau printf-Debugging? #
| Situasi | Pilihan | Alasan |
|---|---|---|
| perlu nilai variabel di tengah alur, sekali dua kali | debugger | tanpa mengubah kode, tanpa menjalankan ulang |
| loop ribuan iterasi, curiganya satu kondisi | conditional breakpoint (chapter berikut) | dbcont seribu kali bukan solusi |
| perlu jejak lengkap untuk dianalisis offline / log produksi | fprintf | debugger berhenti interaktif, log bisa dibaca ulang |
| bug hanya muncul di data pengguna | fprintf + berkas log | sesi interaktif di mesin pengguna tidak praktis |
Keduanya bukan saingan: pola industri yang umum adalah fprintf untuk jejak, debugger untuk bedah mendalam saat jejak menunjukkan titik panik.
Editor Breakpoint dan Alur Kerja #
Di Editor MATLAB, mengklik kolom nomor baris memasang breakpoint merah — padanan visual dbstop in <berkas> at <N>. Saat berjalan dan berhenti, baris aktif ditandai panah hijau; tombol Step/Step In/Step Out/Continue di toolbar memanggil dbstep/dbstep in/dbstep out/dbcont tanpa mengetik. Alur kerja lengkapnya:
Bagian yang Bisa Diverifikasi Batch #
Sesi K>> adalah sesi interaktif — dbstep, dbcont, dan dbquit hanya bermakna ketika eksekusi sedang terjeda, dan ketiganya menolak bekerja bila dipanggil dari berkas batch. Sebaliknya, dbtype, dbstop, dbstatus, dan dbclear murni mengelola tabel breakpoint sehingga aman diuji otomatis. Berkas contoh.m memverifikasi bagian tersebut:
% contoh.m — inti alurnya
dbtype('jumlah_diskon', '3:7');
dbstop in jumlah_diskon at 5;
st = dbstatus();
fprintf('dbstatus: %d breakpoint aktif\n', numel(st));
dbclear in jumlah_diskon at 5;
fprintf('dbstatus setelah dbclear: %d breakpoint aktif\n', numel(dbstatus()));Output yang Dihasilkan:
== dbtype: tampilkan berkas dengan nomor baris ==
3 % total = jumlah_diskon(harga)
4
5 diskon = 0.1;
6 total = 0;
7 for k = 1:numel(harga) + 1 % bug: +1 melampaui batasOutput yang Dihasilkan (lanjutan):
== dbstop + dbstatus: pasang lalu daftar breakpoint ==
dbstatus: 1 breakpoint aktif
fungsi : jumlah_diskon
baris : 5
Panggil jumlah_diskon([100 200 300]) dari Command Window
untuk berhenti di baris 5 dan masuk mode K>>.
== dbclear: hapus breakpoint ==
dbstatus setelah dbclear: 0 breakpoint aktif
SELESAI — perintah interaktif (dbcont, dbstep, dbquit)
membutuhkan sesi debug K>> yang dijelaskan di materi.Baris 3 % total = jumlah_diskon(harga) dst. adalah keluaran dbtype — nomor baris diikuti teks sumbernya, tepat seperti tampilan MATLAB.
Mari kita bedah baris-baris kode di atas:
- Baris 2 (
dbtype('jumlah_diskon', '3:7')): mencetak berkas sumber dengan nomor baris — cara cepat memastikan nomor baris yang akan diberi breakpoint sesuai dengan berkas yang benar-benar dimuat (teks lengkap perintah interaktifnya:dbtype jumlah_diskon 3:7). - Baris 4 (
dbstop in jumlah_diskon at 5): memasang breakpoint di baris 5 — loopfor— tanpa menjalankan fungsinya; eksekusi berkas ini sama sekali tidak berhenti karena fungsi tidak dipanggil. - Baris 5-6 (
st = dbstatus() ...):dbstatus()mengembalikan struct array; di MATLAB setiap elemennya memuat fieldname,file, danline(vektor nomor baris), plus fieldexpression/conduntuk breakpoint bersyarat. - Baris 8 (
dbclear in jumlah_diskon at 5): menghapus breakpoint spesifik itu;dbclear allmenghapus semuanya sekaligus.
Berkas contoh.m pada bagian Berkas Sumber menjalankan urutan lengkap di atas dan selepasnya mengingatkan bahwa dbcont, dbstep, dan dbquit membutuhkan sesi interaktif.
Ringkasan #
Debugger mengubah debugging dari menebak menjadi mengamati: dbstop in <berkas> at <N> menjeda eksekusi sebelum baris curigaan, prompt K>> membuka workspace fungsi untuk diperiksa, dbstep/dbstep in/dbstep out mengatur kedalaman langkah, dbcont melepas program sampai breakpoint berikutnya, dan dbquit menutup sesi. dbstatus mendaftar breakpoint aktif, dbtype mencetak berkas bernomor, dbclear membersihkan. Ketika jeda sederhana belum cukup — misalnya bug baru muncul pada iterasi tertentu — chapter berikutnya memperkenalkan breakpoint bersyarat dan error breakpoint.