Rumah > Operasi dan penyelenggaraan > Keselamatan > Kajian kes Google tentang membina alat analisis kod statik

Kajian kes Google tentang membina alat analisis kod statik

WBOY
Lepaskan: 2023-06-05 22:22:59
ke hadapan
1371 orang telah melayarinya

Pepijat perisian memerlukan banyak masa dan wang bagi pembangun dan syarikat perisian. Mengambil 2014 sebagai contoh, pepijat ("goto fail") dalam pelaksanaan protokol SSL yang digunakan secara meluas menyebabkan sijil SSL tidak sah diterima, dan pepijat lain yang berkaitan dengan pemformatan tarikh menyebabkan gangguan perkhidmatan yang meluas di Twitter. Ralat sebegini selalunya boleh dikesan oleh analisis statik Malah, ia boleh dikenal pasti dengan cepat semasa membaca kod atau dokumentasi, dan realiti terakhir ialah situasi itu masih berlaku dalam persekitaran pengeluaran.

Kerja sebelumnya telah melaporkan pengalaman yang baik dalam menggunakan alat pengesanan pepijat pada pembangunan perisian. Walau bagaimanapun, walaupun terdapat begitu banyak kes pembangun yang berjaya menggunakan alat analisis statik, masih terdapat sebab berikut mengapa jurutera tidak sentiasa bersedia menggunakan alat analisis statik atau secara aktif mengabaikan maklumat amaran yang dijana oleh alatan:

  • Tidak disepadukan dengan betul. Alat ini tidak disepadukan ke dalam aliran kerja pembangun atau program mengambil masa terlalu lama untuk dijalankan; Kebolehlaksanaan maklumat penggera adalah lemah; Pengguna tidak lagi mempercayai keputusan kerana positif palsu;

  • Senario penggunaan sebenar kecacatan itu tidak jelas. Pepijat yang dilaporkan secara teorinya boleh dilaksanakan, tetapi kecacatannya tidak jelas dalam senario penggunaan sebenar; Membaiki kecacatan kod yang dikesan adalah terlalu mahal atau sebaliknya berisiko; Pengguna tidak memahami maklumat dan prinsip khusus maklumat penggera.

  • Artikel berikut menerangkan cara kami belajar daripada pengalaman dan pelajaran Google sebelum ini dalam menggunakan FindBug untuk analisis bahasa dan kesusasteraan akademik Java, dan akhirnya berjaya membina jurutera perisian di Google seni bina infrastruktur analisis statik kegunaan harian. Menggunakan input daripada jurutera, alatan Google boleh mengesan beribu-ribu isu yang jurutera selesaikan setiap hari sebelum kod bermasalah digabungkan ke dalam repositori kod seluruh syarikat.

  • Dari segi skop alat, kami menumpukan pada penyepaduan analisis statik ke dalam proses pembangunan teras Google dan memberi perkhidmatan kepada majoriti pembangun Google. Banyak alat analisis kod statik akan dikecilkan oleh 2 bilion baris kod yang digunakan di Google, jadi teknologi untuk menjalankan analisis kompleks dalam senario berskala besar bukanlah keutamaan yang tinggi.
  • Sudah tentu, ia mesti diambil kira bahawa pembangun di luar Google yang bekerja dalam bidang khusus (seperti aeroangkasa dan peranti perubatan) boleh menggunakan alat analisis statik dan aliran kerja tertentu. Juga pembangun yang projek pembangunannya melibatkan jenis tertentu (seperti kod kernel dan pemacu peranti) mungkin memerlukan kaedah analisis khusus. Terdapat banyak hasil yang sangat baik dalam analisis statik Kami tidak percaya bahawa pengalaman dan cerapan yang telah kami laporkan semula adalah unik, tetapi kami yakin bahawa adalah berfaedah untuk mengatur dan berkongsi kerja kami dalam meningkatkan kualiti kod dan pengalaman pembangunan .

  • Takrif istilah. Kami menggunakan takrif istilah berikut: Alat analisis menjalankan satu atau lebih "pemeriksa" pada kod sumber dan mengenal pasti "kecacatan" yang mungkin menyebabkan kegagalan perisian. Jika pembangun gagal mengambil tindakan proaktif selepas melihat isu, kami menganggapnya sebagai "positif palsu sebenar" jika pembangun menghadapi kecacatan yang dikenal pasti dan tidak mengambil pembetulan yang sewajarnya. Jika analisis statik tidak mengenal pasti kecacatan yang dilaporkan dengan tepat, tetapi pembangun secara proaktif mengambil langkah untuk mengubah suai kod untuk meningkatkan kebolehbacaan dan kebolehselenggaraan, maka ini bukan "positif palsu" yang sah. Jika analisis melaporkan ralat kod sebenar, tetapi pembangun tidak memahami isu kod dan tidak mengambil tindakan, ini dianggap sebagai "positif palsu sebenar." Kami menggunakan perbezaan konsep ini untuk menekankan kepentingan perspektif R&D. Pembangun, bukan pengarang alat, melihat dan secara langsung mempengaruhi kadar positif palsu alat tersebut.
  • Cara Google menyusun dan membina perisian

  • Di bawah kami akan menggariskan perkara utama proses pembangunan perisian Google. Di Google, hampir semua alatan pembangunan (kecuali persekitaran pembangunan) dipusatkan dan diseragamkan. Banyak bahagian infrastruktur dibina dengan Scratch yang dimiliki oleh pasukan dalaman, mengekalkan fleksibiliti untuk menjadi eksperimen.
  • Kawalan kod sumber dan pemilikan kod. Google telah membangunkan dan menggunakan sistem pengurusan kod sumber tunggal. Dan bereksperimen dengan satu cawangan yang menyimpan (hampir) semua kod proprietari Google. Pembangun menggunakan pendekatan pembangunan "berasaskan batang" yang mengehadkan cawangan, selalunya dibahagikan dengan keluaran dan bukannya ciri. Mana-mana jurutera boleh menukar mana-mana kod dengan kelulusan pemilik kod. Pemilikan kod adalah berdasarkan laluan; pemilik direktori mempunyai kebenaran yang sama pada subdirektori.

  • Pembinaan sistem. Semua kod dalam pangkalan kod Google disusun dengan versi Bazel bebas kompilasi, yang bermaksud bahawa semua input mesti diisytiharkan secara eksplisit dan disimpan dalam kawalan sumber untuk memudahkan pengedaran dan penyelarasan binaan dengan mudah. Peraturan Java dalam sistem binaan Google bergantung pada JDK dan pengkompil Java yang dikawal sumber, dan perduaan ini boleh dikemas kini untuk semua pengguna dengan memperkenalkan versi baharu dengan pantas. Binaan biasanya datang daripada sumber (melalui kepala) dan jarang mempunyai komponen binari yang diperiksa ke dalam cawangan. Oleh kerana semua pembangun menggunakan sistem binaan yang sama, sebarang kod boleh disusun dengan jayanya tanpa ralat.

