Apa itu Misra dan bagaimana cara memasaknya

Gambar 2

Mungkin setiap pengembang perangkat lunak mikrokontroler telah mendengar tentang standar pengkodean khusus untuk membantu meningkatkan keamanan dan portabilitas kode. Salah satu standar tersebut adalah MISRA. Pada artikel ini, kita akan melihat lebih dekat apa standar ini, konsepnya dan bagaimana menggunakannya dalam proyek Anda.

Banyak pembaca kami telah mendengar bahwa PVS-Studio mendukung klasifikasi peringatannya sesuai dengan standar MISRA. Saat ini, PVS-Studio mencakup lebih dari 100 aturan MISRA C: 2012 dan MISRA C ++: 2008.

Artikel ini bertujuan untuk membunuh tiga burung dengan satu batu:

  1. Katakan apa MISRA untuk mereka yang belum terbiasa dengan standar ini;
  2. Ingatkan dunia pengembangan tertanam apa yang bisa kita lakukan;
  3. Bantu karyawan baru di perusahaan kami, yang juga akan mengembangkan alat analisa MISRA kami di masa depan, untuk sepenuhnya mengenalnya.

Saya harap saya bisa membuatnya menarik. Jadi ayo pergi!

Sejarah misra


Sejarah MISRA dimulai sejak lama. Saat itu di awal 1990-an, program "TI Aman" pemerintah Inggris menyediakan dana untuk berbagai proyek yang entah bagaimana terkait dengan keamanan sistem elektronik. Proyek MISRA (Asosiasi Keandalan Perangkat Lunak Industri Sepeda Motor) sendiri didirikan untuk membuat panduan untuk mengembangkan perangkat lunak mikrokontroler di kendaraan darat - di mobil, sebagian besar.

Setelah menerima dana dari negara, tim MISRA mulai bekerja, dan pada November 1994 merilis panduan pertama mereka: " Pedoman pengembangan perangkat lunak berbasis kendaraan ". Panduan ini belum dikaitkan dengan bahasa tertentu, tetapi saya harus mengakui bahwa pekerjaan telah dilakukan secara mengesankan dan telah memperhatikan, mungkin, semua aspek yang mungkin dari pengembangan perangkat lunak tertanam. Ngomong-ngomong, baru-baru ini para pengembang panduan ini telah merayakan ulang tahun ke 25 dari tanggal yang begitu penting bagi mereka.

Ketika dana dari negara berakhir, anggota MISRA memutuskan untuk terus bekerja bersama secara informal, seperti yang berlanjut hingga hari ini. Secara umum, MISRA (sebagai organisasi) adalah komunitas pemangku kepentingan dari berbagai industri otomotif dan pesawat terbang. Sekarang pihak-pihak ini adalah:

  • Mobil motor Bentley
  • Ford Motor Company
  • Jaguar land rover
  • Sistem diesel delphi
  • HORIBA MIRA
  • Listrik protein
  • Layanan teknik Visteon
  • Universitas leeds
  • Ricardo uk
  • ZF TRW

Pelaku pasar yang sangat kuat, bukan? Tidak mengherankan, standar terkait bahasa pertama mereka, MISRA C, telah menjadi biasa di kalangan pengembang sistem tertanam kritis. Beberapa saat kemudian, MISRA C ++ muncul. Secara bertahap, versi standar telah diperbarui dan disempurnakan untuk mencakup fitur bahasa baru. Pada tulisan ini, versi saat ini adalah MISRA C: 2012 dan MISRA C ++: 2008.

Konsep utama dan contoh aturan


Fitur MISRA yang paling khas adalah perhatiannya yang luar biasa terhadap detail dan ketelitian ekstrem dalam memastikan keselamatan dan keamanan. Tidak hanya penulis mengumpulkan semua kekurangan C dan C ++ di satu tempat (seperti misalnya, penulis CERT) - mereka juga dengan hati-hati menyusun standar internasional bahasa-bahasa ini dan menulis segala cara untuk membuat kesalahan. Setelah itu, mereka menambahkan aturan tentang keterbacaan kode untuk memastikan kode bersih terhadap kesalahan baru.

Untuk memahami skala keseriusan, mari kita lihat beberapa aturan yang diambil dari standar.

