Bagaimana cara paling efektif men-debug kode? [Tutup]

33

Bug yang merayap ke dalam kode dapat diminimalkan, tetapi tidak sepenuhnya dihilangkan seperti yang tertulis - programmer, meskipun banyak yang tidak setuju , hanya manusia.

Ketika kita mendeteksi kesalahan dalam kode kita, apa yang bisa kita lakukan untuk menghilangkannya? Bagaimana kita harus mendekatinya untuk memanfaatkan waktu berharga kita secara paling efektif dan memungkinkan kita menghabiskan lebih sedikit waktu untuk menemukannya dan lebih banyak pengkodean waktu? Juga, apa yang harus kita hindari saat debugging?

Perhatikan di sini bahwa kita tidak berbicara tentang mencegah bug; kita sedang berbicara tentang apa yang harus dilakukan ketika bug yang muncul. Ini adalah bidang yang luas, saya tahu, dan mungkin sangat tergantung pada bahasa, platform, dan alat. Jika demikian, tetap mencakup jawaban seperti pola pikir dan metode umum.

Gablin
sumber
Pertanyaan tertaut telah dihapus.
1
Saya pikir pendekatannya sebenarnya sederhana. Jika Anda mengembangkannya sendiri, Anda tahu segalanya tentang itu. Anda bahkan dapat memperbaiki bug tanpa men-debug. Dengan mengingat hal itu, cara terbaik adalah menggunakan waktu Anda mengkodekan sesuatu yang lain, sampai seseorang yang tahu banyak tentang hal itu dapat menjawab pertanyaan Anda tentang cara memperbaikinya; atau, biarkan istirahat, kode hal-hal lain, sampai ide untuk memperbaikinya datang ke pikiran Anda, sehingga Anda tidak akan kehilangan waktu dan energi. Dugaan saya adalah pertanyaan Anda tentang manajemen tim perusahaan.
Aquarius Power
Saya pikir Raid. Di luar rak, semprotan pembasmi serangga. Apakah ini pertanyaan filosofis? Buku-buku dibuat dari dominan semata ...
ejbytes

Jawaban:

38

Pola pikir dan sikap terhadap debugging mungkin adalah bagian yang paling penting, karena menentukan seberapa efektif Anda akan memperbaiki kesalahan, dan apa yang akan Anda pelajari darinya - jika ada.

Klasik tentang pengembangan perangkat lunak seperti The Pragmatic Programmer dan Code Complete pada dasarnya mendukung pendekatan yang sama: setiap kesalahan adalah kesempatan untuk belajar, hampir selalu tentang diri Anda (karena hanya pemula yang menyalahkan kompiler / komputer terlebih dahulu).

Jadi perlakukan itu sebagai misteri yang akan menarik untuk dipecahkan. Dan memecahkan misteri itu harus dilakukan secara sistematis, dengan mengekspresikan asumsi kita (kepada diri kita sendiri, atau kepada orang lain) dan kemudian menguji asumsi kita, satu-per-satu jika perlu - menggunakan setiap alat yang kita miliki, terutama debugger dan kerangka kerja pengujian otomatis. Kemudian setelah misteri terpecahkan, Anda dapat melakukan yang lebih baik dengan melihat semua kode Anda untuk kesalahan serupa yang mungkin Anda buat; dan menulis tes otomatis untuk memastikan kesalahan tidak akan terjadi tanpa disadari lagi.

Satu catatan terakhir - Saya lebih suka menyebut kesalahan sebagai "kesalahan" dan bukan "bug" - Dijkstra memarahi rekan-rekannya karena menggunakan istilah yang terakhir karena tidak jujur, mendukung gagasan bahwa peri-bug yang merusak dan berubah-ubah menanam bug di program kami sementara kami tidak t mencari, daripada berada di sana karena pemikiran (ceroboh) kita sendiri: http://www.cs.utexas.edu/users/EWD/transcription/EWD10xx/EWD1036.html