Alat analisis. Alat analisis statik yang digunakan oleh Google biasanya tidak rumit. Infrastruktur Google tidak menyokong menjalankan analisis integriti antara prosedur atau berasaskan program pada sistem pada tahap ini, dan juga tidak menggunakan teknik analisis statik lanjutan (seperti teknologi logik pemisahan) pada skala. Malah penyemak mudah memerlukan infrastruktur analitik untuk menyokong penyepaduan ke dalam aliran kerja. Jenis penganalisis yang telah digunakan sebagai sebahagian daripada proses pembangunan umum termasuk:

  • penyemak gaya (seperti Checkstyle, Pylint dan Golint Penyusun pencarian pepijat lanjutan (seperti Ralat Ralat). , ClangTidy, Clang Thread SafetyAnalysis, Govet dan CheckerFramework), termasuk tetapi tidak terhad kepada alat pemadanan corak pokok sintaks abstrak, penyemak berasaskan jenis dan penganalisis yang mengesan pembolehubah tidak dipanggil.

  • Hubungi pemprofil perkhidmatan pengeluaran (cth. semak jika pekerja yang disebut dalam ulasan kod masih bekerja di Google); Sifat output binaan (seperti saiz binari output).

  • Linter C++ Google boleh menangkap kelemahan "goto fail" dengan menyemak sama ada terdapat kurungan selepas pernyataan if. Penyemak berdasarkan padanan corak akan mengenal pasti ralat pemformatan tarikh, jadi kod yang menyebabkan Twitter ranap tidak akan disusun oleh Google. Pembangun Google juga menggunakan alat analisis dinamik seperti AddressSanitizer untuk mencari kelemahan penimbal dan ThreadSanitizer untuk mencari isu perlumbaan data. Alat ini dijalankan dalam persekitaran dengan ujian dan kadangkala trafik pengeluaran.

  • Persekitaran Pembangunan Bersepadu (IDE). Titik masuk untuk isu analisis statik pada awal proses pembangunan adalah untuk disepadukan ke dalam IDE. Tetapi pembangun Google menggunakan pelbagai jenis editor, jadi sukar untuk secara konsisten mengesan ralat daripada semua pembangun sebelum memanggil alat binaan. Walaupun Google menggunakan analitik yang disepadukan dengan IDE dalaman yang popular, memerlukan IDE khusus yang boleh menganalisis adalah jalan yang panjang dan sukar di hadapan.
  • Ujian. Hampir semua kod Google mengandungi pautan ujian yang sepadan, daripada ujian unit kepada ujian penyepaduan berskala besar. Aktiviti pengujian adalah konsep pertama yang perlu disepadukan dalam pembinaan sistem Sama seperti proses penyusunan, ia adalah bebas dan diedarkan. Untuk kebanyakan projek, pembangun menulis dan menyelenggara kes ujian untuk kod projek biasanya tidak mempunyai kumpulan ujian atau QA yang berasingan.

  • Sistem pembinaan dan ujian berterusan Google akan menjalankan ujian setiap kali kod diserahkan dan akan memberikan maklum balas tepat pada masanya tentang kegagalan binaan atau kes ujian yang gagal disebabkan perubahan kod pembangun. Ia juga menyokong perubahan ujian sebelum membuat komitmen untuk mengelak daripada memecahkan kebergantungan projek.

Semakan kod. Setiap kod yang diserahkan kepada Google akan lulus semakan kod terlebih dahulu. Walaupun mana-mana pembangun boleh membuat perubahan pada mana-mana bahagian kod Google, pemilik kod mesti menyemak dan meluluskan perubahan sebelum ia diserahkan untuk digabungkan. Selain itu, walaupun pemilik kod mesti menyemak kod mereka sebelum melakukan perubahan. Semakan kod dijalankan melalui alat berasaskan web terpusat yang disepadukan rapat dengan infrastruktur pembangunan lain. Keputusan analisis statik boleh dipaparkan dalam ulasan kod.

Keluaran kod. Pasukan Google mengeluarkan keluaran dengan kerap, dan kebanyakan pengesahan keluaran dan proses penempatan diautomatikkan melalui kaedah "tekan pada hijau", yang bermakna sukar untuk bergantung pada proses pengesahan keluaran manual yang susah payah. Jika jurutera Google menemui pepijat dalam pengeluaran, versi baharu boleh digulung semula dan digunakan ke pelayan pengeluaran pada kos yang agak rendah berbanding terpaksa mengganggu perkhidmatan.

Belajar daripada FindBugs

Pada peringkat awal penyelidikan dari 2008 hingga 2010, teknologi analisis statik Google memfokuskan pada penggunaan FindBug untuk analisis Java: diketuai oleh William Pugh dari University of Maryland dan Pennsylvania An alat bebas yang dicipta oleh David Hovemeyer dari York State College. Prinsipnya adalah untuk menganalisis fail kelas Java yang disusun dan mengekstrak model struktur kod yang boleh menyebabkan pepijat. Mulai Januari 2018, FindBugs hanyalah alat baris arahan yang digunakan oleh sebilangan kecil jurutera di Google. Pasukan kecil Google yang dipanggil "BugBot" bekerja dengan pengarang asal Pugh dan membuat tiga percubaan utama untuk menyepadukan FindBugs ke dalam proses pembangunan Google.

Kami mempelajari perkara berikut melalui percubaan:

Cuba 1: Papan pemuka pepijat. Pada mulanya pada tahun 2006, FindBugs telah disepadukan ke dalam alat terpusat untuk mengimbas keseluruhan pangkalan kod Google setiap malam, mengelog keputusan untuk dilihat oleh jurutera melalui papan pemuka. Walaupun FindBugs menemui beratus-ratus ralat dalam pangkalan kod Java Google, papan pemuka mempunyai sedikit kesan kerana papan pemuka mesej ralat dipisahkan daripada proses pembangunan harian dan tidak boleh disepadukan dengan hasil analisis statik sedia ada yang lain.