Di satu sisi, ada aturan yang layak dan bermanfaat yang harus selalu diikuti, apa pun tujuan proyek Anda. Sebagian besar, mereka dirancang untuk menghilangkan perilaku yang tidak ditentukan / tidak ditentukan / implementasi-didefinisikan. Sebagai contoh:

  • Jangan gunakan nilai variabel yang tidak diinisialisasi
  • Jangan gunakan pointer ke FILE setelah aliran ditutup
  • Semua fungsi non-batal harus mengembalikan nilai
  • Counter loop tidak boleh dari tipe floating-point
  • dan lainnya.

Di sisi lain, ada aturan, manfaat yang tidak sulit untuk diselami, tetapi yang (dari sudut pandang proyek biasa) dapat sesekali dilanggar:

  • Jangan gunakan goto dan longjmp
  • Setiap peralihan harus diakhiri dengan label default
  • Jangan menulis kode yang tidak terjangkau
  • Jangan gunakan fungsi variadic
  • Jangan gunakan aritmatika alamat (kecuali [] dan ++ )
  • ...

Aturan seperti itu juga tidak buruk, dan dikombinasikan dengan yang sebelumnya, mereka sudah memberikan peningkatan nyata pada keamanan, tetapi apakah ini cukup untuk sistem embedded yang sangat andal? Mereka digunakan tidak hanya dalam industri otomotif, tetapi juga dalam industri penerbangan, kedirgantaraan, militer dan kedokteran.

Kami tidak ingin mesin sinar-X untuk menyinari pasien dengan dosis 20.000 rad karena kesalahan perangkat lunak, sehingga aturan "sehari-hari" yang biasa tidak cukup. Dengan nyawa manusia dan uang dalam jumlah besar, ketelitian sangat diperlukan. Di sinilah aturan MISRA lainnya ikut berperan:

  • Sufiks 'L' dalam literal harus selalu berupa kapital (huruf kecil 'l' dapat dikacaukan dengan 1)
  • Jangan gunakan operator "koma" (ini meningkatkan kemungkinan melakukan kesalahan)
  • Jangan gunakan rekursi (setumpuk mikrokontroler kecil dapat dengan mudah meluap)
  • Badan pernyataan jika , jika lain , untuk , sementara , lakukan , sakelar harus dibungkus dengan kurung keriting (berpotensi Anda dapat membuat kesalahan ketika kode disejajarkan secara salah )
  • Jangan gunakan memori dinamis (karena ada kemungkinan tidak melepaskannya dari tumpukan, terutama di mikrokontroler)
  • ... dan banyak, banyak dari aturan ini.

Sering terjadi, bahwa orang yang pertama kali bertemu MISRA mendapatkan kesan bahwa tujuan standar adalah untuk "melarang ini dan melarang itu." Sebenarnya, memang demikian, tetapi hanya sampai batas tertentu.

Di satu sisi, standar memang memiliki banyak aturan seperti itu, tetapi itu tidak dimaksudkan untuk melarang semuanya, tetapi di sisi lain, standar ini mencantumkan seluruh cara yang entah bagaimana melanggar keamanan kode. Untuk sebagian besar aturan, Anda memilih sendiri apakah perlu mengikuti atau tidak. Saya akan menjelaskan kasus ini secara lebih rinci.

Dalam MISRA C, aturan dibagi menjadi tiga kategori utama: Mandatory, Required, and Advisory. Wajib adalah aturan yang tidak bisa dilanggar dengan dalih apa pun. Misalnya, bagian ini mencakup aturan: "jangan gunakan nilai variabel yang belum diinisiasi." Aturan yang diperlukan kurang ketat: mereka memungkinkan untuk kemungkinan penolakan, tetapi hanya jika penyimpangan ini didokumentasikan dan dibuktikan secara tertulis. Sisa aturan termasuk dalam kategori Penasihat, yang tidak wajib.

MISRA C ++ memiliki beberapa perbedaan: tidak ada kategori Wajib, dan sebagian besar aturan termasuk dalam kategori Wajib. Karena itu, pada kenyataannya, Anda memiliki hak untuk melanggar aturan apa pun - jangan lupa untuk berkomentar semua penyimpangan. Ada juga kategori Dokumen - ini adalah aturan wajib (penyimpangan tidak diizinkan) terkait dengan praktik umum seperti "Setiap penggunaan assembler harus didokumentasikan" atau "Perpustakaan yang disertakan harus mematuhi MISRA C ++".