Kita bisa, misalnya, mulai dengan membersihkan bahasa kita dengan tidak lagi menyebut bug bug tetapi dengan menyebutnya kesalahan. Itu jauh lebih jujur ​​karena itu menempatkan kesalahan di tempatnya, yaitu. dengan programmer yang membuat kesalahan. Metafora animistik dari bug yang secara licik menyelinap masuk sementara programmer tidak melihat secara intelektual tidak jujur ​​karena menyamarkan bahwa kesalahannya adalah kreasi programmer itu sendiri. Yang menyenangkan dari perubahan kosa kata yang sederhana ini adalah ia memiliki efek mendalam: sementara, sebelumnya, sebuah program dengan hanya satu bug dulu "hampir benar", kemudian sebuah program dengan kesalahan hanyalah "salah" (karena dalam kesalahan).

limist
sumber
7
Sebenarnya saya lebih suka istilah "kesalahan" daripada "bug", bukan karena menyalahkan "programmer yang membuat kesalahan", tetapi karena menjelaskan bahwa itu mungkin bukan kesalahan programmer. Bagi saya, "bug" menyiratkan kesalahan dalam kode; sedangkan "kesalahan" menyiratkan kesalahan di suatu tempat . Mungkin dalam kode, mungkin dalam pengaturan lingkungan, mungkin dalam persyaratan. Membuat saya gila ketika bos saya memiliki "daftar bug" di mana separuh masalahnya adalah perubahan persyaratan. Sebut saja daftar tugas, ferchrissakes!
Carson63000
2
+1 untuk "setiap kesalahan adalah kesempatan untuk belajar, hampir selalu tentang diri Anda (karena hanya pemula yang menyalahkan kompiler / komputer terlebih dahulu)"
Md Mahbubur Rahman
Anda mengetahui sejarah istilah "bug", bukan? Maksud saya, seperti yang digunakan dalam pengembangan perangkat lunak. Tentu saja, kami tidak memiliki masalah ini hari ini, tetapi bug benar-benar terbang ke perangkat keras komputer tanpa diketahui oleh programmer dan menyebabkan masalah. Kalau tidak ada yang berpikir untuk mengoreksi saya, saya tahu Edison menggunakan istilah ini jauh sebelum insiden ngengat, itulah sebabnya saya menggunakan kata 'sejarah', bukan 'asal'. Lihat computerworld.com/article/2515435/app-development/… dan en.wikipedia.org/wiki/Software_bug#Etymology
threed
@ ada Tentu saja. Tetapi untuk beberapa waktu, serangga tidak menyebabkan sebagian besar kesalahan perangkat lunak.
limist
16
  1. Tulis tes. Pengujian tidak hanya hebat dalam mencegah bug (dalam pengalaman saya, TDD dilakukan dengan benar menghilangkan hampir semua bug yang sepele, bodoh), tetapi juga banyak membantu dalam debugging. Pengujian memaksa desain Anda menjadi agak modular, yang membuatnya lebih mudah mengisolasi dan mereplikasi masalah. Juga, Anda mengendalikan lingkungan, jadi akan ada lebih sedikit kejutan. Selain itu, setelah Anda mendapatkan test case yang gagal, Anda dapat yakin bahwa Anda telah memakukannya alasan sebenarnya dari perilaku yang mengganggu Anda.

  2. Pelajari cara menggunakan debugger. printpernyataan mungkin bekerja dengan cukup baik pada tingkat tertentu, tetapi sebagian besar waktu debugger sangat membantu (dan begitu Anda tahu cara menggunakannya, itu jauh lebih nyaman daripada printpernyataan).

  3. Bicara tentang seseorang tentang masalah Anda, walaupun itu hanya sebuah bebek karet . Memaksa diri sendiri untuk mengungkapkan masalah yang sedang Anda kerjakan dengan kata-kata benar-benar membuat keajaiban.

  4. Beri diri Anda batas waktu. Jika misalnya setelah 45 menit Anda merasa tidak ke mana-mana, cukup beralih ke tugas lain untuk beberapa waktu. Saat Anda kembali ke bug Anda, semoga Anda dapat melihat solusi lain yang mungkin tidak pernah Anda pertimbangkan sebelumnya.