Percubaan 2: Fokus pada memperbaik pepijat.

Kemudian pasukan BugBot mula mengklasifikasikan secara manual isu baharu yang ditemui setiap malam dan mengenal pasti serta memproses laporan pepijat yang agak penting. Pada Mei 2009, beratus-ratus jurutera Google mengambil bahagian dalam minggu "Betulkan" seluruh syarikat yang memfokuskan pada menyelesaikan makluman FindBugs Sebanyak 3,954 makluman telah disemak (42% daripada jumlah 9,473), tetapi hanya 16% (640) yang ditetapkan. Sebenarnya 44% daripada hasil yang dilaporkan (1746) telah diserahkan untuk penjejakan maklum balas pepijat. Walaupun kempen Fixit mengesahkan bahawa banyak isu yang ditemui oleh FindBugs adalah kecacatan kod sebenar, sebilangan besar tidak cukup penting untuk menjamin pembetulan sebenar. Mengelaskan isu secara manual dan menyerahkan laporan pepijat adalah sukar untuk dikekalkan dalam persekitaran berskala besar.

Cuba 3: Sepadukan ke dalam semakan kod. Seterusnya, pasukan BugBot menyepadukan dan melaksanakan sistem sedemikian: apabila penyemak dimaklumkan bahawa semakan belum selesai, FindBugs akan dijalankan secara automatik dan hasil imbasan akan dipaparkan sebagai ulasan untuk semakan kod di atas telah pun melaksanakan perkara ini untuk isu standard/gaya pengekodan. Pembangun Google boleh mengabaikan positif palsu dan menapis hasil FindBugs untuk kredibiliti. Alat ini selanjutnya cuba untuk memaparkan hanya makluman FindBugs baharu, tetapi kadangkala menganggapnya sebagai isu baharu kerana klasifikasi yang salah. Apabila alat semakan kod diganti pada tahun 2011, penyepaduan ini telah ditamatkan atas dua sebab: kadar positif palsu yang tinggi dalam amalan menyebabkan pembangun hilang keyakinan terhadap alat tersebut dan kebebasan pembangun untuk menyesuaikan penapisan menyebabkan semua pihak mempersoalkan analisis. Hasilnya tidak konsisten.

Digabungkan ke dalam proses penyusunan

Pada masa yang sama dengan percubaan FindBugs, proses pembangunan C++ Google terus bertambah baik dengan menambahkan peraturan semakan baharu pada pengkompil Clang. Pasukan Clang melaksanakan penyemak pengkompil baharu, termasuk maklumat pengesyoran pembetulan, menggunakan ClangMR untuk menjalankan semakan pengoptimuman pengkompil yang dikemas kini merentasi keseluruhan pangkalan kod Google dalam pendekatan yang diedarkan dan pelaksanaan berkod untuk membetulkan pepijat sedia ada dalam soalan pangkalan kod. Setelah pangkalan kod telah ditandakan dengan isu tetap, pasukan Clang menggunakan penyemak baharu untuk membenderakan isu baharu sebagai ralat pengkompil (bukan amaran, yang pasukan Clang mendapati pembangun Google akan mengabaikan) untuk membatalkan binaan, yang mesti ditangani lulus. Pasukan Clang telah sangat berjaya dalam meningkatkan kualiti asas kod melalui strategi ini.

Kami mengikuti idea ini dan membina alat analisis statik Java yang ringkas dan mudah digunakan berdasarkan analisis corak yang dipanggil Ralat Ralat berdasarkan pengkompil javac. Peraturan semakan pertama yang diperkenalkan dipanggil PreconditionsCheckNotNull, yang digunakan untuk mengesan sama ada parameter input pengesanan kaedah kosong pada permulaan program berjalan, seperti checkNotNull ("uid is null", uid) dan bukannya checkNotNull (uid, "uid adalah batal").

Untuk mendayakan pemeriksa seperti PreconditionsCheckNotNull tanpa memecahkan sebarang binaan berturut-turut, pasukan Ralat Ralat menggunakannya untuk menjalankan pemeriksaan sedemikian terhadap keseluruhan pangkalan kod menggunakan program MapReduce berasaskan javac, sama seperti ClangMR, menggunakan panggilan binaan FlumeJava It's JavacFlume . JavacFlume akan menjana satu siri cadangan pembetulan, membandingkan perbezaan, dan kemudian menggunakan pembetulan ini pada keseluruhan pangkalan kod. Pasukan Ralat Rawan menggunakan alat dalaman Rosie untuk memecahkan perubahan kod berskala besar kepada perubahan yang lebih kecil, setiap perubahan hanya akan menjejaskan satu projek, menguji perubahan ini dan menghantarnya kepada pasukan yang sesuai untuk semakan kod. Pasukan hanya menyemak pembetulan yang digunakan pada kod mereka dan hanya jika mereka diluluskan untuk dimasukkan, Rosie akan melakukan perubahan sebenar. Akhirnya, semua pembaikan dan perubahan kepada masalah sedia ada telah diluluskan, dan semua kecacatan sedia ada telah diselesaikan. Pasukan secara rasmi membuka kaedah ralat pengkompil.

Apabila kami meninjau pembangun yang menerima tampung ini, 57% daripada mereka yang menerima pembetulan yang dimasukkan ke dalam kod gembira menerima maklumat sedemikian dan 41% adalah neutral. Hanya 2% orang bertindak balas secara negatif dan berkata: "Ini hanya akan meningkatkan beban kerja saya"

Nilai semakan pengkompil

Ralat kompilasi ditunjukkan pada awal proses pembangunan dan disepadukan ke dalam aliran kerja pembangun . Kami mendapati bahawa memanjangkan penyemak kompil telah meningkatkan kualiti kod di Google dengan berkesan. Oleh kerana semakan dalam Ralat Rawan ditulis secara dalaman terhadap pokok sintaks abstrak javac dan bukannya bytecode (tidak seperti FindBugs), pembangun di luar pasukan boleh membuat semakan dengan agak mudah. Memanfaatkan sumbangan luar ini adalah penting untuk meningkatkan kesan keseluruhan Ralat Ralat. Sehingga Januari 2018, 162 penulis menyumbang 733 dam.

