Debug untuk pemula absolut
Tanpa gagal, kode yang kami tulis sebagai pengembang perangkat lunak tidak selalu melakukan apa yang kami harapkan untuk dilakukan. 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, bukanlah sesuatu yang dapat secara ajaib mengungkapkan semua masalah atau "bug" dalam kode kami. Penelusuran kesalahan berarti menjalankan kode Anda langkah demi langkah dalam 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 penelusuran kesalahan dan memberikan tips untuk memulai.
Klarifikasi masalah dengan mengajukan pertanyaan yang tepat kepada diri sendiri
Ini membantu mengklarifikasi masalah yang Anda alami sebelum mencoba memperbaikinya. Kami berharap Bahwa Anda sudah mengalami masalah dalam kode Anda, jika tidak, Anda tidak akan berada di sini mencoba mencari tahu cara men-debugnya! Jadi, sebelum memulai penelusuran kesalahan, pastikan Anda telah mengidentifikasi masalah yang coba Anda selesaikan:
Apa yang Anda harapkan untuk dilakukan kode Anda?
Apa yang terjadi sebaliknya?
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 mencurigai di mana masalah ini terjadi dalam kode Anda? Misalnya, jika kode Anda menampilkan beberapa teks, tetapi teksnya 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 seberapa salah nilai 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 ditanyakan pada diri 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 Menurut Anda lakukan. (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.
Tip
Saat menulis kode, mulailah dari yang kecil dan mulailah dengan kode yang berfungsi! (Kode sampel yang baik sangat membantu 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.
Menelusuri kode Anda dalam mode penelusuran kesalahan untuk menemukan di mana masalah terjadi
Saat Anda biasanya menjalankan aplikasi, Anda akan melihat kesalahan dan hasil yang salah hanya setelah kode berjalan. Sebuah program mungkin juga berakhir 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 melangkah melalui baris demi baris kode Anda untuk menonton setiap detail seperti yang terjadi.
Di Visual Studio, Anda memasukkan mode penelusuran kesalahan dengan menggunakan F5 (atau perintah menu Debug>Mulai Debugging atau tombol Mulai Penelusuran Kesalahan 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 lebih lanjut tentang cara menangani pengecualian dalam kode Anda, lihat Teknik dan alat penelusuran kesalahan.
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 dasar dan esensial dari penelusuran kesalahan yang andal. 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 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 beban kerja pengembangan desktop .NET terinstal.
Jika Anda belum menginstal Visual Studio, buka halaman pengunduhan Visual Studio untuk menginstalnya secara gratis.
Jika Anda perlu menginstal beban kerja tetapi sudah memiliki Visual Studio, pilih Alat>Dapatkan Alat dan Fitur. Alat Penginstal Visual Studio diluncurkan. Pilih beban kerja Pengembangan desktop .NET, lalu pilih Ubah.
Buka Visual Studio.
Dari jendela awal, pilih Buat proyek baru. Ketik konsol di kotak pencarian, pilih C# atau Visual Basic sebagai bahasa, lalu pilih Aplikasi Konsol untuk .NET. Pilih Berikutnya. Ketik nama proyek seperti ConsoleApp_FirstApp dan pilih Berikutnya.
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} } }
Niat 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!
Men-debug aplikasi
Dengan aplikasi yang masih berjalan, sisipkan titik henti.
Klik kanan di
Console.WriteLine
samping metode untuk mendapatkan menu konteks dan pilih Breakpoint>Insert 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 menelusuri kesalahan dengan melihat kode sebelumnya yang mengatur output dalam debugger.
Pilih tombol 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 atas variabel
GalaxyType
di sebelah kanan, lalu, ke kiri ikon kunci inggris, perluastheGalaxy.GalaxyType
. Anda melihat bahwaGalaxyType
berisi propertiMyGType
, dan nilai properti diatur keSpiral
."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 men-debug, letakkan kursor Anda di akhir
theGalaxy.GalaxyType
dan ubah menjaditheGalaxy.GalaxyType.MyGType
. Meskipun Anda dapat membuat perubahan, editor kode menunjukkan kesalahan yang menunjukkan bahwa itu tidak dapat mengkompilasi kode ini. (Di Visual Basic, kesalahan tidak ditampilkan dan bagian kode ini berfungsi.)Tekan F11 (Debug>Langkah Ke Dalam atau tombol Masuk ke 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.
Kotak dialog Edit dan Lanjutkan muncul, menunjukkan bahwa pengeditan tidak dapat dikompilasi.
Catatan
Untuk menelusuri kesalahan kode contoh Visual Basic, lewati beberapa langkah berikutnya hingga Anda diinstruksikan untuk mengklik tombol Mulai Ulang.
Pilih Edit di kotak Edit dan Lanjutkan pesan. 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 memilikiMyGType
properti ), debugger tidak mengenalitheGalaxy
objek sebagai objek jenisGType
. Apa yang terjadi? Anda ingin melihat melalui kode apa pun yang mengatur jenis galaksi. Ketika Anda melakukan ini, Anda melihat bahwa kelasGType
pasti memiliki propertiMyGType
, tetapi ada sesuatu yang tidak benar. Pesan kesalahan tentangobject
ternyata adalah petunjuk; bagi penafsir bahasa, jenisnya tampak sebagai objek berjenisobject
alih-alih objek berjenisGType
.Melihat melalui kode Anda yang terkait dengan pengaturan jenis galaksi, Anda menemukan properti
GalaxyType
dari kelasGalaxy
ditentukan sebagaiobject
alih-alihGType
.public object GalaxyType { get; set; }
Ubah kode sebelumnya sebagai berikut:
public GType GalaxyType { get; set; }
Pilih tombol Mulai Ulang di Toolbar Debug (Ctrl + Shift + F5) untuk mengkompilasi ulang kode dan menghidupkan ulang.
Sekarang, ketika debugger dijeda pada
Console.WriteLine
, Anda dapat mengarahkan mouse ke atastheGalaxy.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 berjalan 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
switch
pernyataan (sebelumSelect
pernyataan di Visual Basic).public GType(char type)
Kode ini adalah tempat jenis galaksi diatur, jadi kita ingin melihat lebih dekat.
Pilih tombol Mulai Ulang di Toolbar Debug (Ctrl + Shift + F5) untuk memulai ulang.
Debugger berhenti pada baris kode tempat Anda menyetel titik henti.
Arahkan kursor ke variabel
type
. Anda melihat nilaiS
(mengikuti kode karakter). Anda tertarik pada nilaiI
, seperti yang Anda tahu bahwa adalah jenis galaksi tidak teratur.Tekan F5 dan arahkan mouse ke atas variabel
type
lagi. Ulangi langkah ini hingga Anda melihat nilaiI
dalam variabeltype
.Sekarang, tekan F11 (Debug>Langkah Ke Dalam).
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 untuk maju ke tempat kode ditetapkanMyGType
sebagai jenis galaksi Tidak Teratur, tetapi debugger malah melompati kode ini sepenuhnya dan berhenti sejenak pada bagiandefault
pernyataanswitch
(pernyataanElse
dalam Visual Basic).Melihat kode, Anda melihat kesalahan ketik dalam pernyataan
case 'l'
. Properti tersebut seharusnyacase 'I'
.Pilih dalam kode untuk
case 'l'
dan ganti dengancase 'I'
.Hapus titik henti Anda, lalu pilih tombol Hidupkan ulang untuk menghidupkan 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 debugger dan langkah seperti F10 dan F11 untuk menemukan wilayah kode dengan masalah.
Catatan
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 ke 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 berisi jenis nilai yang harus dimuat. Jika Anda menemukan nilai yang buruk, cari tahu di mana nilai buruk diatur (untuk menemukan di mana nilai diatur, Anda mungkin perlu memulai ulang debugger, melihat tumpukan panggilan, atau keduanya).
Periksa apakah aplikasi Anda menjalankan kode yang Anda harapkan. (Misalnya, dalam aplikasi sampel, kami mengharapkan kode untuk
switch
pernyataan untuk mengatur jenis galaksi ke Tidak Teratur, tetapi aplikasi melewatkan kode karena kesalahan ketik.)
Tip
Anda menggunakan debugger untuk membantu Anda menemukan bug. Alat penelusuran kesalahan dapat menemukan bug untuk Anda hanya jika tahu niat kode Anda. Alat hanya dapat mengetahui niat kode Anda jika Anda, pengembang, mengekspresikan niat tersebut. Menulis pengujian unit adalah bagaimana Anda melakukan itu.
Langkah berikutnya
Dalam artikel ini, Anda telah mempelajari beberapa konsep penelusuran kesalahan umum. Selanjutnya, Anda dapat mulai mempelajari lebih lanjut tentang debugger.