Haruskah kode debug dibiarkan di tempat, selalu, atau ditambahkan hanya ketika debugging dan dihapus ketika bug telah ditemukan?


35

Saya, misalnya, hanya menambahkan kode debug (seperti pernyataan cetak) ketika saya mencoba menemukan bug. Dan begitu saya menemukannya, saya menghapus kode debug (dan menambahkan test case yang secara khusus menguji bug itu). Saya merasa itu mengacaukan kode asli dan karena itu tidak memiliki tempat di sana kecuali saya sedang debugging.

Bagaimana Anda melakukannya? Apakah Anda membiarkan kode debug di tempat, atau menghapusnya ketika usang (yang mungkin sulit untuk menilai kapan itu)?

Jawaban:


30

Pernyataan cetak debug harus dikeluarkan; namun, jika Anda perlu menambahkannya ke debug masalah produksi maka mungkin perlu dipertimbangkan jika Anda memiliki cukup informasi yang dimasukkan ke dalam kerangka kerja logging Anda. Informasi tentang parameter, kondisi kesalahan dan sebagainya mungkin berguna nanti ketika bug berikutnya muncul. Menggunakan kerangka kerja pencatatan yang baik yang dapat men-debug atau melacak pesan log yang dinyalakan secara dinamis bisa sangat berguna di alam liar.


5
+1 Terutama karena menyebutkan memiliki kerangka kerja debug yang masuk akal. Jika ini ada pada awalnya, dan ada berbagai level debug, maka kode produksi mudah-mudahan dapat berjalan tanpa memanggil rutinitas debug yang mahal, dan kode pengembangan dapat berjalan dengan tingkat pengawasan apa pun yang diperlukan, mudah-mudahan login dengan cara apa pun yang diinginkan.
Orbling

1
Setuju dengan Orbling. Dan ditambah lagi, untuk kode debug selain hanya tampilan informasi yang memiliki dampak kinerja atau alasan lain yang tidak sesuai untuk produksi. (mis. Pernyataan tentang hasil fungsi mis. memeriksa hasil pengurutan), Anda dapat mempertimbangkan dua mode target bangunan. mode debug dan mode rilis.
Zekta Chan

16

Kode yang ditambahkan secara khusus untuk debugging harus dihapus dari perangkat lunak produksi.

Apakah ini penghapusan lengkap atau dimasukkan ke bagian kompilasi bersyarat (seperti dalam C / C ++ / C #) terserah Anda dan standar pengkodean Anda.

Ada sejumlah alasan untuk ini:

  1. Mungkin ada implikasi keamanan jika kode ini dijalankan atau seseorang dapat mengakses hasilnya.
  2. Mungkin memperlambat aplikasi.
  3. Mungkin membingungkan bagi pengembang lain yang melihat kode (atau bahkan diri Anda sendiri) 6 bulan kemudian.

+1 untuk kompilasi bersyarat, tetapi blok komentar akan berfungsi dalam bahasa yang tidak mendukungnya. Anda seharusnya tidak pernah membiarkannya dikompilasi menjadi rilis prod, tetapi kadang-kadang sangat tidak efisien untuk terus menghapusnya sepenuhnya setiap kali Anda ingin menghentikan build rilis.
Bill

1
Saya telah bekerja di lingkungan di mana kode C / C ++ selalu dikompilasi dengan opsi debug jika kode produksi perlu di-debug atau coredump diperiksa. Terkadang mandat debug yang selalu siap ini mengharuskan pernyataan debug dibiarkan sehingga mereka dapat dinyalakan dengan flag tanpa mengkompilasi ulang kode. Java selalu memungkinkan debugging jika opsi JVM Anda diatur untuk itu sehingga pekerjaan persiapan yang relatif lebih sedikit diperlukan untuk debug hal-hal nanti.
Michael Shopsin

16

ChrisF dan Alaric keduanya memiliki poin yang valid; +1 untuk mereka. Saya dapat mengidentifikasi setidaknya 5 jenis kode debug yang saya gunakan.

  1. Menggunakan log untuk membuang status sistem pada titik waktu tertentu.

    void function(...)
    {
        ...dump everything i know about.
    }
    
  2. Menggunakan log untuk titik pemeriksaan eksekusi.

    void function(...)
    {
        ...got here 1
        ...got here 2
    }
    
  3. Kode yang benar-benar memaksa kondisi tertentu menjadi benar, tetapi merusak perilaku normal. Contoh:

    • Misalkan Anda memiliki beberapa log tentang kesalahan, tetapi Anda tidak dapat mereproduksi masalah. Anda dapat mencoba menulis kode yang memaksa variabel tertentu untuk memiliki nilai tertentu yang cocok dengan informasi dalam log.
  4. Verifikasi logging - Saya akan mengklasifikasikan ini sebagai logging verbose yang dapat digunakan untuk memvalidasi kebenaran perangkat lunak yang tidak boleh dimasukkan dalam produksi, seperti memvalidasi langkah-langkah individual dari algoritma misalnya.

  5. Operasi logging - lihat posting Alaric . Itulah yang saya maksud dengan "operasi logging".

1, 2 dan 3 harus digunakan sepenuhnya. Sesuatu seperti 4 Saya mungkin akan mengkompilasi dengan syarat kode. Untuk 5, Alaric memiliki poin bagus tentang kemampuan untuk mematikan log secara dinamis. Itu mungkin membahas poin ChrisF dalam peluru keduanya untuk sebagian besar kasus.


1
Ini ringkasan yang bagus. Namun, akan lebih baik jika Anda dapat memformatnya dengan benar dengan mengganti 1)... dengan 1.... (sehingga pemformatan Markdown mengambilnya sebagai daftar) dan membuat indentasi kode contoh sebanyak 8 spasi (sekali lagi, sehingga Markdown mengambilnya sebagai contoh kode dalam daftar).
Konrad Rudolph