Lebih cepat anda melaporkan isu, lebih baik

Sistem binaan berpusat Google merekodkan semua proses binaan dan hasil binaan, jadi kami memastikan semua pengguna boleh melihat mesej ralat dalam tetingkap masa yang ditentukan. Kami menghantar maklum balas tinjauan kepada pembangun yang baru-baru ini mengalami ralat pengkompil dan kepada pembangun yang telah menerima pengesyoran untuk pembetulan isu yang sama. Pembangun Google percaya bahawa isu yang dibenderakan pada masa penyusunan (berbanding tampalan yang digabungkan menjadi kod) menangkap pepijat yang lebih penting, contohnya, peserta tinjauan percaya bahawa 74% daripada isu telah dibenderakan sebagai "isu sebenar" pada masa penyusunan, manakala Hanya 21% daripada isu ditemui dalam kod yang digabungkan. Selain itu, peserta tinjauan menilai 6% daripada isu yang ditemui pada masa penyusunan (berbanding 0% semasa fasa gabungan) sebagai "kritikal." Keputusan ini boleh dijelaskan oleh "kesan berat sebelah yang terselamat" iaitu, pepijat lebih berkemungkinan ditangkap dengan cara yang lebih mahal (seperti ujian dan semakan kod) pada masa penyerahan kod. Memaksa sebanyak mungkin semakan ke dalam pengkompil adalah cara yang pasti untuk mengelakkan kos ini.

Standard untuk semakan pengkompil

Untuk menskalakan kerja kami, kerana mengganggu kompilasi akan menjadi tindakan yang lebih besar, kami telah menentukan piawaian untuk mendayakan semakan dalam pengkompil, menetapkan Untuk mod anotasi tinggi yang ketat. Semakan pengkompil di Google hendaklah mudah dibaca, boleh diambil tindakan dan mudah dibetulkan (jika boleh, mesej ralat harus menyertakan cadangan pembetulan yang boleh dilaksanakan secara amnya tidak menghasilkan positif palsu yang sah (tindakan analisis tidak boleh mengganggu binaan yang sebenarnya betul) bebas pepijat); kod); dan hanya melaporkan pepijat tulen dan bukannya isu dengan gaya atau konvensyen pengekodan. Matlamat utama mengukur penganalisis yang memenuhi kriteria ini bukan sekadar untuk mengesan masalah, tetapi untuk membetulkan ralat pengkompil ini secara automatik di seluruh pangkalan kod. Tetapi piawaian ini juga mengehadkan skop pemeriksaan yang boleh didayakan oleh pasukan Ralat Ralat semasa menyusun kod;

Memaparkan makluman semasa semakan kod

Setelah pasukan Rawan Ralat telah membina infrastruktur yang diperlukan untuk mengesan isu pada masa penyusunan dan telah membuktikan bahawa ia berfungsi, kami berharap untuk mengetahui lebih lanjut Terdapat banyak -pepijat kesan, dan pepijat tidak terhad kepada pemeriksaan ralat pengkompil yang kami lakukan dan hasil analisis yang kami sediakan untuk bahasa selain Java dan C++. Titik masuk penyepaduan kedua untuk hasil analisis statik ialah alat semakan kod Google - Kritikan keputusan analisis statik dipaparkan dalam Critique, platform analisis program Google, dengan menggunakan Tricorder. Mulai Januari 2018, versi C++ dan Java Google mempunyai ralat pengkompil sifar, dengan semua hasil analisis ditunjukkan dalam ralat pengkompil atau semasa fasa semakan kod.

Kriteria untuk Semakan Semakan Kod

Tidak seperti semakan masa kompilasi, hasil analisis yang dipaparkan semasa semakan kod membolehkan kadar positif palsu berkesan sehingga 10%. Maklum balas yang dijangka semasa semakan kod tidak selalunya sempurna dan pembangun perlu menilai cadangan pembetulan yang sepadan sebelum benar-benar menggunakannya. Penyemak Google semasa fasa audit kod harus memenuhi kriteria berikut:

Mudah difahami. Ia jelas dan mudah difahami untuk jurutera; Pembetulan mungkin memerlukan lebih banyak masa, pemikiran dan usaha daripada fasa semakan pengkompil, dan hasil semakan harus merangkumi panduan tentang cara untuk melayakkan masalah itu; Pembangun harus merasakan bahawa penyemak menjumpai pepijat sebenar sekurang-kurangnya 90% daripada masa itu

mempunyai kesan ketara pada kualiti kod. Isu yang ditemui mungkin tidak menghalang program daripada berjalan dengan betul, tetapi pembangun harus mengambil serius dan memilih untuk membetulkannya.

Sesetengah masalah cukup serius untuk dibenderakan dalam pengkompil, tetapi ia tidak boleh dilakukan untuk mengurangkan atau membangunkan pembetulan automatik. Sebagai contoh, membetulkan beberapa masalah mungkin memerlukan pemfaktoran semula kod. Mendayakan semakan ini sebagai ralat pengkompil memerlukan pembersihan manual pelaksanaan sedia ada, yang tidak boleh dilaksanakan pada asas kod sebesar Google. Alat analisis yang menunjukkan semakan dalam semakan kod ini mengelak daripada memperkenalkan masalah baharu, membolehkan pembangun memutuskan sama ada akan mengambil langkah untuk membuat pembetulan yang sesuai. Semakan kod juga merupakan masa yang sesuai untuk melaporkan isu yang agak tidak penting, seperti isu spesifikasi atau pemudahan kod yang dioptimumkan. Dalam pengalaman kami, pelaporan semasa penyusunan sentiasa sukar untuk diterima oleh pembangun dan menjadikan lelaran dan penyahpepijatan pantas lebih sukar sebagai contoh, pengesan untuk laluan kod yang tidak boleh dicapai mungkin menghalang blok Kod untuk nyahpepijat. Tetapi semasa semakan kod, pembangun sedang bersiap sedia dengan teliti untuk melengkapkan kod mereka, mereka berada dalam minda menerima, lebih menerima isu dengan kebolehbacaan dan butiran gaya.

Tricorder