Masalah lainnya


Faktanya, MISRA bukan hanya tentang seperangkat aturan. Bahkan, itu adalah pedoman untuk menulis kode aman untuk mikrokontroler, dan itu penuh dengan barang. Mari kita lihat lebih dalam.

Pertama-tama, standar berisi deskripsi latar belakang yang cukup menyeluruh: mengapa standar dibuat, mengapa C atau C ++ dipilih, pro dan kontra dari bahasa-bahasa ini.

Kita semua tahu manfaat dari bahasa-bahasa ini dengan sangat baik. Selain kami juga menyadari kekurangan mereka :) Tingkat kerumitan yang tinggi, spesifikasi standar yang tidak lengkap, dan sintaks yang memungkinkan untuk dengan mudah membuat kesalahan dan kemudian mencarinya untuk waktu yang lama - semua ini tidak bisa tidak disebutkan. Misalnya, Anda mungkin secara tidak sengaja menulis ini:

for (int i = 0; i < n; ++i); { do_something(); } 

Lagipula, ada kemungkinan seseorang tidak akan melihat titik koma tambahan , kan? Pilihan lain adalah menulis kode sebagai berikut :
 void SpendTime(bool doWantToKillPeople) { if (doWantToKillPeople = true) { StartNuclearWar(); } else { PlayComputerGames(); } } 

Baik bahwa kasus pertama dan kedua dapat dengan mudah ditangkap oleh aturan MISRA (1 - MISRA C: 13.4 / MISRA C ++: 6.2.1; 2 - MISRA C: 13.4 / MISRA C ++: 6.2.1).

Standar ini berisi deskripsi masalah masalah dan tip tentang apa yang harus diketahui sebelum mengambil tugas tertentu: bagaimana mengatur proses pengembangan sesuai dengan MISRA; cara menggunakan analisis statis untuk memeriksa kepatuhan kode; dokumen apa yang harus dipelihara, bagaimana mengisinya, dan sebagainya.

Lampiran pada bagian akhir juga mencakup: daftar pendek dan ringkasan aturan, daftar kecil kerentanan C / C ++, contoh dokumentasi penyimpangan aturan, dan beberapa daftar periksa yang membantu memilah semua birokrasi ini.

Seperti yang Anda lihat, MISRA bukan hanya seperangkat aturan, tetapi hampir seluruh infrastruktur untuk menulis kode aman untuk sistem tertanam.

Penggunaan dalam proyek Anda


Bayangkan pemandangannya: Anda akan menulis sebuah program untuk sistem embedded yang sangat dibutuhkan dan bertanggung jawab. Atau Anda sudah memiliki program, tetapi Anda perlu "port" ke MISRA. Jadi, bagaimana Anda memeriksa kode Anda untuk kepatuhannya terhadap standar? Apakah Anda benar-benar harus melakukannya secara manual?

Verifikasi kode manual adalah tugas yang tidak mudah dan bahkan berpotensi tidak mungkin. Tidak hanya setiap reviewer harus hati-hati memeriksa setiap baris kode, tetapi juga kita harus tahu standarnya. Gila!

Oleh karena itu, pengembang MISRA sendiri menyarankan untuk menggunakan analisis statis untuk menguji kode Anda. Setelah semua, pada kenyataannya, analisis statis adalah proses tinjauan kode otomatis. Anda cukup menjalankan analisa pada program Anda dan dalam beberapa menit, Anda mendapatkan laporan tentang kemungkinan pelanggaran standar. Itu yang Anda butuhkan, bukan? Yang harus Anda lakukan adalah meninjau log dan memperbaiki peringatan.

Pertanyaan selanjutnya adalah - pada titik mana kita harus mulai menggunakan MISRA? Jawabannya sederhana: semakin cepat semakin baik. Idealnya - sebelum Anda mulai menulis kode sama sekali, karena MISRA mengasumsikan bahwa Anda mengikuti standar untuk seluruh siklus hidup kode Anda.