@Konrad Rudolph: Selesai.
gablin

3

Tergantung pada apa yang dilakukan kode. Beberapa kode yang digunakan untuk debugging dapat dibiarkan apa adanya, dan beberapa harus dihapus.

Kode yang memverifikasi kewarasan parameter dalam suatu metode tidak selalu berguna setelah kode berfungsi dengan baik, tetapi sering kali dipastikan bahwa kode tersebut terus berfungsi dengan baik.

Terkadang Anda menulis kode secara berbeda untuk memudahkan debug kode, misalnya menghitung nilai dan memasukkannya ke dalam variabel lokal, dan kemudian menggunakan variabel di baris berikutnya, yang membuatnya mudah untuk memeriksa hasil perhitungan ketika langkah tunggal melalui kode. Anda bisa menulis ulang kode untuk menggunakan nilai yang dihitung secara langsung, tetapi biaya menggunakan variabel lokal sangat kecil (jika ada sama sekali) sehingga ada sedikit alasan untuk menulis ulang kode. Juga, ada gunanya membiarkan kode tidak berubah setelah Anda mengujinya, selalu ada risiko kecil bahwa Anda memperkenalkan bug saat mengubahnya.

Kode yang Anda tambahkan hanya untuk melacak bug tertentu seringkali dapat dihapus setelah Anda menemukan bug.


2

Sekali waktu saya menggunakan banyak kode debug. Saya hampir seluruhnya menargetkan Windows, jadi ada banyak fungsi output string debug ini yang saya tidak ingat bagaimana mengeja lagi, jadi saya bisa menangkap jejak dengan program tertentu.

Beberapa kode debug tetap ada di tempat, hal-hal tertentu yang dimaksudkan untuk memberi panggilan bersarang. Namun, meskipun masalah string debug sebagian besar tidak akan terlihat pada sistem produksi, semuanya masih dilakukan di bawah kompilasi bersyarat.

Kenyataannya adalah, bagaimanapun, bahwa semua kode debug itu banyak upaya untuk sesuatu yang idealnya ditangani dengan cara yang berbeda - tentu saja menggunakan debugger. Pada saat itu, saya tidak terkesan dengan debugger Borland C ++. Alat ada di sana, tetapi mereka terlalu sering memberikan hasil yang menyesatkan, dan menggunakan debugger non-IDE (sering diperlukan) berarti menghafal tombol pintas, yang berarti gangguan dari pekerjaan yang sedang dihadapi.

Satu-satunya pengalaman debugging yang saya temukan lebih buruk adalah command-line GDB.

Menjadi seorang ahli dengan alat yang Anda gunakan setiap hari tentu saja penting - tetapi debugging tidak seharusnya menjadi sesuatu yang Anda lakukan setiap hari. Jika Anda sering menggunakan debugger, Anda akan baik-baik saja dengan mempelajari lusinan perintah dan / atau pintasan keyboard, yang tampaknya agak red-flag bagi saya.

Pada saat saya bekerja di Visual Studio 7, sudah jelas bahwa debugging bisa sangat praktis dan efektif. Jika Anda dapat melakukan debugging di Visual Studio (termasuk edisi ekspres), debugging sangat mudah. Tidak diragukan lagi jika Anda dapat menemukan ujung depan GUI / IDE yang tepat, GDB juga mudah dan efektif, meskipun saya belum melakukan pencarian itu.

Ada juga sesuatu yang bisa dikatakan untuk pengujian unit, dengan analisis cakupan menggunakan gcov. Semakin yakin bahwa Anda berada dalam perilaku perpustakaan Anda, semakin tidak perlu debugging Anda menjadi - dan semakin sering Anda membutuhkan debugger di tempat pertama. Dan menulis unit test adalah sesuatu yang cukup masuk akal yang harus Anda lakukan hampir setiap hari.

Tool yang tidak terduga penting = cmake, tool build yang memungkinkan saya untuk dengan mudah beralih antara membangun untuk GCC dan untuk VC ++, antara lain. Jadi saya bisa melakukan pengujian unit dan cakupan berbasis gcov menggunakan GCC, tetapi dengan mudah beralih ke VC ++ untuk menggunakan debugger.


Seorang debugger bisa sangat berguna jika tidak berbahaya di aplikasi multi-threaded, tapi saya suka komentar flag-ish merah Anda.
Pemdas

@Pemdas - Saya belum pernah mengalami masalah serius, meskipun multi-threading jelas tidak ramah debugger. Meski begitu, saya pikir alat yang tepat kemungkinan solusi yang lebih baik daripada kode debug pada prinsipnya. Alat analisis statis yang dapat melihat kondisi balapan, kebuntuan, kondisi ketika dua utas dapat memperebutkan memori / sumber daya yang sama pada saat yang sama dan seterusnya akan menyenangkan. Saya tidak tahu apa yang tersedia di sepanjang garis itu, meskipun saya tahu ada beberapa alat pintar di luar sana. Klee, misalnya - Saya tidak mengerti, tapi deskripsi dasar terdengar sangat mengesankan.
Steve314

"Saya pikir alat yang tepat kemungkinan solusi yang lebih baik daripada kode debug pada prinsipnya" Itu pernyataan yang berbahaya;). Memiliki alat yang membentuk beberapa analisis mungkin bagus, tetapi saya khawatir bahwa pengembang terutama yang baru akan mulai menjadi terlalu bergantung pada alat, seperti seseorang yang perlu menggunakan kalkulator untuk mencari tahu apa 15% dari 100 itu.
Pemdas

Terlalu bergantung pada alat yang bahkan belum saya teliti sepertinya tidak mungkin. Pada contoh kalkulator Anda, ya, tapi saya masih akan menggunakan OpenOffice Calc daripada menulis spreadsheet sederhana saya sendiri. Ada waktu untuk kode debug (bahkan dengan debugger - mis. Kasut Anda sendiri yang menciptakan kondisi), tetapi jika melampaui titik tertentu, alat yang ada menang. Dan ketika harus mengurangi 15% dari 115, saya akan menggunakan kalkulator itu juga - apa yang banyak orang berikan sebagai jawaban yang jelas (100) salah. Dalam multithreading, jawaban yang benar jelas terkenal karena terkadang ternyata salah.
Steve314

1

Pandangan saya: Kode debug digunakan untuk membunuh bug di dalam kode yang saya tanya pada umumnya saya hapus seluruhnya. Kode debug digunakan untuk membunuh bug yang dihasilkan dari pasukan luar. Saya biasanya hanya berkomentar.


-1

Jika bug berasal dari unit testing atau dari internal, kode debug bisa dihapus sama sekali. Tetapi jika bug berasal dari produksi, kode debug sebaiknya ada di dalam tag kompilasi. Menempatkannya di dalam tag kompilasi akan membantu pengembang lain untuk memahami bahwa kode ini hanya untuk tujuan debug.


-1

Gunakan TDD , jadi kode pengujian Anda selalu memiliki tempat yang bahkan dipertahankan.


bagaimana ini menjawab pertanyaan yang diajukan?
Agak

Karena TDD mengarahkan Anda ke "debug" atau kode pengujian yang tidak harus Anda hapus.
dukeofgaming

Saya tidak mengikuti maaf. Bagaimana itu?
nyamuk
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.