Tricorder direka bentuk supaya mudah diperluaskan dan menyokong pelbagai jenis alatan analisis atur cara termasuk alatan analisis statik dan dinamik. Kami menunjukkan beberapa penyemak Ralat Rawan dalam Tricorder yang tidak boleh didayakan sebagai ralat pengkompil. Error Prone juga telah mencipta satu set komponen analisis C++ baharu yang disepadukan dengan Tricorder yang dipanggil ClangTidy. Laporan penganalisis Tricorder menyokong hasil dalam lebih 30 bahasa, menyokong analisis sintaks mudah seperti penyemak gaya, memanfaatkan maklumat pengkompil untuk Java, JavaScript dan C++, dan boleh disepadukan secara langsung dengan data pengeluaran (mis. maklumat tentang tugasan yang sedang dijalankan). Tricorder terus berjaya di Google kerana ia merupakan model pemalam yang menyokong platform ekologi untuk penulis penganalisis, menyerlahkan pembetulan yang boleh dilaksanakan semasa proses semakan kod dan menyediakan saluran maklum balas untuk menambah baik penganalisis dan memastikan pembangun penganalisis Mengambil tindakan maklum balas positif.

Membolehkan pengguna menyumbang. Sehingga Januari 2018, Tricorder menyertakan 146 penganalisis, 125 daripadanya adalah dari luar pasukan Tricorder dan tujuh sistem pemalam untuk ratusan pemeriksaan tambahan (seperti ErrorProne dan ClangTidy), iaitu dua).

Pengulas mempertimbangkan untuk mencadangkan pembetulan.

Pemeriksa Tricorder boleh menyediakan alat semakan kod dengan cadangan pembaikan munasabah yang boleh dilihat oleh penyemak dan pembangun kod. Penyemak boleh meminta pembangun membetulkan kod yang rosak dengan mengklik butang "Sila Betulkan" pada hasil analisis. Pengulas biasanya tidak meluluskan perubahan kod untuk dimasukkan sehingga semua ulasan mereka (manual dan ditemui secara automatik) telah ditangani.

Teruskan maklum balas daripada pengguna. Sebagai tambahan kepada butang "Sila betulkan", Tricorder juga menyediakan butang "tidak berguna" yang boleh diklik oleh penyemak atau pencadang untuk menunjukkan bahawa mereka tidak bersetuju dengan penemuan analisis. Tindakan klik akan menyerahkan pepijat secara automatik dalam penjejak pepijat dan menghalakannya kepada pasukan yang menjadi milik penganalisis. Pasukan Tricorder membuat susulan pada klik "tidak berguna" ini dan mengira nisbah klik antara klik "sila betulkan" dan "tidak berguna". Jika nisbah penganalisis melebihi 10% maka pasukan Tricorder akan melumpuhkan penganalisis sehingga pengarang memperbaikinya. Walaupun pasukan Tricorder jarang melumpuhkan penganalisis secara kekal, ia telah melumpuhkan beberapa penganalisis (dalam beberapa senario) sehingga pengarang penganalisis telah mengalih keluar dan mengubah suai dam yang ternyata menyusahkan dan tidak berguna.

Pepijat yang diserahkan sering meningkatkan prestasi penganalisis, dengan itu meningkatkan kepuasan pembangun dengan penganalisis ini sebagai contoh, pasukan Rawan Ralat telah membangunkan semakan pada tahun 2014 yang menandakan apabila Guava Melepasi terlalu banyak hujah kepada fungsi seperti printf. Fungsi seperti printf sebenarnya tidak menerima semua penentu printf, hanya %S. Kira-kira sekali seminggu pasukan Rawan Ralat akan menerima pepijat "bodoh" yang mendakwa bahawa analisis itu tidak betul dan bilangan kad bebas format dalam kod pemadanan pepijat sebenarnya sepadan dengan bilangan hujah yang benar-benar diluluskan. Apabila pengguna cuba melepasi pemegang tempat kad bebas selain %s, penghurai sebenarnya tidak betul dalam apa jua keadaan. Jadi pasukan menukar teks perihalan pemeriksaan kod untuk menyatakan secara langsung bahawa fungsi itu hanya menerima %s ruang letak dan berhenti mendapat ralat tentang semakan itu.

Skala penggunaan Tricorder. Sehingga Januari 2018, Tricorder telah menganalisis kira-kira 50,000 perubahan semakan kod setiap hari. Analisis dilakukan tiga kali sesaat pada waktu puncak. Penyemak mengklik "Sila betulkan" lebih daripada 5,000 kali sehari dan pengarang menggunakan penyelesaian pembaikan automatik kira-kira 3,000 kali sehari. Penganalisis Tricorder menerima maklum balas sebanyak 250 klik "tidak berguna" setiap hari.

Kejayaan analisis semakan kod menunjukkan bahawa ia menduduki "sweet spot" dalam aliran kerja pembangun Google. Keputusan analisis yang dipaparkan pada masa penyusunan mestilah mempunyai kualiti dan ketepatan relatif yang tidak dapat dipenuhi dengan bergantung kepada penganalisis untuk terus mengenal pasti masalah yang serius. Selepas ulasan dan kod digabungkan, pembangun menghadapi peningkatan rintangan untuk membuat perubahan. Akibatnya, pembangun bergelut untuk membuat perubahan pada kod yang telah diuji dan dikeluarkan serta kurang berkemungkinan menangani isu berisiko rendah dan kurang penting. Banyak projek analitik lain dalam organisasi pembangunan perisian (seperti analisis Facebook Infer untuk apl Android/iOS) turut menekankan semakan kod sebagai titik masuk utama untuk melaporkan hasil analitik.

Melanjutkan penganalisis

Apabila pembangun Google mendapat penerimaan keputusan penganalisis Tricorder, mereka terus meminta sambungan lanjut kepada penganalisis. Tricorder menyelesaikan masalah ini dalam dua cara: membenarkan penyesuaian pada peringkat projek dan menambah hasil analisis pembentangan pada titik lain dalam proses pembangunan. Dalam bahagian ini, kami juga membincangkan beberapa sebab Google belum lagi memanfaatkan analitik yang lebih canggih sebagai proses pembangunan teras.

Penyesuaian peringkat projek

Tidak semua penganalisis yang diminta mempunyai nilai yang sama dengan keseluruhan pangkalan kod Google; contohnya, sesetengah penganalisis dikaitkan dengan kadar positif palsu yang lebih tinggi dan oleh itu mempunyai kadar positif palsu yang lebih tinggi pemeriksa mungkin perlu dikonfigurasikan dalam projek tertentu untuk menjadi berkesan. Profiler ini hanya berguna kepada pasukan yang betul.