Yah tidak selalu mungkin untuk menulis sesuai dengan MISRA dari awal. Misalnya, sering kali proyek telah dilaksanakan sebagian atau seluruhnya, tetapi kemudian pelanggan menginginkan proyek memenuhi standar. Dalam hal ini, Anda harus berurusan dengan refactoring menyeluruh dari kode yang ada.

Di situlah perangkap muncul. Saya bahkan akan mengatakan batu bawah air muncul. Apa yang terjadi jika Anda mengambil analisa statis dan memeriksa proyek "biasa" untuk memenuhi standar MISRA? Spoiler: Anda mungkin takut.

Gambar 5


Benar, contoh dalam gambar ini dilebih-lebihkan. Ini menunjukkan hasil memeriksa proyek yang cukup besar yang sebenarnya tidak dimaksudkan untuk bekerja pada mikrokontroler. Namun, saat memeriksa kode yang sudah ada, Anda mungkin mendapatkan satu, dua, tiga, atau bahkan sepuluh ribu peringatan penganalisa. Peringatan baru, dikeluarkan untuk kode baru atau modifikasi, hanya akan hilang dalam banyak peringatan ini.

Jadi, apa yang dapat Anda lakukan? Apakah Anda benar-benar harus menunda semua tugas dan berusaha memperbaiki peringatan lama?

Sebagai pengembang penganalisa statis, kita tahu bahwa begitu banyak peringatan muncul setelah pemeriksaan. Oleh karena itu, kami mengembangkan solusi, yang dapat membantu digunakan langsung dari penganalisa tanpa menghentikan pekerjaan. Solusi ini disebut "basis penekan".

Basis penekan mewakili mekanisme PVS-Studio yang memungkinkan Anda untuk secara besar-besaran menekan pesan penganalisa. Jika Anda memeriksa proyek untuk pertama kalinya dan mendapatkan beberapa ribu peringatan - Anda hanya perlu menambahkannya dalam basis penekan dan proses berikutnya akan memberi Anda nol peringatan.

Dengan cara ini, Anda dapat terus menulis dan mengubah kode seperti biasa, dan dengan melakukan itu, Anda hanya akan menerima pesan tentang bug yang baru saja dibuat di proyek. Jadi, Anda akan mendapatkan manfaat terbesar dari penganalisis di sini dan sekarang, tanpa terganggu oleh penyadap bug lama. Beberapa klik - dan penganalisa diadopsi ke dalam pengembangan Anda! Anda dapat membaca petunjuk terperinci tentang melakukan ini di sini .

Anda mungkin bertanya-tanya: "Tunggu, bagaimana dengan peringatan yang disembunyikan?" Jawabannya cukup sederhana: jangan lupakan dan perbaiki secara bertahap. Misalnya, Anda dapat memuat basis penekan dalam sistem kontrol versi dan hanya memperbolehkan komit yang tidak menambah jumlah peringatan. Dengan demikian, secara bertahap "batu bawah air" Anda cepat atau lambat akan menggiling tanpa meninggalkan bekas.

Oke, analisa sekarang berhasil diadopsi dan kami siap untuk melanjutkan. Apa yang harus dilakukan selanjutnya? Jawabannya jelas - bekerja dengan kode! Tapi apa yang diperlukan untuk bisa menyatakan kepatuhan dengan standar? Bagaimana Anda membuktikan bahwa proyek Anda sesuai dengan MISRA?

Faktanya, tidak ada "sertifikat" khusus yang sesuai dengan kode Anda dengan MISRA. Seperti yang ditentukan standar, pelacakan kepatuhan harus dilakukan oleh dua pihak: pelanggan perangkat lunak dan vendor perangkat lunak. Vendor mengembangkan perangkat lunak yang memenuhi standar dan mengisi dokumen yang diperlukan. Pelanggan, pada gilirannya, harus memastikan bahwa data dari dokumen-dokumen ini benar.

Jika Anda mengembangkan perangkat lunak untuk diri Anda sendiri, maka tanggung jawab untuk memenuhi standar hanya akan berada di pundak Anda :)

Secara umum, untuk membuktikan kepatuhan proyek Anda, Anda akan memerlukan dokumen pendukung. Daftar dokumen yang harus disiapkan oleh pengembang proyek mungkin beragam, tetapi MISRA menawarkan beberapa set sebagai referensi. Mari kita lihat lebih dekat set ini.

Anda membutuhkan hal-hal ini untuk mengajukan kepatuhan standar:

  • Proyek itu sendiri, yang kodenya mematuhi aturan Wajib dan Diperlukan
  • Panduan rencana penegakan
  • Dokumentasi tentang semua peringatan pengumpul dan penganalisa statis
  • Dokumentasi untuk semua penyimpangan dari Aturan yang Diperlukan
  • Ringkasan pedoman kepatuhan

Yang pertama adalah rencana penegakan panduan. Ini adalah tabel Anda yang paling penting, dan berisi referensi ke semua dokumen lainnya. Di kolom pertama adalah daftar aturan MISRA, sisanya, dicatat apakah ada penyimpangan dari aturan tersebut. Tabel ini terlihat seperti ini:

Gambar 1

Standar merekomendasikan membangun proyek Anda dengan beberapa kompiler, serta menggunakan dua atau lebih analisa statis untuk menguji kode Anda untuk kepatuhan. Jika kompiler atau penganalisa mengeluarkan peringatan terkait aturan, Anda harus mencatatnya dalam tabel dan mendokumentasikan poin-poin berikut: mengapa peringatan tidak dapat diperbaiki, apakah itu salah atau tidak, dll.

Jika salah satu aturan tidak dapat diperiksa oleh penganalisa statis, Anda harus melakukan tinjauan kode manual. Prosedur ini juga harus didokumentasikan, setelah itu tautan ke dokumentasi itu harus ditambahkan ke rencana kepatuhan.

Jika kompilator atau penganalisa statis ternyata benar, atau jika ada pelanggaran aturan yang valid selama proses peninjauan kode, Anda harus memperbaikinya atau mendokumentasikannya. Sekali lagi, dengan melampirkan tautan ke dokumentasi di tabel.

Dengan demikian, rencana kepatuhan adalah dokumen yang akan menyediakan dokumentasi untuk setiap penyimpangan yang diidentifikasi dalam kode Anda.

Mari kita secara singkat menyentuh secara langsung mendokumentasikan penyimpangan dari aturan. Seperti yang saya sebutkan, dokumentasi semacam itu hanya diperlukan untuk Aturan yang Diperlukan, karena aturan Wajib tidak dapat dilanggar, dan aturan Penasihat dapat dilanggar tanpa dokumentasi apa pun.

Jika Anda memilih untuk menyimpang dari aturan, dokumentasi harus mencakup:

  • Jumlah aturan yang dilanggar
  • Lokasi pasti dari penyimpangan
  • Validitas penyimpangan
  • Bukti bahwa penyimpangan tidak membahayakan keamanan
  • Konsekuensi potensial bagi pengguna

Seperti yang Anda lihat, pendekatan dokumentasi seperti itu membuat Anda benar-benar bertanya-tanya apakah pelanggaran itu sepadan. Ini dilakukan secara khusus untuk merasakan tidak ada keinginan untuk melanggar aturan yang diperlukan :)

Sekarang tentang ringkasan kepatuhan dengan aturan. Makalah ini, mungkin, akan menjadi yang paling mudah untuk diisi:

Gambar 3

Kolom pusat diisi sebelum Anda mulai bekerja dengan kode, dan yang tepat - setelah proyek Anda siap.

Inilah pertanyaan yang masuk akal: mengapa kategori aturan harus ditentukan, jika sudah ditentukan dalam standar itu sendiri? Faktanya adalah bahwa standar memungkinkan "mempromosikan" aturan ke dalam kategori yang lebih ketat. Misalnya, pelanggan mungkin meminta Anda untuk mengkategorikan aturan Penasihat. "Promosi" seperti itu harus dibuat sebelum bekerja dengan kode, dan ringkasan kepatuhan dengan aturan memungkinkan Anda untuk secara eksplisit mencatatnya.

Sedangkan untuk kolom terakhir, ini cukup sederhana: Anda hanya perlu mencatat apakah aturan itu digunakan, dan jika demikian, apakah ada penyimpangan dari itu.

Seluruh tabel ini diperlukan agar Anda dapat dengan cepat melihat apa yang diprioritaskan oleh aturan dan apakah kode tersebut mematuhinya. Jika Anda tiba-tiba tertarik untuk mengetahui penyebab pasti dari penyimpangan tersebut, Anda selalu dapat beralih ke rencana kepatuhan dan menemukan dokumentasi yang Anda butuhkan.

Gambar 6

Jadi, Anda menulis kode dengan cermat mengikuti aturan MISRA. Anda telah membuat rencana kepatuhan dan mendokumentasikan segala sesuatu yang dapat didokumentasikan, dan Anda telah mengisi resume kepatuhan Anda. Jika memang demikian halnya, maka Anda telah mendapatkan kode yang sangat bersih, sangat mudah dibaca, dan sangat andal yang sekarang Anda benci :)

Di mana program Anda akan tinggal sekarang? Di perangkat MRI? Dalam sensor kecepatan biasa atau dalam sistem kontrol beberapa satelit luar angkasa? Ya, Anda sudah melalui jalur birokrasi yang serius, tapi itu bukan masalah besar. Ketika datang ke kehidupan manusia yang nyata, Anda harus selalu teliti.

Jika Anda telah mengatasi dan berhasil mencapai kemenangan, maka saya dengan tulus mengucapkan selamat kepada Anda: Anda menulis kode aman berkualitas tinggi. Terima kasih

Masa depan standar


Untuk penutup, saya ingin memikirkan masa depan standar.

Sekarang Misra hidup dan berkembang. Misalnya, "MISRA C: 2012 Edisi Ketiga (Revisi Pertama)" adalah revisi dan diperbesar dengan edisi peraturan baru yang diumumkan pada awal 2019. Pada saat yang sama, rilis mendatang "MISRA C: 2012 Amendemen 2 - C11 Core ”, yang merupakan standar revisi tahun 2012, diumumkan. Dokumen ini akan mencakup aturan yang untuk pertama kalinya mencakup versi bahasa C 2011 dan 2018 tahun.

MISRA C ++ terus berkembang juga. Seperti yang Anda ketahui, standar terakhir MISRA C ++ bertanggal 2008, jadi versi tertua bahasa yang dicakupnya adalah C ++ 03. Karena itu, ada standar lain yang mirip dengan MISRA, dan itu disebut AUTOSAR C ++. Ini awalnya dimaksudkan sebagai kelanjutan dari MISRA C ++ dan dimaksudkan untuk mencakup versi bahasa selanjutnya. Tidak seperti dalangnya, AUTOSAR C ++ diperbarui dua kali setahun dan saat ini mendukung C ++ 14. Pembaruan C ++ 17 baru dan kemudian C ++ 20 belum datang.

Mengapa saya mulai berbicara tentang standar lain? Faktanya adalah bahwa kurang dari setahun yang lalu, kedua organisasi mengumumkan bahwa mereka akan menggabungkan standar mereka menjadi satu. MISRA C ++ dan AUTOSAR C ++ akan menjadi standar tunggal, dan mulai sekarang mereka akan berevolusi bersama. Saya pikir itu berita bagus untuk pengembang yang menulis untuk mikrokontroler di C ++, dan tidak kurang berita bagus untuk pengembang penganalisa statis. Masih banyak yang harus dilakukan! :)

Kesimpulan


Mudah-mudahan hari ini Anda belajar banyak tentang MISRA: membaca sejarah asalnya, mempelajari contoh aturan dan konsep standar, mempertimbangkan semua yang Anda perlukan untuk menggunakan MISRA dalam proyek Anda, dan bahkan melihat sekilas masa depan. Saya harap sekarang Anda memiliki pemahaman yang lebih baik tentang apa MISRA itu dan bagaimana cara memasaknya!

Dalam tradisi lama, saya akan meninggalkan di sini tautan ke penganalisa statis PVS-Studio kami. Ia dapat menemukan tidak hanya penyimpangan dari standar MISRA, tetapi juga sejumlah besar kesalahan dan kerentanan. Jika Anda tertarik untuk mencoba PVS-Studio sendiri, unduh versi demo dan periksa proyek Anda.

Di situlah artikel saya berakhir. Saya berharap semua pembaca selamat Natal dan selamat liburan Tahun Baru!

Source: https://habr.com/ru/post/id482486/


All Articles