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:

matlab
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
end

Saat 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:

text
>> 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:

  1. 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).
  2. Pemanggilan fungsi: MATLAB berhenti persis sebelum baris 6 dieksekusi, menampilkan baris sumbernya, lalu menunggu di prompt K>>.
  3. k / total: variabel loop dicetak telanjang — k bernilai 1 pada jeda pertama; setelah dbstep mengeksekusi satu baris, iterasi kedua berjalan dan total terisi 90 (= 100 × 0.9).
  4. dbcont: melanjutkan eksekusi sampai breakpoint berikutnya — karena breakpoint ada di dalam loop, program berhenti lagi di baris 6 setiap iterasi; k merambat ke 3, lalu 4.
  5. numel(harga): membuktikan array hanya berisi 3 elemen, sementara k sudah bernilai 4 — kontradiksi yang menyingkap numel(harga) + 1 di baris 5 sebagai sumber bug.
  6. harga(4): galat indexing sengaja dipicu di prompt — dalam mode debug, galat seperti ini hanya dicetak; kita tetap berada di K>> dan tidak terlempar keluar.
  7. 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:

PerintahPerilakuDipakai saat
dbstepeksekusi satu baris; pemanggilan fungsi dijalankan utuhmengikuti alur utuh per baris
dbstep inseperti dbstep, tetapi masuk ke fungsi yang dipanggil baris itucuriga fungsi yang dipanggil bermasalah
dbstep outjalankan sisa fungsi saat ini, berhenti di titik kembali ke pemanggilbagian fungsi sudah tidak menarik

Jika baris berikutnya tidak memanggil fungsi apa pun, dbstep in berperilaku sama dengan dbstep.

Debugger atau printf-Debugging? #

SituasiPilihanAlasan
perlu nilai variabel di tengah alur, sekali dua kalidebuggertanpa mengubah kode, tanpa menjalankan ulang
loop ribuan iterasi, curiganya satu kondisiconditional breakpoint (chapter berikut)dbcont seribu kali bukan solusi
perlu jejak lengkap untuk dianalisis offline / log produksifprintfdebugger berhenti interaktif, log bisa dibaca ulang
bug hanya muncul di data penggunafprintf + berkas logsesi 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:

matlab
% 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:

text
== 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 batas

Output yang Dihasilkan (lanjutan):

text
== 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:

  1. 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).
  2. Baris 4 (dbstop in jumlah_diskon at 5): memasang breakpoint di baris 5 — loop for — tanpa menjalankan fungsinya; eksekusi berkas ini sama sekali tidak berhenti karena fungsi tidak dipanggil.
  3. Baris 5-6 (st = dbstatus() ...): dbstatus() mengembalikan struct array; di MATLAB setiap elemennya memuat field name, file, dan line (vektor nomor baris), plus field expression/cond untuk breakpoint bersyarat.
  4. Baris 8 (dbclear in jumlah_diskon at 5): menghapus breakpoint spesifik itu; dbclear all menghapus 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.