Untuk mencapai keperluan ini, matlamat kami adalah untuk menjadikan Tricorder boleh disesuaikan. Pengalaman kami sebelum ini dengan penyesuaian untuk FindBugs adalah kurang berkesan penyesuaian peringkat pengguna mengakibatkan pembezaan dalam dan antara pasukan dan penggunaan alat yang berkurangan. Oleh kerana setiap pengguna boleh melihat pandangan yang berbeza bagi sesuatu isu, tidak ada cara untuk memastikan bahawa semua orang yang bekerja pada projek yang sama dapat melihat isu tertentu. Jika pembangun mengalih keluar semua import yang tidak digunakan daripada kod pasukan mereka, maka walaupun seorang pembangun lain tidak konsisten tentang mengalih keluar import yang tidak digunakan, perubahan itu akan segera ditolak oleh rollback.

Untuk mengelakkan masalah sedemikian, Tricorder hanya membenarkan konfigurasi pada peringkat projek, memastikan sesiapa sahaja yang membuat perubahan pada projek tertentu melihat pandangan konsisten hasil analisis yang berkaitan dengan projek tersebut. Mengekalkan ketekalan dalam paparan hasil membolehkan beberapa jenis penganalisis melakukan tindakan berikut:

Menghasilkan hasil binari. Sebagai contoh, Tricorder menyertakan penghurai untuk definisi penimbal protokol yang mengenal pasti perubahan tidak serasi ke belakang. Ini digunakan oleh pasukan pembangun untuk memastikan maklumat berterusan dalam penimbal protokol dalam bentuk bersiri, tetapi menjengkelkan untuk pasukan yang tidak menyimpan data dalam borang ini. Contoh lain ialah penganalisis mencadangkan penggunaan kod Guava atau Java yang tidak masuk akal untuk projek yang tidak boleh menggunakan pustaka atau ciri bahasa tersebut; Sebagai contoh, pasukan hanya boleh menggunakan ketiadaan Rangka Kerja Pemeriksa untuk menganalisis jika kod mereka diberi anotasi dengan betul. Penganalisis lain yang, apabila dikonfigurasikan dengan betul, akan menyemak pertumbuhan saiz binari dan bilangan panggilan fungsi perduaan Android tertentu, dan memberi amaran kepada pembangun sama ada pertumbuhan itu dijangkakan atau jika ia menghampiri had; bahasa kawasan khusus (DSL) dan garis panduan pengekodan khusus pasukan. Sesetengah pasukan pembangunan perisian Google telah membangunkan beberapa DSL kecil dan ingin menjalankan penyemak berkaitan. Pasukan lain telah melaksanakan amalan terbaik dalam kebolehbacaan dan kebolehselenggaraan dan ingin terus menguatkuasakan semakan ini; Satu kes analisis bercampur berdasarkan keputusan analisis dinamik yang disertakan. Analisis sedemikian memberikan nilai yang tinggi untuk sesetengah pasukan tetapi terlalu mahal atau memakan masa untuk semua orang.

Sehingga Januari 2018, terdapat kira-kira 70 analitis pilihan dalam Google, dengan 2,500 projek membolehkan sekurang-kurangnya satu daripadanya. Berpuluh-puluh pasukan di seluruh syarikat sedang giat membangunkan penganalisis baharu, kebanyakannya bergabung di luar kumpulan alat pembangunan.

Mata Penyepaduan Aliran Kerja Tambahan

Apabila kepercayaan pembangun terhadap alatan ini semakin meningkat, mereka juga menuntut penyepaduan selanjutnya ke dalam aliran kerja mereka. Tricorder kini menyediakan hasil analisis dengan menyediakan alat baris arahan, sistem penyepaduan berterusan dan alat semakan kod.

Sokongan baris perintah. Pasukan Tricorder telah menambah sokongan baris arahan untuk pembangun yang pada asasnya merupakan pengurus kod, kerap menyemak imbas dan membersihkan pelbagai analitik amaran dalam pangkalan kod pasukan. Pembangun ini juga sangat biasa dengan jenis pembetulan yang akan dihasilkan oleh setiap penganalisis dan mempunyai tahap kepercayaan yang tinggi terhadap penganalisis tertentu. Jadi pembangun boleh menggunakan alatan baris perintah untuk menggunakan semua pembetulan secara automatik dalam analisis tertentu dan membuat perubahan yang bersih; Sesetengah pasukan mahu penganalisis khusus menyekat komit kod dan bukannya hanya muncul dalam alat semakan kod. Biasanya permintaan untuk keupayaan untuk menyekat komitmen dibuat oleh pasukan dengan penyemak tersuai tinggi yang menjamin tiada positif palsu, biasanya dalam DSL atau perpustakaan tersuai.

Kod menunjukkan hasilnya. Pembentangan kod adalah yang terbaik untuk menunjukkan skala masalah dalam projek besar (atau keseluruhan pangkalan kod). Sebagai contoh, hasil analisis apabila menyemak imbas kod untuk API yang ditamatkan boleh menunjukkan jumlah kerja yang diperlukan untuk berhijrah atau beberapa analisis keselamatan dan privasi adalah global dan memerlukan pasukan profesional untuk menyemak keputusan sebelum menentukan sama ada terdapat isu. Oleh kerana keputusan analisis tidak dipaparkan secara lalai, Pelayar Kod membenarkan pasukan tertentu mendayakan paparan analisis dan kemudian mengimbas keseluruhan pangkalan kod dan menyemak keputusan tanpa mengganggu pembangun lain daripada penganalisis ini. Jika hasil analisis mempunyai pembetulan yang berkaitan, pembangun boleh menggunakan pembetulan dengan hanya mengklik pada alat penyemakan imbas kod. Pelayar Kod juga bagus untuk menunjukkan hasil analisis penggunaan data pengeluaran, memandangkan data ini tidak tersedia sehingga kod itu dilakukan dan dijalankan.
Analisis Kompleks

