Debug untuk pemula absolut
Sering kali, kode yang kami tulis sebagai pengembang perangkat lunak tidak selalu sesuai dengan harapan kami. Kadang-kadang itu melakukan sesuatu yang sama sekali berbeda! Ketika hal yang tidak terduga terjadi, tugas berikutnya adalah mencari tahu mengapa, dan meskipun kita mungkin tergoda untuk terus menatap kode kita selama berjam-jam, lebih mudah dan lebih efisien untuk menggunakan alat debugging atau debugger.
Debugger, sayangnya, bukan sesuatu yang dapat secara ajaib mengungkapkan semua masalah atau "bug" dalam kode kami. Debugging berarti menjalankan kode Anda langkah demi langkah di alat penelusuran kesalahan seperti Visual Studio, untuk menemukan titik yang tepat di mana Anda membuat kesalahan pemrograman. Anda kemudian memahami koreksi apa yang perlu Anda lakukan dalam kode dan alat penelusuran kesalahan sering memungkinkan Anda untuk membuat perubahan sementara sehingga Anda dapat terus menjalankan program.
Menggunakan debugger secara efektif juga merupakan keterampilan yang membutuhkan waktu dan praktik untuk belajar tetapi pada akhirnya merupakan tugas mendasar untuk setiap pengembang perangkat lunak. Dalam artikel ini, kami memperkenalkan prinsip inti debugging dan memberikan tips untuk membantu Anda memulai.
Klarifikasi masalah dengan mengajukan pertanyaan yang tepat kepada diri Anda
Ini membantu mengklarifikasi masalah yang Anda alami sebelum mencoba memperbaikinya. Kami berharap Anda sudah mengalami masalah dalam kode Anda, jika tidak, Anda tidak akan berada di sini mencoba mencari tahu cara men-debugnya! Jadi, sebelum memulai debug, pastikan Anda telah mengidentifikasi masalah yang ingin Anda selesaikan:
Apa yang Anda harapkan kode Anda lakukan?
Apa yang terjadi sebagai gantinya?
Jika Anda mengalami kesalahan (pengecualian) saat menjalankan aplikasi, itu bisa menjadi hal yang baik! Pengecualian adalah peristiwa tak terduga yang ditemui saat menjalankan kode, biasanya kesalahan semacam itu. Alat penelusuran kesalahan dapat membawa Anda ke tempat yang tepat dalam kode Anda di mana pengecualian terjadi dan dapat membantu Anda menyelidiki kemungkinan perbaikan.
Jika sesuatu yang lain terjadi, apa gejala masalahnya? Apakah Anda sudah menduga di mana masalah ini terjadi dalam kode Anda? Misalnya, jika kode Anda menampilkan beberapa teks, tetapi teks salah, Anda tahu bahwa data Anda buruk atau kode yang mengatur teks tampilan memiliki semacam bug. Dengan menelusuri kode dalam debugger, Anda dapat memeriksa setiap perubahan pada variabel Anda untuk menemukan kapan dan bagaimana nilai yang salah ditetapkan.
Periksa asumsi Anda
Sebelum Anda menyelidiki bug atau kesalahan, pikirkan asumsi yang membuat Anda mengharapkan hasil tertentu. Asumsi tersembunyi atau tidak dikenal bisa menghalangi identifikasi masalah bahkan ketika Anda melihat tepat penyebab masalah dalam debugger. Anda mungkin memiliki daftar panjang kemungkinan asumsi! Berikut adalah beberapa pertanyaan untuk diajukan kepada diri Anda sendiri untuk menantang asumsi Anda.
Apakah Anda menggunakan API yang tepat (yaitu, objek, fungsi, metode, atau properti yang tepat)? API yang Anda gunakan mungkin tidak melakukan apa yang Anda pikirkan. (Setelah Anda memeriksa panggilan API di debugger, memperbaikinya dapat memerlukan perjalanan ke dokumentasi untuk membantu mengidentifikasi API yang benar.)
Apakah Anda menggunakan API dengan benar? Mungkin Anda menggunakan API yang tepat tetapi tidak menggunakannya dengan cara yang benar.
Apakah kode Anda berisi kesalahan ketik? Beberapa kesalahan ketik, seperti kesalahan ejaan sederhana dari nama variabel, bisa sulit dilihat, terutama ketika bekerja dengan bahasa yang tidak memerlukan variabel untuk dideklarasikan sebelum digunakan.
Apakah Anda membuat perubahan pada kode Anda dan menganggapnya tidak terkait dengan masalah yang Anda lihat?
Apakah Anda mengharapkan objek atau variabel berisi nilai tertentu (atau jenis nilai tertentu) yang berbeda dari apa yang sebenarnya terjadi?
Apakah Anda tahu niat kode? Seringkali lebih sulit untuk men-debug kode orang lain. Jika bukan kode Anda, ada kemungkinan Anda mungkin perlu menghabiskan waktu untuk mempelajari dengan tepat apa yang dilakukan kode sebelum Anda dapat men-debugnya secara efektif.
Saran
Saat menulis kode, mulailah dari yang kecil dan mulailah dengan kode yang berfungsi! (Kode sampel yang baik berguna di sini.) Terkadang, lebih mudah untuk memperbaiki sekumpulan kode besar atau rumit dengan memulai dengan sepotong kecil kode yang menunjukkan tugas inti yang ingin Anda capai. Kemudian, Anda dapat memodifikasi atau menambahkan kode secara bertahap, menguji di setiap titik untuk kesalahan.
Dengan mempertanyakan asumsi Anda, Anda dapat mengurangi waktu yang diperlukan untuk menemukan masalah dalam kode Anda. Anda juga dapat mengurangi waktu yang diperlukan untuk memperbaiki masalah.
Melangkah melalui kode Anda dalam mode penelusuran kesalahan untuk menemukan di mana terjadi masalah
Saat biasanya menjalankan aplikasi, Anda akan melihat kesalahan dan hasil yang salah hanya setelah kode berjalan. Sebuah program mungkin juga mengakhiri secara tak terduga tanpa memberi tahu Anda alasannya.
Saat Anda menjalankan aplikasi dalam debugger, juga disebut mode debugging, debugger secara aktif memantau semua yang terjadi saat program berjalan. Ini juga memungkinkan Anda untuk menjeda aplikasi kapan saja untuk memeriksa statusnya dan kemudian menelusuri kode Anda secara baris demi baris untuk mengamati setiap detail saat itu terjadi.
Di Visual Studio, Anda memasuki mode debugging dengan menggunakan F5 (atau perintah menu Debug>Mulai Debugging atau tombol Mulai Debugging dengan ikon di Toolbar Debug). Jika ada pengecualian yang terjadi, Pembantu Pengecualian Visual Studio membawa Anda ke titik yang tepat di mana pengecualian terjadi dan memberikan informasi bermanfaat lainnya. Untuk informasi selengkapnya tentang cara menangani pengecualian dalam kode Anda, lihat Teknik debugging dan alat.
Jika Anda tidak mendapatkan pengecualian, Anda mungkin memiliki ide yang baik tentang di mana mencari masalah dalam kode Anda. Langkah ini adalah tempat Anda menggunakan titik henti dengan debugger untuk memberi diri Anda kesempatan untuk memeriksa kode Anda dengan lebih hati-hati. Titik henti adalah fitur paling mendasar dan penting dari debugging yang bisa diandalkan. Titik henti menunjukkan di mana Visual Studio harus menjeda kode yang sedang berjalan sehingga Anda dapat melihat nilai variabel, atau perilaku memori, urutan di mana kode berjalan.
Di Visual Studio, Anda dapat dengan cepat mengatur titik henti dengan mengklik di margin kiri di samping baris kode. Atau letakkan kursor pada garis dan tekan F9.
Untuk membantu mengilustrasikan konsep-konsep ini, kami membawa Anda melalui beberapa contoh kode yang sudah memiliki beberapa bug. Kami menggunakan C#, tetapi fitur penelusuran kesalahan berlaku untuk Visual Basic, C++, JavaScript, Python, dan bahasa lain yang didukung. Kode sampel untuk Visual Basic juga disediakan, tetapi cuplikan layar ada di C#.
Membuat aplikasi sampel (dengan beberapa bug)
Selanjutnya, Anda membuat aplikasi yang memiliki beberapa bug.
Anda harus menginstal Visual Studio, dan pengembangan desktop .NET beban kerja yang terinstal.
Jika Anda belum menginstal Visual Studio, buka halaman unduhan Visual Studio untuk menginstalnya secara gratis.
Jika Anda perlu menginstal beban kerja tetapi sudah memiliki Visual Studio, pilih Alat >Dapatkan Alat dan Fitur. Penginstal Visual Studio diluncurkan. Pilih beban kerja pengembangan desktop .NET, lalu pilih Ubah.
Buka Visual Studio.
Pada jendela mulai, pilih Buat proyek baru. Ketik konsol di kotak pencarian, pilih C# atau Visual Basic sebagai bahasa, lalu pilih Console App untuk .NET. Pilih Berikutnya. Ketik ConsoleApp_FirstApp sebagai nama proyek dan pilih Berikutnya.
Jika Anda menggunakan nama proyek yang berbeda, Anda harus memodifikasi nilai namespace agar sesuai dengan nama proyek Anda saat menyalin kode contoh.
Pilih kerangka kerja target yang direkomendasikan atau .NET 8, lalu pilih Buat.
Jika Anda tidak melihat templat proyek Aplikasi Konsol untuk .NET, buka alat >Dapatkan Alat dan Fitur, yang membuka Alat Penginstal Visual Studio. Pilih beban kerja pengembangan desktop .NET , lalu pilih Ubah.
Visual Studio membuat proyek konsol, yang muncul di Penjelajah Solusi di panel kanan.
Di Program.cs (atau Program.vb), ganti semua kode default dengan kode berikut. (Pilih tab bahasa yang benar terlebih dahulu, baik C# atau Visual Basic.)
using System; using System.Collections.Generic; namespace ConsoleApp_FirstApp { class Program { static void Main(string[] args) { Console.WriteLine("Welcome to Galaxy News!"); IterateThroughList(); Console.ReadKey(); } private static void IterateThroughList() { var theGalaxies = new List<Galaxy> { new Galaxy() { Name="Tadpole", MegaLightYears=400, GalaxyType=new GType('S')}, new Galaxy() { Name="Pinwheel", MegaLightYears=25, GalaxyType=new GType('S')}, new Galaxy() { Name="Cartwheel", MegaLightYears=500, GalaxyType=new GType('L')}, new Galaxy() { Name="Small Magellanic Cloud", MegaLightYears=.2, GalaxyType=new GType('I')}, new Galaxy() { Name="Andromeda", MegaLightYears=3, GalaxyType=new GType('S')}, new Galaxy() { Name="Maffei 1", MegaLightYears=11, GalaxyType=new GType('E')} }; foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears + ", " + theGalaxy.GalaxyType); } // Expected Output: // Tadpole 400, Spiral // Pinwheel 25, Spiral // Cartwheel, 500, Lenticular // Small Magellanic Cloud .2, Irregular // Andromeda 3, Spiral // Maffei 1, 11, Elliptical } } public class Galaxy { public string Name { get; set; } public double MegaLightYears { get; set; } public object GalaxyType { get; set; } } public class GType { public GType(char type) { switch(type) { case 'S': MyGType = Type.Spiral; break; case 'E': MyGType = Type.Elliptical; break; case 'l': MyGType = Type.Irregular; break; case 'L': MyGType = Type.Lenticular; break; default: break; } } public object MyGType { get; set; } private enum Type { Spiral, Elliptical, Irregular, Lenticular} } }
Tujuan kami untuk kode ini adalah untuk menampilkan nama galaksi, jarak ke galaksi, dan galaksi jenis semua dalam daftar. Untuk men-debug, penting untuk memahami niat kode. Berikut adalah format untuk satu baris dari daftar yang ingin kita tampilkan dalam output:
nama galaksi , jarak, jenis galaksi .
Menjalankan aplikasi
Tekan F5 atau tombol Mulai Penelusuran Kesalahan di Toolbar Debug, yang terletak di atas editor kode.
Aplikasi dimulai dan tidak ada pengecualian yang ditunjukkan kepada kami oleh debugger. Namun, output yang Anda lihat di jendela konsol bukan yang Anda harapkan. Berikut adalah output yang diharapkan:
Tadpole 400, Spiral
Pinwheel 25, Spiral
Cartwheel, 500, Lenticular
Small Magellanic Cloud .2, Irregular
Andromeda 3, Spiral
Maffei 1, Elliptical
Tapi, Anda melihat output ini sebagai gantinya:
Tadpole 400, ConsoleApp_FirstApp.GType
Pinwheel 25, ConsoleApp_FirstApp.GType
Cartwheel, 500, ConsoleApp_FirstApp.GType
Small Magellanic Cloud .2, ConsoleApp_FirstApp.GType
Andromeda 3, ConsoleApp_FirstApp.GType
Maffei 1, 11, ConsoleApp_FirstApp.GType
Melihat output dan kode kami, kita tahu bahwa GType
adalah nama kelas yang menyimpan jenis galaksi. Kami mencoba menunjukkan jenis galaksi yang sebenarnya (seperti "Spiral"), bukan nama kelas!
Melakukan debug aplikasi
Dengan aplikasi yang masih berjalan, sisipkan titik henti.
Di dalam loop
foreach
, klik kanan di samping metodeConsole.WriteLine
untuk mendapatkan menu konteks dan pilih Breakpoint>Sisipkan Breakpoint dari menu fly-out.foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears + ", " + theGalaxy.GalaxyType); }
Saat Anda mengatur titik henti, titik merah muncul di margin kiri.
Saat Anda melihat masalah dalam output, Anda mulai melakukan debugging dengan melihat kode sebelumnya yang mengatur output dalam debugger.
Pilih ikon Mulai Ulang
di Toolbar Debug (Ctrl + Shift + F5).
Aplikasi berhenti sejenak di titik henti yang Anda tetapkan. Penyorotan kuning menunjukkan tempat debugger dijeda (baris kode kuning belum dijalankan).
Arahkan mouse ke variabel
GalaxyType
di sebelah kanan, lalu, di sebelah kiri ikon kunci pas, perluastheGalaxy.GalaxyType
. Anda melihat bahwaGalaxyType
berisi propertiMyGType
, dan nilai properti telah diatur menjadiSpiral
."Spiral" sebenarnya adalah nilai yang benar yang Anda harapkan untuk dicetak ke konsol! Jadi, ini adalah awal yang baik bahwa Anda dapat mengakses nilai dalam kode ini saat menjalankan aplikasi. Dalam skenario ini, kami menggunakan API yang salah. Mari kita lihat apakah Anda dapat memperbaikinya saat menjalankan kode di debugger.
Dalam kode yang sama, saat masih melakukan debugging, letakkan kursor Anda di akhir
theGalaxy.GalaxyType
dan ubah menjaditheGalaxy.GalaxyType.MyGType
. Meskipun Anda dapat melakukan pengeditan, editor kode menunjukkan kesalahan (garis berlekuk merah). (Di Visual Basic, kesalahan tidak ditampilkan dan bagian kode ini berfungsi.)Tekan F11 (Debug>Melangkah Ke atau tombol Masuk ke di Toolbar Debug) untuk menjalankan baris kode saat ini.
F11 memajukan debugger (dan menjalankan kode) satu pernyataan pada satu waktu. F10 (Step Over) adalah perintah serupa, dan keduanya berguna saat mempelajari cara menggunakan debugger.
Saat Anda mencoba melanjutkan debugger, kotak dialog Hot Reload muncul, menunjukkan bahwa pengeditan tidak dapat dikompilasi.
Kotak dialog Edit dan Lanjutkan muncul, menunjukkan bahwa pengeditan tidak dapat dikompilasi.
Nota
Untuk menelusuri kesalahan kode contoh Visual Basic, lewati beberapa langkah berikutnya hingga Anda diinstruksikan untuk mengklik ikon Mulai Ulang
.
Pilih Edit di kotak pesan Hot Reload atau Edit dan Lanjutkan. Anda melihat pesan kesalahan sekarang di jendela Daftar Kesalahan. Kesalahan menunjukkan bahwa
'object'
tidak berisi definisi untukMyGType
.Meskipun kita mengatur setiap galaksi dengan objek jenis
GType
(yang memiliki propertiMyGType
), debugger tidak mengenali objektheGalaxy
sebagai objek jenisGType
. Apa yang terjadi? Anda ingin memeriksa kode apa pun yang menentukan jenis galaksi. Saat Anda melakukan ini, Anda melihat bahwa kelasGType
jelas memiliki propertiMyGType
, tetapi ada sesuatu yang tidak benar. Pesan kesalahan tentangobject
ternyata adalah petunjuk; untuk penerjemah bahasa, jenis ini nampaknya merupakan objek tipeobject
, bukan objek tipeGType
.Meninjau kode sumber Anda terkait pengaturan jenis galaksi, Anda menemukan properti
GalaxyType
dari kelasGalaxy
didefinisikan sebagaiobject
daripadaGType
.public object GalaxyType { get; set; }
Ubah kode sebelumnya sebagai berikut:
public GType GalaxyType { get; set; }
Pilih Ikon Mulai Ulang
di Toolbar Debug (Ctrl + Shift + F5) untuk mengkompilasi ulang kode dan memulai ulang.
Sekarang, ketika debugger berhenti sejenak di
Console.WriteLine
, Anda dapat mengarahkan mouse ketheGalaxy.GalaxyType.MyGType
, dan melihat bahwa nilai diatur dengan benar.Hapus titik henti dengan mengklik lingkaran titik henti di margin kiri (atau klik kanan dan pilih titik henti >Hapus Titik Henti), lalu tekan F5 untuk melanjutkan.
Aplikasi ini menjalankan dan menampilkan output. Ini terlihat bagus, tapi kau memperhatikan satu hal. Anda mengharapkan galaksi Small Magellanic Cloud muncul sebagai galaksi tidak teratur dalam output konsol, tetapi tidak menunjukkan jenis galaksi sama sekali.
Tadpole 400, Spiral Pinwheel 25, Spiral Cartwheel, 500, Lenticular Small Magellanic Cloud .2, Andromeda 3, Spiral Maffei 1, Elliptical
Atur titik henti pada baris kode ini sebelum pernyataan
switch
(sebelum pernyataanSelect
di Visual Basic).public GType(char type)
Kode ini adalah tempat jenis galaksi diatur, jadi kita ingin meninjau lebih detail.
Pilih Ikon Mulai Ulang
di Toolbar Debug (Ctrl + Shift + F5) untuk memulai ulang.
Debugger berhenti sejenak pada baris kode tempat Anda mengatur breakpoint.
Arahkan mouse ke atas variabel
type
. Anda melihat nilaiS
(mengikuti kode karakter). Anda tertarik pada nilaiI
, karena Anda tahu itu adalah jenis galaksi tak beraturan.Tekan F5 dan arahkan mouse ke atas variabel
type
lagi. Ulangi langkah ini hingga Anda melihat nilaiI
dalam variabeltype
.Sekarang, tekan F11 (Debug>Melangkah Ke).
Tekan F11 hingga Anda berhenti pada baris kode dalam pernyataan
switch
untuk nilai 'I' ( pernyataanSelect
untuk Visual Basic). Di sini, Anda melihat masalah yang jelas yang dihasilkan dari kesalahan ketik. Anda mengharapkan kode melanjutkan ke bagian di manaMyGType
ditetapkan sebagai jenis galaksi tidak teratur, tetapi debugger malah melewati kode ini seluruhnya dan menjeda pada bagiandefault
dari pernyataanswitch
(pernyataanElse
di Visual Basic).Melihat kode, Anda melihat kesalahan ketik dalam pernyataan
case 'l'
. Ini haruscase 'I'
.Pilih
case 'l'
dalam kode dan ganti dengancase 'I'
.Hapus titik henti Anda, lalu pilih tombol Mulai Ulang untuk memulai ulang aplikasi.
Bug diperbaiki sekarang dan Anda melihat Output yang Anda harapkan!
Tekan tombol apa pun untuk menyelesaikan aplikasi.
Ringkasan
Saat Anda melihat masalah, gunakan perintah langkah debugger dan seperti F10 dan F11 untuk menemukan wilayah kode dengan masalah.
Nota
Jika sulit untuk mengidentifikasi wilayah kode tempat masalah terjadi, atur titik henti dalam kode yang berjalan sebelum masalah terjadi, lalu gunakan perintah langkah hingga Anda melihat manifes masalah. Anda juga dapat menggunakan titik pelacakan untuk mencatat pesan pada jendela Output. Dengan melihat pesan yang dicatat (dan memperhatikan pesan mana yang belum dicatat!), Anda sering dapat mengisolasi wilayah kode dengan masalah tersebut. Anda mungkin harus mengulangi proses ini beberapa kali untuk mempersempitnya.
Saat Anda menemukan wilayah kode dengan masalah, gunakan debugger untuk menyelidiki. Untuk menemukan penyebab masalah, periksa kode masalah saat menjalankan aplikasi Anda di debugger:
Periksa variabel dan periksa apakah variabel tersebut berisi jenis nilai yang harus dikandungnya. Jika Anda menemukan nilai tidak valid, cari tahu di mana nilai tidak valid tersebut diatur (untuk menemukan di mana nilai diatur, Anda mungkin perlu memulai ulang debugger, melihat tumpukan panggilan pada ,, atau keduanya).
Periksa apakah aplikasi Anda menjalankan kode yang Anda harapkan. (Misalnya, dalam aplikasi sampel, kami mengharapkan kode untuk pernyataan
switch
untuk mengatur jenis galaksi ke Tidak Teratur, tetapi aplikasi melewati kode karena kesalahan ketik.)
Ujung
Anda menggunakan debugger untuk membantu Anda menemukan bug. Alat debugging dapat menemukan bug untuk Anda hanya jika alat tersebut mengetahui maksud dari kode Anda. Alat hanya dapat mengetahui niat kode Anda jika Anda, pengembang, mengekspresikan niat tersebut. Menulis tes unit begitulah caranya.
Langkah berikutnya
Dalam artikel ini, Anda telah mempelajari beberapa konsep debugging dasar. Selanjutnya, Anda dapat mulai mempelajari lebih lanjut tentang debugger.
Pertama-tama lihat debugger