Ryszard Szopa
sumber
2
+1 untuk "Memaksa diri sendiri untuk mengungkapkan masalah yang sedang Anda kerjakan dengan kata-kata benar-benar membuat keajaiban."
Md Mahbubur Rahman
Dan untuk menambahkan ke (1), hampir setiap bug yang Anda lihat dalam kode menyiratkan bahwa ada bug - atau setidaknya kelalaian - di dalam test suite. Perbaiki keduanya pada saat yang sama dan Anda tidak hanya membuktikan bahwa Anda telah memperbaiki masalah yang ada, Anda juga aman terhadap masalah itu diperkenalkan kembali.
Julia Hayward
3

Saya pikir reproduksi bug juga penting. Semua kasus yang mereproduksi bug dapat didaftar dan kemudian Anda dapat memastikan bahwa perbaikan bug Anda mencakup semua kasus tersebut.

aslisabanci
sumber
3

Ada buku bagus yang saya baca tentang topik ini yang disebut Why Programs Fail , yang menguraikan berbagai strategi untuk menemukan bug mulai dari menerapkan metode ilmiah untuk mengisolasi dan menyelesaikan bug, hingga delta debugging. Bagian menarik lainnya dari buku ini adalah bahwa ia menghilangkan istilah 'bug'. Pendekatan Zeller adalah:

(1) Seorang programmer membuat cacat pada kode. (2) Cacat menyebabkan infeksi (3) Infeksi menjalar (4) Infeksi menyebabkan kegagalan.

Jika Anda ingin meningkatkan keterampilan debug Anda, saya sangat merekomendasikan buku ini.

Dalam pengalaman pribadi saya, saya telah menemukan banyak bug dalam aplikasi kami, tetapi manajemen cukup menekan kami untuk mengeluarkan fitur baru. Saya sering mendengar "Kami menemukan bug ini sendiri dan klien belum menyadarinya, jadi biarkan saja sampai mereka menemukannya". Saya pikir menjadi reaktif menentang proaktif dalam memperbaiki bug adalah ide yang sangat buruk karena ketika tiba saatnya untuk benar-benar memperbaiki, Anda memiliki masalah lain yang perlu diselesaikan dan lebih banyak fitur manajemen ingin keluar secepatnya, sehingga Anda ketahuan. dalam lingkaran setan yang dapat menyebabkan banyak stres dan terbakar dan akhirnya, sistem cacat ditunggangi.

Komunikasi juga merupakan faktor lain ketika bug ditemukan. Mengirimkan email atau mendokumentasikannya di pelacak bug semuanya baik-baik saja, tetapi menurut pengalaman saya sendiri, pengembang lain menemukan bug yang sama dan alih-alih menggunakan kembali solusi yang Anda buat untuk memperbaiki kode (karena mereka sudah lupa semua tentangnya ), mereka menambahkan versi mereka sendiri, jadi Anda punya 5 solusi berbeda dalam kode Anda dan hasilnya terlihat lebih membengkak dan membingungkan. Jadi, ketika Anda memperbaiki bug, pastikan beberapa orang meninjau perbaikan dan memberi Anda umpan balik seandainya mereka telah memperbaiki sesuatu yang serupa dan menemukan strategi yang baik untuk mengatasinya.

Limist menyebut buku itu, The Pragmatic Programmer yang memiliki beberapa materi menarik tentang cara memperbaiki bug. Dengan menggunakan contoh yang saya berikan pada paragraf sebelumnya, saya akan melihat ini: Entropi Perangkat Lunak , di mana analogi janda rusak digunakan. Jika dua jendela yang pecah muncul, tim Anda mungkin menjadi apatis untuk memperbaikinya, kecuali jika Anda bersikap proaktif.

