Membaca komentar untuk jawaban ini , khususnya:
Hanya karena Anda tidak dapat menulis tes tidak berarti itu tidak rusak. Perilaku tidak terdefinisi yang biasanya bekerja sesuai yang diharapkan (C dan C ++ penuh dengan itu), kondisi balapan, potensi pemesanan ulang karena model memori yang lemah ... - CodesInChaos 7 jam yang lalu
@CodesInChaos jika tidak dapat direproduksi maka kode yang ditulis untuk 'fix' juga tidak dapat diuji. Dan menempatkan kode yang belum diuji ke dalam hidup adalah kejahatan yang lebih buruk menurut saya - RhysW 5 jam yang lalu
... membuat saya bertanya-tanya apakah ada cara umum yang baik untuk secara konsisten memicu sangat jarang terjadi masalah produksi yang disebabkan oleh kondisi balapan dalam test case.
testing
multithreading
Dan Neely
sumber
sumber
Jawaban:
Setelah berkecimpung dalam bisnis gila ini sejak sekitar 1978, menghabiskan hampir semua waktu itu dalam komputasi waktu-nyata yang disematkan, bekerja multitasking, multithreaded, sistem multi-apa pun, kadang-kadang dengan beberapa prosesor fisik, mengejar lebih dari sekadar bagian ras yang adil. kondisi, pendapat saya yang dipertimbangkan adalah bahwa jawaban untuk pertanyaan Anda cukup sederhana.
Tidak.
Tidak ada cara umum yang baik untuk memicu kondisi balapan dalam pengujian.
Satu-satunya harapan Anda adalah mendesain mereka sepenuhnya dari sistem Anda.
Kapan dan jika Anda menemukan orang lain memasukkannya, Anda harus menaruhnya di sarang semut, dan kemudian mendesain ulang untuk menghilangkannya. Setelah Anda mendesain kecerobohannya (diucapkan f *** up) dari sistem Anda, Anda bisa melepaskannya dari semut. (Jika semut telah memakannya, hanya menyisakan tulang, pasang tanda bertuliskan "Inilah yang terjadi pada orang yang memasukkan kondisi ras ke dalam proyek XYZ!" Dan TINGGALKAN DIA.)
sumber
Jika Anda berada di rantai alat ms. Penelitian Ms telah menciptakan alat yang akan memaksa interlevings baru untuk setiap lari dan dapat diciptakan kembali gagal menjalankan catur yang disebut .
di sini adalah video yang menunjukkan itu digunakan.
sumber
Alat terbaik yang saya tahu untuk masalah seperti ini adalah perpanjangan Valgrind yang disebut Helgrind .
Pada dasarnya Valgrind mensimulasikan prosesor virtual dan menjalankan biner Anda (tidak dimodifikasi) di atasnya, sehingga dapat memeriksa setiap akses tunggal ke memori. Menggunakan kerangka kerja itu, sistem arloji Helgrind menyerukan untuk menyimpulkan ketika akses ke variabel bersama tidak dilindungi dengan baik oleh mekanisme saling pengecualian. Dengan begitu ia dapat mendeteksi kondisi ras teoretis bahkan jika itu belum benar-benar terjadi.
Intel menjual alat yang sangat mirip yang disebut Intel Inspector .
Alat-alat ini memberikan hasil yang bagus tetapi program Anda akan jauh lebih lambat selama analisis.
sumber
Mengekspos bug multi-threading membutuhkan pemaksaan utas eksekusi yang berbeda untuk melakukan langkah-langkah mereka dalam urutan tertentu. Biasanya ini sulit dilakukan tanpa debugging manual atau memanipulasi kode untuk mendapatkan semacam "pegangan" untuk mengontrol interleaving ini. Tetapi mengubah kode yang berperilaku tak terduga seringkali akan memengaruhi ketidakpastian itu, jadi ini sulit untuk diotomatisasi.
Trik yang bagus dijelaskan oleh Jaroslav Tulach dalam Praktis Desain API : jika Anda memiliki pernyataan logging dalam kode yang dipertanyakan, memanipulasi konsumen dari pernyataan logging tersebut (misalnya terminal pseudo-disuntikkan) sehingga menerima pesan log individu dalam suatu tertentu memesan berdasarkan konten mereka. Ini memungkinkan Anda untuk mengontrol interleaving langkah-langkah di utas yang berbeda tanpa harus menambahkan apa pun ke kode produksi yang belum ada di sana.
sumber
Tidak ada cara untuk benar-benar memastikan berbagai jenis perilaku yang tidak terdefinisi (dalam kondisi ras tertentu) tidak ada.
Namun, ada sejumlah alat yang menunjukkan sejumlah situasi seperti itu. Anda mungkin dapat membuktikan bahwa ada masalah saat ini dengan alat tersebut, meskipun Anda tidak dapat membuktikan bahwa perbaikan Anda valid.
Beberapa alat menarik untuk tujuan ini:
Valgrind adalah pemeriksa memori. Ia menemukan kebocoran memori, pembacaan memori yang tidak diinisialisasi, penggunaan pointer menggantung dan akses di luar batas.
Helgrind adalah pemeriksa keamanan utas. Ia menemukan kondisi balapan.
Keduanya bekerja dengan instrumentasi dinamis, yaitu mereka mengambil program Anda apa adanya dan menjalankannya dalam lingkungan yang tervirtualisasi. Ini membuat mereka tidak mengganggu, tetapi lambat.
UBSan adalah pemeriksa perilaku yang tidak ditentukan. Ia menemukan berbagai kasus perilaku tidak terdefinisi C dan C ++, seperti integer overflows, out-of-range shift dan hal-hal serupa.
MSan adalah pemeriksa memori. Ini memiliki tujuan yang sama dengan Valgrind.
TSan adalah pemeriksa keamanan utas. Ini memiliki tujuan yang sama dengan Helgrind.
Ketiganya dibangun ke dalam kompiler Dentang dan menghasilkan kode pada waktu kompilasi. Ini berarti bahwa Anda perlu mengintegrasikan mereka ke dalam proses build Anda (khususnya, Anda harus mengkompilasi dengan Dentang), yang membuat mereka jauh lebih sulit untuk diatur daripada * grind, tetapi di sisi lain mereka memiliki overhead runtime yang jauh lebih rendah.
Semua alat yang saya daftarkan berfungsi di Linux dan beberapa di MacOS. Saya belum berpikir ada pekerjaan di Windows andal.
sumber
Tampaknya sebagian besar jawaban di sini keliru dengan pertanyaan ini sebagai "bagaimana cara saya mendeteksi kondisi lomba secara otomatis?" ketika pertanyaannya adalah "bagaimana cara mereproduksi kondisi balapan dalam pengujian saat saya menemukannya?"
Cara melakukannya adalah dengan memperkenalkan sinkronisasi dalam kode Anda yang hanya digunakan untuk pengujian. Misalnya, jika kondisi balapan terjadi ketika Peristiwa X terjadi di antara Peristiwa A dan Peristiwa B, maka untuk menguji aplikasi Anda, tulis beberapa kode yang menunggu Peristiwa X terjadi setelah Peristiwa A terjadi. Anda mungkin perlu beberapa cara agar tes Anda berbicara dengan aplikasi Anda untuk memberi tahu ("hei saya sedang menguji hal ini, jadi tunggu acara ini di lokasi ini").
Saya menggunakan node.js dan mongo, di mana beberapa tindakan melibatkan pembuatan data yang konsisten dalam beberapa koleksi. Dalam kasus ini, pengujian unit saya akan melakukan panggilan ke aplikasi untuk mengatakan "mengatur tunggu untuk Acara X", dan setelah aplikasi mengaturnya, tes untuk acara X akan berjalan, dan tes selanjutnya akan memberi tahu aplikasi ("saya sudah selesai dengan menunggu Acara X") sehingga sisa tes akan berjalan normal.
Jawabannya di sini menjelaskan hal semacam ini secara terperinci dalam konteks python: https://stackoverflow.com/questions/19602535/how-can-i-reproduce-the-race-conditions-in-this-python-code- andal
sumber