Metode kode debug (situasi Nightmare)


16

Saya sering ditugaskan untuk men-debug aplikasi di pekerjaan saya. Ini adalah Aplikasi BI yang kami gunakan untuk bisnis, yang meliputi lingkungan pengujian, dan lingkungan produksi. Saya bertanya-tanya apakah ada aplikasi / alat / metode yang dapat disarankan orang, berdasarkan kendala ini:

  1. Debugger tidak dapat digunakan di situs klien atau secara lokal, karena perangkat lunak tergantung pada aplikasi pihak ketiga khusus yang kami tidak memiliki lingkungan pengujian. (EDIT: untuk bersikap adil, adalah mungkin untuk men-debug secara lokal dalam beberapa kasus. Jika kita tidak menggunakan apa pun kecuali kode inti. Banyak kode bermasalah berada di dll yang merangkum komunikasi spesifik pihak ketiga: soket, pipa proses, panggilan sabun, logika khusus yang mengubah perilaku kode inti. Biasanya selama implementasi atau peningkatan untuk klien, kami akan menulis kode baru ke area ini.)

  2. Hampir tidak ada penebangan yang dilakukan di aplikasi kami. Tidak ada tes unit.

  3. Kontrol versi hanya memiliki 1 versi dari solusi lengkap (menggunakan source safe 2005). Jadi tidak mungkin untuk mendapatkan versi sebelumnya dari seluruh solusi, hanya file individual. (Kecuali ada yang tahu cara mengatasi ini).

  4. Tidak dapat mereproduksi secara lokal, seringkali kali tidak dapat mereproduksi di lingkungan pengujian (Kemungkinan besar pengujian dan produksi bukan versi yang sama).

  5. Ada kemungkinan besar bahwa versi yang digunakan klien berbeda dari yang ada di sumber aman. Ini karena file individual diperbarui, yang telah menyematkan logika khusus untuk klien tertentu. Seringkali yang terjadi adalah pembaruan dibuat ke biner, yang membutuhkan perubahan pada beberapa binari lainnya, tetapi ketika komit dilakukan, tidak ada yang memiliki catatan atau pengetahuan tentang ini. Kesalahan yang agak umum saya lihat adalah 'Function / Method not found' atau 'Method call memiliki terlalu banyak / terlalu sedikit parameter yang ditentukan' pada lingkungan klien.

  6. Ini adalah solusi .net VB

  7. Tidak dapat menginstal perangkat lunak apa pun di situs klien, tetapi dapat secara lokal

  8. Aplikasi kami sangat dapat dikustomisasi, tetapi sayangnya logika kustomisasi tersebar di semua kelas dan file, dari ujung depan sampai ke lapisan data, termasuk perubahan khusus yang dibuat ke database pada basis per klien.

  9. Hampir tidak ada komentar dalam kode. Tidak ada dokumentasi tentang arsitektur. Tidak ada dokumentasi tentang api. Satu-satunya yang kami miliki adalah ratusan rantai email yang menjelaskan apa yang terjadi. Satu-satunya orang yang mengetahui kode adalah orang-orang yang semula menulisnya, tetapi mereka tidak lagi pengembang per kata sehingga mereka tidak terlalu terlibat.

Dan sebelum Anda mengatakannya ... ya saya tahu; Saya ingin menembak diri sendiri juga. Itu tidak membantu bahwa ada kode spaghetti, ratusan peringatan kompiler, dan polimorfisme patah yang BENAR-BENAR harus diperbaiki, tetapi saya tidak memiliki suara di dalamnya.

Jenis kesalahan paling umum yang saya temui adalah kesalahan referensi nol, gips yang tidak valid, dan fungsi yang hilang / ketidakcocokan tanda tangan fungsi. Terkadang saya beruntung dan pemirsa acara akan mencatat pesan kelas, metode, dan pengecualian. Ini bukan yang paling membantu, tapi tetap saja sesuatu. Yang terburuk adalah kesalahan yang tidak memiliki jejak, tidak ada langkah repro selain tangkapan layar, dan pesan kesalahan umum seperti yang disebutkan di atas. Kadang-kadang tidak mungkin untuk mencari tahu mengapa itu terjadi, hanya untuk berdoa agar lingkungan tidak dikonfigurasikan dengan benar, dan itu akan hilang kemudian.