Semua analisis statik yang digunakan secara meluas di Google adalah agak mudah, walaupun sesetengah pasukan melakukan analisis antara prosedur dengan rangka kerja analisis khusus projek untuk domain tertentu (mis. apl Android). Analitis proses berskala Google boleh dilaksanakan secara teknikal. Tetapi analisis sedemikian sangat mencabar untuk dilaksanakan. Seperti yang dinyatakan di atas, semua kod Google disimpan dalam repositori kod sumber keseluruhan yang berasingan, jadi secara konseptual mana-mana kod dalam repositori kod boleh menjadi sebahagian daripada mana-mana fail binari. Oleh itu, boleh dibayangkan untuk membayangkan situasi di mana keputusan analisis semakan kod tertentu memerlukan analisis keseluruhan repositori kod. Walaupun Infer Facebook memfokuskan pada analisis antara prosedur, menskalakan penganalisis berasaskan logik berpecah kepada asas kod berjuta-juta baris, menskalakan penganalisis sedemikian kepada repositori kod berbilion baris Google masih memerlukan usaha kejuruteraan yang ketara. Mulai Januari 2018, melaksanakan sistem analitis yang lebih canggih bukanlah keutamaan untuk Google:

Pelaburan yang ketara. Pelaburan infrastruktur awal akan menjadi terlalu tinggi;

Usaha akan diperlukan untuk mengurangkan kadar penggera palsu. Pasukan analisis mesti membangunkan teknik untuk mengurangkan kadar positif palsu banyak penganalisis dan/atau mengehadkan dengan ketat mesej ralat yang dipaparkan, seperti yang dilakukan oleh Figureinfer

Terdapat banyak lagi yang perlu dilaksanakan. Pasukan analitis masih mempunyai penganalisis yang lebih "mudah" untuk dilaksanakan dan disepadukan; Kami mendapati penganalisis "mudah" ini sangat menjimatkan kos, yang merupakan motivasi teras untuk FindBugs. Sebagai perbandingan, walaupun kos ROI bagi penyemak yang lebih canggih ditentukan, kos pendahuluan adalah tinggi.

Sila ambil perhatian bahawa ROI ini boleh menjadi ketara untuk pembangun di luar Google yang bekerja di kawasan khusus (seperti aeroangkasa dan peranti perubatan) atau pada perbezaan projek tertentu (seperti pemacu peranti dan aplikasi mudah alih).

Refleksi

Pengalaman kami cuba menyepadukan analisis statik ke dalam aliran kerja Google mengajar kami pelajaran berharga berikut:

Mudah untuk mencari pepijat. Apabila pangkalan kod cukup besar, ia mengandungi hampir semua corak kod yang boleh dibayangkan. Walaupun dalam asas kod matang dengan liputan ujian lengkap dan proses semakan kod yang ketat, pepijat kelihatan besar. Kadangkala masalah tidak jelas daripada pemeriksaan tempatan, dan kadangkala ralat diperkenalkan oleh pemfaktoran semula yang kelihatan tidak berbahaya. Sebagai contoh, pertimbangkan coretan kod berikut menggunakan medan f jenis panjang,

hasil =
31 * hasil


    (int) (f ^ ( f >>> 32));
Bayangkan apa yang akan berlaku jika pembangun menukar jenis f kepada int. Kod terus dikompil, tetapi offset kanan 32 menjadi operasi tanpa operasi, medan XORed dengan dirinya sendiri, dan nilai hash pembolehubah menjadi pemalar 0. Hasilnya ialah f tidak lagi mempengaruhi nilai yang dijana oleh kaedah hashCode. Mana-mana alat yang boleh mengira jenis f boleh mengesan dengan betul offset lebih daripada 31, kami telah membetulkan 31 kod dalam pangkalan kod Google dengan ralat ini, dan juga memasukkan semakan dalam kompilasi dalam ralat Ralat Pone Server.

Memandangkan mengesan ralat adalah mudah, Google menggunakan alat mudah untuk mengesan jenis ralat. Seterusnya, penulis analisis membuat penalaan halus berdasarkan hasil menjalankan kod Google.

Kebanyakan pembangun tidak menggunakan alat analisis statik seperti yang mereka fikirkan. Seperti pembangunan banyak alat komersial, Google pada mulanya bergantung pada pelaksanaan FindBugs memilih untuk mengakses papan pemuka berpusat untuk melihat masalah yang terdapat dalam projek mereka, tetapi hanya sedikit daripada mereka yang benar-benar melihatnya dengan cara ini. Sudah terlambat untuk mencari pepijat yang telah dimasukkan ke dalam kod (yang mungkin telah digunakan dan dijalankan tanpa pengguna menyedari masalah itu). Untuk memastikan bahawa kebanyakan atau semua jurutera melihat amaran analisis statik, alat analisis mesti disepadukan ke dalam aliran kerja dan didayakan secara lalai untuk semua orang. Projek seperti Error Prone tidak menyediakan papan pemuka ralat, tetapi memanjangkan pengkompil dengan penyemak tambahan dan memaparkan hasil analisis semasa semakan kod.

Perasaan pembangun adalah penting. Dalam pengalaman dan pengumpulan bahan kami, banyak percubaan untuk mengintegrasikan analisis statik ke dalam organisasi pembangunan perisian telah gagal. Jurutera biasanya tidak dibenarkan oleh pengurusan Google untuk menggunakan alat analisis statik. Jurutera yang bekerja pada analisis statik mesti menunjukkan kesannya dengan data dunia sebenar yang sah. Untuk projek analisis statik untuk berjaya, pembangun mesti merasakan bahawa mereka mendapat manfaat daripadanya dan menikmati nilai menggunakannya.

Untuk membina platform analitik yang berjaya, kami membina alatan yang memberikan nilai tinggi kepada pembangun. Pasukan Tricorder akan menyemak dengan teliti isu tetap, menjalankan tinjauan sebenar untuk memahami perasaan pembangun, memudahkan penyerahan pepijat melalui alat analisis dan menggunakan semua data ini untuk menambah baik secara berterusan. Pembangun perlu membina kepercayaan dalam alat analisis. Jika alat membuang masa pembangun dengan positif palsu dan maklum balas tentang isu peringkat rendah, pembangun akan hilang keyakinan dan mengabaikan keputusan.