Planet terpencil
sumber
Saya pernah mendengar "Kami menemukan bug ini sendiri dan klien belum menyadarinya, jadi biarkan saja sampai mereka melakukannya" terlalu sering. Dan telah pergi pada kunjungan situs, sering klien telah melihat, namun belum melaporkan hal itu. Kadang-kadang karena mereka berpikir tidak ada gunanya karena itu tidak akan diperbaiki, kadang-kadang karena mereka sudah melihat pengganti pesaing, dan kadang-kadang (benar atau salah) "Yah, bagaimanapun juga itu semua tumpukan sampah yang mengepul".
Julia Hayward
@JuliaHayward - Ini sangat sering terjadi, tetapi dalam situasi Anda, klien Anda mungkin puas dengan fungsi dan tidak terlalu peduli dengan apa yang terjadi di bawah tenda. Masalahnya mulai muncul ketika klien kembali meminta fitur tambahan dan Anda perlu menambahkan perangkat tambahan seperti membuat aplikasi Anda multibahasa, bla bla yang sesuai dengan seluler, Anda mulai melihat apa yang Anda miliki dan melihat semua retakan di dinding.
Desolate Planet
Hanya menunjukkan kepada Anda, semua buku di dunia tentang desain perangkat lunak, pengujian dan komunikasi yang baik dan banyak produk yang Anda kerjakan berantakan berantakan. Meskipun mengetahui apa yang benar, tekanan dan tenggat waktu yang tidak realistis (di wajah pada kode Anda yang sudah berantakan) adalah alasan di balik mengapa kode itu berada di negara itu. Saya tidak punya jawaban untuk itu sendiri, saya cukup terkenal di kantor sebagai wajah mengerang ****** ketika saya menendang dan berteriak untuk menjaga kode tetap sehat dan proses pengembangannya lancar, tetapi kadang-kadang tim tidak melakukannya. ikatan dengan baik.
Desolate Planet
3

Bug, kesalahan, masalah, cacat - apa pun yang Anda inginkan, tidak ada bedanya. Saya akan tetap pada masalah karena itulah yang biasa saya lakukan.

  1. Cari tahu apa persepsi masalahnya: terjemahkan dari pelanggan, 'Bob masih belum ada di sistem' ke 'Ketika saya mencoba membuat catatan pengguna untuk Bob, itu gagal dengan pengecualian kunci duplikat, meskipun Bob belum di sana'
  2. Cari tahu apakah itu benar-benar masalah atau hanya kesalahpahaman (memang, Bob tidak ada di sana, tidak ada yang bernama bob, dan insert seharusnya berfungsi).
  3. Cobalah untuk mendapatkan langkah-langkah minimum yang dapat diandalkan yang dapat Anda ikuti untuk mereproduksi masalah - sesuatu seperti 'Diberikan sistem dengan catatan pengguna' Bruce ', ketika catatan pengguna' Bob 'dimasukkan, maka pengecualian terjadi'
  4. Ini adalah tes Anda - jika memungkinkan, letakkan di harness uji otomatis yang dapat Anda jalankan lagi dan lagi, ini akan sangat berharga saat debugging. Anda juga dapat menjadikannya bagian dari rangkaian uji untuk memastikan bahwa masalah tertentu tidak muncul lagi di lain waktu.
  5. Keluarkan debugger Anda dan mulai letakkan breakpoints - cari tahu jalur kode ketika Anda menjalankan tes Anda, dan identifikasi apa yang salah. Ketika Anda melakukan itu, Anda juga dapat memperbaiki tes Anda dengan membuatnya sesempit mungkin - idealnya tes unit.
  6. Perbaiki - verifikasi lulus tes Anda.
  7. Verifikasi masalah asli seperti yang dijelaskan oleh pelanggan juga sudah diperbaiki (sangat penting - Anda mungkin telah memperbaiki sebagian masalah). Pastikan Anda tidak memperkenalkan regresi dalam aspek-aspek lain dari program ini.

Jika Anda sangat terbiasa dengan kode, atau jika masalah atau perbaikannya jelas, Anda dapat melewati beberapa langkah itu.

Bagaimana kita harus mendekatinya untuk memanfaatkan waktu berharga kita secara paling efektif dan memungkinkan kita menghabiskan lebih sedikit waktu untuk menemukannya dan lebih banyak pengkodean waktu?

Saya mengambil masalah dengan itu, karena itu menyiratkan bahwa menulis kode baru lebih berharga daripada memiliki program kerja yang berkualitas tinggi. Tidak ada yang salah dengan menjadi seefektif mungkin dalam memperbaiki masalah, tetapi suatu program tidak selalu menjadi lebih baik dengan hanya menambahkan lebih banyak kode ke dalamnya.

ptyx
sumber
ini jawaban terbaik IMO
marcusshep
3

Saya suka sebagian besar jawaban lain, tetapi di sini ada beberapa tips tentang apa yang harus dilakukan SEBELUM Anda melakukan semua itu. Akan menghemat waktu Anda beaucoup.

  1. Tentukan apakah memang ada bug. Bug adalah SELALU perbedaan antara perilaku sistem dan persyaratan; penguji harus mampu mengartikulasikan perilaku yang diharapkan dan aktual. Jika dia tidak dapat memberikan dukungan untuk perilaku yang diharapkan, tidak ada persyaratan dan tidak ada bug - hanya pendapat seseorang. Kirim kembali.

  2. Pertimbangkan kemungkinan bahwa perilaku yang diharapkan salah. Ini bisa jadi karena salah tafsir dari persyaratan. Bisa juga karena cacat pada persyaratan itu sendiri (delta antara persyaratan rinci dan persyaratan bisnis). Anda dapat mengirim ini kembali juga.

  3. Isolasikan masalahnya. Hanya pengalaman yang akan mengajarkan Anda cara tercepat untuk melakukan ini - beberapa orang hampir dapat melakukannya dengan keberanian mereka. Satu pendekatan dasar adalah memvariasikan satu hal sambil menjaga semua hal lainnya tetap konstan (apakah masalah terjadi pada lingkungan lain? Dengan peramban lain? Di wilayah pengujian yang berbeda? Pada waktu yang berbeda dalam sehari?) Pendekatan lain adalah dengan melihat tumpukan tumpukan atau pesan kesalahan - kadang-kadang Anda dapat mengetahui hanya dengan cara diformat komponen sistem mana yang melempar kesalahan asli (misalnya jika itu dalam bahasa Jerman Anda dapat menyalahkan pihak ketiga yang bekerja dengan Anda di Berlin).

  4. Jika Anda mempersempitnya menjadi dua sistem yang berkolaborasi, periksa pesan di antara kedua sistem melalui monitor lalu lintas atau file log, dan tentukan sistem mana yang berperilaku spesifik dan mana yang tidak. Jika ada lebih dari dua sistem dalam skenario, Anda dapat melakukan pemeriksaan berpasangan dan bekerja dengan cara "menurunkan" tumpukan aplikasi.

  5. Alasan mengapa mengisolasi masalah sangat penting adalah bahwa masalahnya mungkin bukan karena cacat dalam kode yang Anda kontrol (misalnya sistem pihak ketiga atau lingkungan) dan Anda ingin agar pihak tersebut mengambil alih secepat mungkin . Ini baik untuk menyelamatkan Anda bekerja dan untuk mendapatkan mereka pada titik segera sehingga resolusi dapat dicapai dalam waktu sesingkat mungkin. Anda tidak ingin mengerjakan masalah selama sepuluh hari hanya untuk menemukan itu benar-benar masalah dengan layanan web orang lain.

  6. Jika Anda telah menentukan bahwa memang ada cacat dan itu benar-benar ada dalam kode yang Anda kontrol, Anda dapat mengisolasi masalah lebih lanjut dengan mencari build "dikenal baik" terakhir dan memeriksa log kontrol sumber untuk perubahan yang mungkin menyebabkan masalah. Ini bisa menghemat banyak waktu.

  7. Jika Anda tidak dapat mengetahuinya dari kontrol sumber, sekarang saatnya untuk melampirkan debugger Anda dan melangkah melalui kode untuk mengetahuinya. Kemungkinannya sekarang Anda sudah memiliki ide yang cukup bagus tentang masalah itu.

Setelah Anda tahu di mana bug itu dan bisa memikirkan perbaikan, berikut ini adalah prosedur yang baik untuk memperbaikinya:

  1. Tulis tes unit yang mereproduksi masalah dan gagal.

  2. Tanpa memodifikasi tes unit, buat lulus (dengan memodifikasi kode aplikasi).

  3. Simpan unit test di dalam test suite Anda untuk mencegah / mendeteksi regresi.

John Wu
sumber
1

Begini cara saya melakukannya:

  1. gunakan metode yang sama setiap kali menemukan masalahnya. Ini akan meningkatkan waktu reaksi Anda terhadap kesalahan.
  2. Cara terbaik mungkin adalah membaca kode. Ini karena semua informasi tersedia dalam kode. Anda hanya perlu cara yang efisien untuk menemukan posisi yang benar dan kemampuan untuk memahami semua detail.
  3. debugging adalah cara yang sangat lambat, dan hanya diperlukan jika programmer Anda belum mengerti bagaimana komputer mengeksekusi instruksi asm / tidak dapat memahami tumpukan panggilan dan hal-hal dasar
  4. Cobalah untuk mengembangkan teknik bukti seperti menggunakan prototipe fungsi untuk alasan tentang perilaku program. Ini akan membantu menemukan posisi yang benar lebih cepat
tp1
sumber
1

Ketika kita mendeteksi kesalahan dalam kode kita, apa yang bisa kita lakukan untuk menghilangkannya? Bagaimana kita harus mendekatinya untuk memanfaatkan waktu berharga kita secara paling efektif dan memungkinkan kita menghabiskan lebih sedikit waktu untuk menemukannya dan lebih banyak pengkodean waktu? Juga, apa yang harus kita hindari saat debugging?

Dengan asumsi bahwa Anda berada dalam lingkungan produksi, inilah yang perlu Anda lakukan:

  1. Jelaskan "kesalahan" dengan benar, dan identifikasi peristiwa yang menyebabkannya terjadi.

  2. Menentukan apakah "kesalahan" adalah kesalahan kode atau kesalahan spesifikasi. Misalnya, memasukkan nama 1 huruf dapat dianggap sebagai kesalahan pada beberapa sistem tetapi perilaku yang dapat diterima untuk sistem lain. Kadang-kadang pengguna akan melaporkan kesalahan yang menurutnya merupakan masalah tetapi harapan pengguna untuk perilaku sistem bukan bagian dari persyaratan.

  3. Jika Anda telah membuktikan bahwa ada kesalahan dan kesalahan disebabkan oleh kode, maka Anda dapat menentukan potongan kode mana yang perlu diperbaiki untuk mencegah kesalahan. Juga memeriksa pengaruh perilaku pada data saat ini dan operasi sistem masa depan (analisis dampak pada kode dan data).

  4. Pada titik ini Anda mungkin akan memiliki perkiraan berapa banyak sumber daya yang akan dikonsumsi untuk memperbaiki bug. Anda dapat memperbaikinya segera atau menjadwalkan perbaikan dalam rilis perangkat lunak yang akan datang. Ini juga tergantung pada apakah pengguna akhir bersedia membayar untuk perbaikannya. Anda juga harus mengevaluasi berbagai opsi yang tersedia untuk memperbaiki kesalahan. Mungkin ada lebih dari satu cara. Anda harus memilih pendekatan yang paling sesuai dengan situasi.

  5. Analisis alasan yang menyebabkan bug ini muncul (persyaratan, pengkodean, pengujian, dll.). Menegakkan proses yang akan mencegah kondisi terjadi lagi.

  6. Dokumentasikan episode dengan memadai.

  7. Lepaskan perbaikan (atau versi baru)

Tidak ada kesempatan
sumber