Saya tahu ini muncul sebagai kata-kata kasar, dan sedikit banyak. Tapi saya sangat membutuhkan opsi. Apakah ada metode / alat lain yang bisa saya gunakan?


43
Apakah kamu memiliki resume?
Robert Harvey

5
+1 untuk "Saya ingin menembak diri sendiri juga". Sumber Aman 2005, aduh. Ya, setidaknya Anda harus 'fokus' pada pelajaran sejarah yang luar biasa - pada dasarnya Anda seorang penjelajah waktu! Anda akan belajar pelajaran dari satu dekade pengetahuan yang dikembangkan dengan cermat tentang "jadi ini sebabnya kami tidak melakukan itu lagi". Semoga berhasil, belalang.
BrianH

7
Mengingat persyaratan # 1, satu-satunya cara untuk menjadi efektif dalam debugging kekacauan ini adalah menjadi waskita. Serius, tidak ada peluru ajaib yang akan membuat ini apa-apa selain omong kosong. Dalam beberapa hal ini akan mengurangi tekanan Anda, karena debugging tentu merupakan masalah keberuntungan. Atau manajemen Anda akan memerintahkan Anda untuk beruntung? Jelas ini tidak berkelanjutan, jadi Anda harus mencari peluang lain.
Charles E. Grant

14
Berikut adalah beberapa saran karier aktual: Menghabiskan terlalu lama di rumah yang memiliki praktik rekayasa perangkat lunak yang mengerikan dan Anda mungkin akan disalahkan oleh manajemen karena menjadi pengembang yang buruk untuk masalah yang tak terhindarkan terjadi kemudian. Saya pernah ke sana, dan saya yakin orang lain juga. Paling-paling, itu mengarah pada kebiasaan perkembangan yang buruk.
Gort the Robot

2
bagaimana saya mengelola situasi ini: jika saya tidak dibayar jauh di atas pasar, saya pergi mencari hal lain untuk dilakukan.
kevin cline

Jawaban:


22

Nasihat Robert Harvey mungkin yang terbaik, tetapi karena nasihat karier bukan topik, saya akan memberikan jawaban apa yang bisa diberikan:

Anda berada di dasar gunung yang sangat curam yang ditutupi semak duri dan lumpur serta kambing gunung yang mudah tersinggung. Tidak ada jalan naik yang mudah. Jika Anda ingin mencapai puncak, Anda harus memaksakan langkah Anda naik satu langkah yang sangat menyakitkan sekaligus.

Sepertinya Anda tahu persis bagaimana hal itu yang harus bekerja. Jika tidak ada orang lain yang akan membantu Anda (lagi, mengabaikan nasihat karier) satu-satunya pilihan Anda adalah mulai memperbaiki sendiri hal-hal ini.

Pertama, untuk semua yang suci, dapatkan barang-barang itu dengan nyata sistem kontrol versi . Hampir tidak ada sama sekali kecuali Source Safe, yang dikenal sebagai tumpukan sampah yang bau. gitgratis dan dapat diatur dengan cukup mudah. Anda tidak dapat memperbaiki masalah dari kurangnya kontrol versi sebelumnya, tetapi setidaknya menghentikan masalah dari melanjutkan ke masa depan.

Selanjutnya, lihat ke logging. Temukan, atau kasus terburuk, tulis sistem pencatatan, dan mulailah menggunakannya. Gunakan satu yang dapat digunakan di situs klien juga, jadi ketika segala sesuatunya berjalan ke samping Anda memiliki setidaknya sesuatu.

Dan mulailah menulis tes, setidaknya untuk perubahan baru yang Anda buat.

Tidak ada lapisan gula: tidak ada jawaban di sini yang tidak melibatkan banyak pekerjaan, atau memperlakukan ini sebagai masalah karier.


Percayalah, saya ingin tidak lebih dari menambahkan pernyataan, penjaga, dan pencatatan, mungkin menulis ulang lapisan data juga (saya sedang menulis validator konfigurasi untuk mendiagnosis masalah konfigurasi yang khas). Sayangnya itu tidak terserah saya. Saya dapat membuat permintaan untuk memasukkan sesuatu ke dalam sumber yang aman, tetapi respons umum adalah 'niat Anda baik, tetapi ini bukan sesuatu yang harus kami fokuskan'. Sayangnya, saya hanyalah seorang junior dengan pengalaman 1/2 tahun. Saya akan mendaki gunung ini sebentar.
Igneous01

9
@ Igneous01 Sejujurnya, cobalah mencari gunung lain untuk didaki. Kondisi kerja di tempat lain mungkin tidak sempurna, tetapi saya kira setidaknya sebagian besar secara signifikan lebih baik daripada apa yang Anda alami. Jika penjaga gerbang Anda menolak peningkatan Anda dengan "ini bukan sesuatu yang harus kita fokuskan", itu keputusan mereka untuk membuat, dan mereka akan menuai hasil dari kebijakan yang gagal itu (mereka sudah kehilangan banyak uang karena kehilangan waktu pengembangan) . Pertanyaannya adalah, apakah Anda ingin tetap bersama mereka sampai mereka melakukannya?
cmaster - mengembalikan monica

6
Dan perlu diingat bahwa ketika kebijakan buruk gagal, semua orang yang terlibat terlihat buruk, bahkan mereka yang tidak setuju.
Gort the Robot

1
Yup, mulai logging & tracing. Juga mulai mendokumentasikan, dan menambahkan komentar. Sedikit demi sedikit, semuanya akan bertambah. Juga, Anda mengatakan bahwa Anda cukup beruntung masih memiliki beberapa coders asli di perusahaan, jika bukan tim. Dorong manajemen untuk mendapatkan akses kepada mereka. Jika memungkinkan, bujuk mereka bahwa mereka lebih suka menghasilkan beberapa dokumen daripada didekati dengan pertanyaan.
Mawg mengatakan mengembalikan Monica

4
@ Igneous01: Lari, jangan berjalan. Tempat ini sakit dan akan membuatmu sakit.
Pasang kembali Monica - M. Schröder

8

1) Debugger tidak dapat digunakan di situs klien ...

Itu sangat normal.

... atau secara lokal

Nah, itu masalahnya.

2) Hampir tidak ada penebangan yang dilakukan di aplikasi kami.

Logging adalah Debugging Produksi.

Tidak ada tes unit.

Oh sayang. Tapi semuanya sama saja.

3) Kontrol versi hanya memiliki 1 versi dari solusi lengkap

Maka Anda tidak menggunakan Kontrol Versi.

4) Tidak dapat mereproduksi secara lokal, sering kali tidak dapat mereproduksi pada lingkungan pengujian (Kemungkinan besar pengujian dan produksi bukan versi yang sama).

Jadi hanya yang digunakan, lingkungan klien menunjukkan kesalahan.

Dalam hal ini, Anda memerlukan pencatatan disgnostik yang tertanam dalam kode aplikasi yang (a) memerangkap dan [sepenuhnya] mencatat kesalahan [fatal] dan (b) dapat "dihidupkan" berdasarkan permintaan untuk menghasilkan diagnostik tambahan, terus-menerus, yang berguna dalam melacak masalah.

5) Ada kemungkinan besar bahwa versi yang digunakan klien berbeda dari yang ada di sumber aman.

Sekali lagi, Anda tidak menggunakan kontrol versi untuk keuntungan Anda.

8) Aplikasi kami sangat bisa dikustomisasi

Itu cukup tipikal.

Perbedaan spesifik situs harus dikelola melalui Kontrol Versi "Percabangan".

9) Hampir tidak ada komentar dalam kode.

Sekali lagi, itu terlalu umum, karena Pengembang menulis kode "mendokumentasikan sendiri", bukan?
Atau, setidaknya, kode yang mereka pahami pada hari mereka menulisnya.

Tidak ada dokumentasi tentang arsitektur.

Oh sayang.

Tidak ada dokumentasi tentang api.

Oh sayang, oh sayang.

Dan sebelum Anda mengatakannya ... ya saya tahu; Saya ingin menembak diri sendiri juga.

Tidak; Anda ingin menembak orang-orang yang menulis semua hal ini, menciptakan kekacauan yang tidak berdokumen, tidak dapat dipelihara, dan kemudian pindah ke padang rumput yang baru, meninggalkan kekacauan yang tidak masuk akal di belakang mereka.

Jenis kesalahan paling umum yang saya temui adalah kesalahan referensi nol, gips yang tidak valid, dan fungsi yang hilang / ketidakcocokan tanda tangan fungsi.

Referensi kosong dan gips yang tidak valid adalah kesalahan run-time; sampai batas tertentu, Anda harus mengharapkan mereka dan fakta bahwa Anda mendapatkannya sering menunjukkan kurangnya pemrograman defensif (atau surplus optimisme) oleh penulis asli.

Ketidaksesuaian fungsi tanda tangan harus menyebabkan patah membangun ; itu harus menyebabkan "bangunan rusak" dan tidak boleh keluar dari pintu!


2
"Selalu kode seolah-olah orang yang akhirnya mempertahankan kode Anda adalah seorang psikopat kejam yang tahu di mana Anda tinggal"
PerryC

Kesalahan runtime lebih disebabkan oleh kurangnya pemahaman daripada kurangnya pemrograman defensif. Pemrograman defensif hanyalah cara menyembunyikan fakta bahwa kode tidak berfungsi.
user253751

1
"Tidak ada dokumentasi tentang arsitektur" biasanya berarti "tidak ada arsitektur" ...
gnasher729

The site-specific differences should be managed through Version Control "Branching".- Saya tidak berpikir ini adalah cara terbaik untuk melanjutkan. Menggunakan file konfigurasi dan fitur toggle tampaknya lebih umum dan lebih mudah untuk dipikirkan.
sixtyfootersdude

5

Mulai dengan pencatatan. Ini akan memiliki dampak terbesar. Menerapkan kerangka kerja logging ke basis kode, seperti Log4Net atau serupa. Mulai mencatat apa yang dilakukan kode.

Debugging harus dimungkinkan secara lokal. Jika tidak, berusahalah mendapatkan file simbol (PDBs) sehingga Anda dapat men-debug ke dll pihak ke-3 untuk mendapatkan gambaran lengkap tentang masalah yang terjadi. Alat seperti WINDBG dapat menunjukkan DLL mana yang bermasalah jika sistem macet. Seseorang dapat mengkonfigurasi server mana saja untuk mengambil dump memori ketika ada kerusakan. Ini pada dasarnya snapshot dari apa yang terjadi ketika masalah terjadi. Orang dapat memeriksa kesedihan secara lokal untuk menemukan petunjuk tentang apa yang terjadi. Jika debugging tidak memungkinkan, berusahalah untuk membuatnya mungkin. Dokumentasikan langkah-langkah yang diperlukan untuk debug. Kadang pada sistem yang kompleks, ada cukup banyak pengaturan yang diperlukan untuk debug penuh.

Pelacakan bug ... Jika Anda tidak menggunakannya, mulailah menggunakannya. Ini berjalan seiring dengan sistem kontrol versi yang tepat. Pada dasarnya, mulailah melacak cacat dan revisi kode Anda. Mulai untuk membangun sejarah sistem.

Lakukan Analisis Kode Statis. Investasikan dalam alat seperti ReSharper. Ini akan dengan cepat menunjukkan semua kemungkinan pengecualian referensi nol dan praktik pengkodean buruk lainnya. Ini dapat membantu mendapatkan kode dalam bentuk yang lebih baik hanya dengan beberapa klik dan mengotomatiskan item yang membosankan seperti pemformatan kode, penamaan variabel, dll. Ukur kode Anda, cari tahu di mana hot spot untuk refactoring melalui metrik kode.

Tes Unit dan Refactor. Saya akan berasumsi bahwa mungkin sebagian besar kode yang ditulis tidak terlalu dapat diuji, jadi saya tidak akan repot-repot mencoba menambahkan tes untuk itu. Kode baru apa pun, buat proyek tes dan mulailah menulis tes, baik unit maupun integrasi. Jika tes unit gagal, gagal membangun. Jadi, ketika Anda refactor, harus ada tes. Satu hal dengan tes adalah bahwa seseorang dapat menulis tes untuk memanggil metode apa saja dan debug ke dalam metode itu tanpa memuat seluruh aplikasi atau basis kode. Ini berguna untuk membantu memecahkan masalah.

Dokumentasikan pengetahuan suku apa pun sesuai kebutuhan. Kode harus mendokumentasikan diri sendiri sehingga komentar jadi jarang, tetapi banyak sistem memiliki cara "tidak biasa" dalam melakukan sesuatu, tunjukkan hal itu dalam WIKI pengkodean atau jenis penyimpanan informal lainnya. Juga, pertimbangkan untuk membuat standar dan praktik pengkodean. Menegakkan standar-standar tersebut melalui toolset seperti Resharper. Karena sebagian besar kode mungkin tidak mengikuti standar dan pedoman apa pun, terapkan standar pada kode baru yang ditulis.

Sejak Anda baru, saya akan memperlakukan ini seperti tur tugas. 6 bulan hingga 2 tahun, dan kemudian tentukan pilihan untuk tetap atau melanjutkan. Ambil kepuasan dari membuat sesuatu sedikit lebih baik dari hari sebelumnya.


4

Pertama, semua yang di atas ... ditto.

Beberapa heuristik:

  • Gunakan kontrol sumber pada komputer pengembangan Anda. Itu hal terbaik yang pernah saya lakukan. Ini bukan pengganti untuk kontrol versi proyek, yang kami miliki. Ini adalah alat yang memberikan kebebasan luar biasa untuk bereksperimen, meretas, menyelesaikan masalah secara simultan namun mandiri, dll. Saya lebih baik dalam menggunakan kontrol versi karena saya memiliki kebebasan untuk berani, gagal, dan belajar.
  • Sejauh Anda menambahkan komentar, memprioritaskan elemen antarmuka publik, untuk memanfaatkan intellisense. Lakukan ini saat Anda menguraikan selama petualangan debug Anda.
  • Tetap gigih dengan refactoring kecil. Cepat atau lambat, untuk sebongkah kode yang diberikan, Anda akan mendapatkan massa kritis yang memungkinkan refactoring besar seperti MENGURANGI kode berlebihan di seluruh kelas.
  • Jangan mencampur pemformatan ulang kode dan perubahan aktual dalam kontrol versi yang sama dilakukan.
  • Prinsip-prinsip SOLID
    • Jangan pernah mengabaikan tanggung jawab tunggal. Bagus sekali, ini adalah jalan menuju janji berorientasi objek; MENURUT OPINI SAYA.
    • Selalu abaikan Open / Closed.
    • Kami tidak berbicara kode baru di sini.
    • Membuat antarmuka tanpa desain yang disengaja menghambat pemeliharaan.
  • Refactoring
  • Beberapa file kode memerlukan pemformatan ulang yang lengkap, penggantian nama variabel, dll. Bahkan sebelum mencoba debugging. Jangan malu menggunakan menu refactor studio visual tanpa unit test.
  • Satu-satunya dokumentasi yang tidak dapat salah tempat adalah dalam file kode.
  • Ketika Anda mendapatkan kontrol versi berikan pemikiran untuk rencana VC. Dan dokumentasikan! Dan datang dengan konvensi penamaan untuk cabang, tag yang akan menyoroti versi perangkat lunak dan tonggak sejarah.
  • Gunakan peralatan yang bagus
  • Berlatih Debugging Bebek Karet
  • Terkadang hal terburuk yang bisa terjadi adalah mereka tidak memecat Anda.

Edit

Pengembangan Aplikasi Brownfield di .NET

Coba buku ini. Sampul awal untuk sampul membaca mungkin yang terbaik. Buku ini akan membantu Anda memikirkan gambaran besar, kemungkinan, dan mengembangkan rencana serangan strategis dan taktis.

Menjulurkannya

Tetap, katakanlah, 1,5 tahun jika Anda bisa; cukup lama untuk mengetahui apakah Anda membuat kemajuan berdasarkan pengalaman. Anda akan tahu jika Anda mendapatkan 2 tahun pengalaman atau 6 bulan pengalaman 4 kali.

Menjadi "junior dengan pengalaman 1/2 tahun" Saya khawatir bahwa calon majikan akan melihatnya sebagai bail out lebih awal karena Anda tidak bisa meretasnya. Satu hal untuk mengatakan Anda belajar z, y, x, mengambil beberapa nama dan menendang beberapa pantat - tetapi tidak diizinkan untuk berkontribusi pada kemampuan Anda; dan yang lain hanya beresiko mengabaikan pekerjaan, kode, manajemen, dll dengan penjelasan.

Saya mungkin tidak paham tentang hal ini tetapi "waktu terbaik dan terburuk" saya adalah pekerjaan pertama saya, yang kebetulan merupakan kode yang benar-benar tidak dapat dipertahankan. Saya memiliki penyelia yang hebat (sisanya dari program in-breeding manajemen) yang memberi saya ruang untuk menulis ulang beberapa program utama. Pengalaman itu adalah wahyu.

end Edit


+1 untuk Jangan gabungkan pemformatan ulang kode dan perubahan aktual dalam komitmen kontrol versi yang sama.- saran bagus
kiwiron

0

Saya akan mengatakan (5) adalah yang harus Anda perbaiki dulu. Jika Anda tidak tahu kode mana yang berjalan dalam produksi, Anda tidak memiliki cara yang aman untuk mereproduksi dan memperbaiki masalah. Ini membuat perubahan lain yang Anda buat berbahaya, karena dapat menyebabkan masalah yang tidak dapat Anda perkirakan dan tidak dapat direproduksi.

Anda mungkin perlu melakukan beberapa pekerjaan detektif dan mungkin melakukan rekayasa balik untuk mengetahui versi kode mana dan perpustakaan mana yang digunakan. (Dan Anda perlu memiliki sistem build dan deploy yang konsisten untuk membawa semua kode yang digunakan sejalan dengan kontrol sumber ke depan.)

Anda mungkin harus membangun beberapa lingkungan pengujian untuk mereplikasi berbagai penerapan. (Tentu saja perbaikan paling sederhana adalah dengan membuat bangunan bersih baru dan menyebarkannya secara konsisten di mana-mana, tetapi sepertinya ini tidak mungkin?)

Hanya ketika Anda mengetahui versi yang tepat dikerahkan dan memiliki lingkungan pengujian yang sesuai, Anda harus mulai mencoba memperbaiki / meningkatkan kode.

Prioritas Anda berikutnya adalah untuk mengkonsolidasikan ke basis kode tunggal yang dapat digunakan di mana-mana. Sepertinya Anda memiliki berbagai versi kode yang digunakan karena penyesuaian? Anda harus menggabungkan ke versi tunggal dan kemudian menggunakan sakelar konfigurasi untuk logika khusus.

Setelah ini, Anda dapat mulai meningkatkan basis kode dengan hati-hati untuk memudahkan proses debug. Menambahkan logging mungkin merupakan peningkatan yang paling tidak berisiko.

Anda akan ingin menambahkan tes otomatis, tetapi unittests seringkali sulit ditambahkan ke proyek yang awalnya tidak dirancang untuk pengujian. Sebagai gantinya saya merekomendasikan memulai dengan tes integrasi end-to-end otomatis. Ini lebih sulit untuk diatur, tetapi tidak mengharuskan Anda untuk merancang ulang solusinya, sehingga kurang berisiko.


0

Mengabaikan masalah yang Anda miliki di tim Anda, tampaknya yang pertama kali ditangani adalah men-debug kode yang cocok dengan yang ada di produksi. Kalau tidak, Anda mungkin mengejar bug yang sudah diperbaiki dalam kode yang Anda miliki di "Kontrol sumber" Anda. Karena ini. NET, Anda dapat dengan mudah "mendekompilasi" binari produksi untuk membandingkan kode dengan apa yang Anda miliki. Ini bukan tugas yang mudah tetapi jika Anda berhasil ini adalah argumen yang kuat untuk alat kontrol sumber yang lebih baik yang dapat menandai versi yang dirilis.


Ketika Anda bermaksud mendekompilasi, maksud Anda menggunakan sesuatu seperti IDA Pro untuk melihat kode mesin? Saya mungkin akan menjadi satu-satunya yang menggunakannya karena tidak ada yang tahu perakitan (dan saya tahu dasar-dasarnya).
Igneous01

Nah, karena ini .NET, binari bukan kode mesin, mereka berada di CIL ( en.wikipedia.org/wiki/Common_Intermediate_Language ). Ini dapat dengan mudah dan akurat dikonversi kembali ke kode c # atau VB, terutama jika tidak dikaburkan. Anda dapat mencobanya dengan ILSpy misalnya ( ilspy.net ) tetapi mungkin ada alat lain yang bisa Anda gunakan.
20c
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.