Jangan hanya mencari pepijat, betulkan ia. Pendekatan biasa untuk mempromosikan alat analisis statik adalah dengan menyenaraikan sejumlah besar masalah dalam pangkalan kod. Tujuannya adalah untuk mempengaruhi tindakan dengan menunjukkan kemungkinan ralat untuk dibetulkan atau untuk mengelakkan pepijat daripada berlaku pada masa hadapan. Tetapi jika pembangun tidak diberi insentif untuk mengambil tindakan, hasil yang mungkin diingini ini akan kekal tidak direalisasikan. Ini adalah kelemahan asas: Alat analisis mengukur kegunaannya dengan bilangan masalah yang mereka kenal pasti, manakala penyepaduan proses gagal dengan hanya segelintir pembetulan pepijat. Sebaliknya, pasukan analisis statik Google akan bertanggungjawab untuk kerja pembaikan yang sepadan serta mencari pepijat, menggunakan ini sebagai kriteria untuk gelung tertutup yang berjaya. Memfokuskan pada membetulkan ralat memastikan alat menyediakan pengesyoran yang boleh diambil tindakan dan meminimumkan positif palsu. Dalam kebanyakan kes, membetulkan ralat semudah mencarinya melalui alat automatik. Walaupun untuk masalah yang sukar diselesaikan, penyelidikan sepanjang lima tahun yang lalu telah menyerlahkan teknik baharu untuk membuat pembetulan secara automatik untuk masalah analisis statik.

Pembangunan penganalisis memerlukan usaha kolektif. Walaupun alat analisis statik tertentu memerlukan pembangun pakar untuk menulis analisis, beberapa pakar mungkin benar-benar mengetahui pemeriksaan yang menghasilkan faktor impak yang lebih besar. Selain itu, pakar penganalisis selalunya bukan pakar domain (seperti mereka yang bekerja dengan API, bahasa dan keselamatan). Penyepaduan melalui FindBugs Hanya segelintir pekerja Google yang tahu cara menulis penyemak baharu, jadi pasukan BugBot yang kecil terpaksa melakukan semua kerja itu sendiri. Ini mengehadkan kelajuan semakan baharu boleh ditambah dan berkesan menghalang orang lain daripada mendapat manfaat daripada sumbangan pengetahuan domain mereka. Pasukan seperti Tricorder kini menumpukan pada menurunkan piawaian untuk semakan yang disediakan oleh pembangun, tanpa memerlukan pengalaman analisis statik terlebih dahulu. Alat Google Refaster, sebagai contoh, membenarkan pembangun menulis penyemak dengan menyatakan contoh sebelum dan selepas coretan kod. Memandangkan penyumbang sering terdorong untuk menyumbang selepas menyahpepijat kod yang salah sendiri, semakan baharu akan menjimatkan masa pembangun dari semasa ke semasa.

Kesimpulan

Pengalaman kami ialah penyepaduan ke dalam proses pembangunan adalah kunci kepada pelaksanaan alat analisis statik. Walaupun pengarang alat pemeriksa mungkin percaya bahawa pembangun seharusnya gembira berhadapan dengan senarai kecacatan dalam kod yang mereka tulis, kami sebenarnya tidak mendapati bahawa senarai sedemikian mendorong pembangun untuk memperbaiki kecacatan tersebut. Sebagai pembangun alat analitis, kita mesti menentukan keberkesanan pengukuran dari segi kecacatan yang sebenarnya diperbetulkan, dan bukannya memberi nombor pembangun. Ini bermakna tanggungjawab kita melangkaui alat analisis itu sendiri.

Kami menyokong sistem yang memfokuskan pada memacu integrasi aliran kerja seawal mungkin. Dayakan penyemak sebagai ralat pengkompil apabila boleh. Untuk mengelakkan penulis alat binaan yang mengganggu ditugaskan untuk membetulkan semua isu sedia ada dalam pangkalan kod terlebih dahulu, membolehkan kami terus meningkatkan kualiti pangkalan kod Google satu langkah pada satu masa. Oleh kerana kami memberikan amaran ralat dalam pengkompil, pembangun menanganinya dengan segera selepas menulis kod supaya mereka masih boleh membuat perubahan tepat pada masanya. Untuk mencapai matlamat ini, kami membangunkan infrastruktur untuk menjalankan analisis dan menjana pembetulan merentas pangkalan kod Google yang luas. Kami juga mendapat manfaat daripada semakan kod dan melakukan automasi yang membenarkan perubahan kepada ratusan fail, dan sudah tentu budaya kejuruteraan yang sering bertolak ansur dengan perubahan yang dimasukkan ke dalam kod warisan kerana menambah baik kod mengatasi keengganan terhadap risiko pengubahsuaian.

Semakan kod ialah titik masuk terbaik untuk memaparkan amaran analisis sebelum melakukan kod. Untuk memastikan pembangun menerima keputusan analisis, Tricorder hanya memaparkan isu semasa fasa pengubahsuaian kod pembangun sebelum melakukan perubahan dan pasukan Tricorder menggunakan satu siri kriteria untuk memilih makluman yang hendak dipaparkan. Tricorder selanjutnya mengumpul statistik dalam alat semakan kod, yang digunakan untuk mengesan punca utama penganalisis menjana sejumlah besar makluman tidak sah.

Untuk mengatasi amaran yang diabaikan, kami bekerja keras untuk mendapatkan semula kepercayaan jurutera Google dan mendapati bahawa pembangun Google mempunyai berat sebelah yang kuat untuk mengabaikan analisis statik Sebarang laporan dengan kadar positif palsu yang tidak memuaskan memberi mereka a alasan untuk tidak berbuat apa-apa. Pasukan analisis sangat berhati-hati tentang memaparkan hasil pemeriksaan sebagai ralat atau amaran hanya selepas mereka disemak berdasarkan kriteria objektif deskriptif, jadi pembangun jarang terharu, keliru atau terganggu dengan keputusan analisis. Tinjauan dan saluran maklum balas adalah kaedah kawalan kualiti yang penting untuk proses ini. Memandangkan pembangun telah mendapat semula kepercayaan dalam hasil analisis, pasukan Tricorder sedang menangani keperluan untuk lebih banyak analitik untuk lebih terlibat dalam aliran kerja pembangun Google.

Kami telah membina infrastruktur analisis statik yang berjaya di Google yang menghalang ratusan pepijat daripada memasuki pangkalan kod Google setiap hari, pada masa penyusunan dan semasa semakan kod. Kami berharap orang lain boleh mendapat manfaat daripada pengalaman kami dan berjaya menyepadukan analisis statik ke dalam aliran kerja mereka sendiri.

Atas ialah kandungan terperinci Kajian kes Google tentang membina alat analisis kod statik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan