Cerita rakyat programmer dan insinyur (bagian 2)



Kelanjutan kumpulan cerita dari Internet tentang bagaimana bug terkadang memiliki manifestasi yang sangat luar biasa. Bagian pertama ada di sini .



Lebih banyak keajaiban



Beberapa tahun yang lalu, saya mengobrak-abrik lemari yang menampung komputer PDP-10 milik lab AI MIT. Saya melihat sebuah tombol kecil menempel pada bingkai salah satu lemari. Tampak jelas bahwa itu adalah produk buatan sendiri, ditambahkan oleh salah satu pengrajin laboratorium (tidak ada yang tahu persis siapa).



Anda tidak akan menyentuh sakelar yang tidak dikenal di komputer Anda tanpa mengetahui fungsinya, karena Anda dapat merusak komputer Anda. Saklar ditandatangani sama sekali tidak dapat dipahami. Itu memiliki dua posisi, dan kata-kata "sihir" dan "lebih banyak sihir" dituliskan pada tubuh logam dengan pensil. Saklar berada pada posisi yang lebih ajaib. Saya memanggil salah satu teknisi untuk memeriksanya. Dia belum pernah melihat hal seperti itu sebelumnya. Setelah diperiksa lebih dekat, ternyata hanya satu kabel yang masuk ke sakelar! Ujung kabel lainnya menghilang ke dalam tumpukan kabel di dalam komputer, tetapi sifat listrik menyatakan bahwa sakelar tidak akan melakukan apa pun sampai Anda mencolokkan dua kabel ke dalamnya.



Jelas sekali bahwa ini adalah lelucon bodoh seseorang. Setelah memastikan sakelar tidak melakukan apa-apa, kami mengalihkannya. Komputer segera mati.



Bayangkan keheranan kami. Kami menganggapnya sebagai kebetulan, tetapi masih memasang kembali tombol tersebut ke posisi "lebih ajaib" sebelum memulai komputer.



Setahun kemudian, saya menceritakan kisah ini kepada teknisi lain, David Moon, sejauh yang saya ingat. Dia mempertanyakan kecukupan saya, atau dicurigai percaya pada sifat supernatural dari sakelar itu, atau mengira saya bermain-main dengan cerita palsu itu. Untuk membuktikan maksud saya, saya tunjukkan saklar ini, masih terpaku pada rangka dan dengan satu kabel, masih dalam posisi "lebih ajaib". Kami memeriksa sakelar dan kabelnya dengan cermat dan menemukan bahwa itu ground. Kelihatannya tidak ada artinya ganda: sakelar tidak hanya tidak berfungsi secara elektrik, tetapi juga dicolokkan ke tempat yang tidak memengaruhi apa pun. Kami memindahkannya ke posisi lain.



Komputer langsung kosong.



Kami menghubungi Richard Greenblatt, yang merupakan teknisi lama di MIT, yang berada di dekatnya. Dia, juga, belum pernah melihat tombolnya. Saya memeriksanya, sampai pada kesimpulan bahwa sakelar tidak berguna, mengeluarkan pemotong kabel dan memotong kabel. Kemudian kami menyalakan komputer dan komputer mulai bekerja dengan tenang.



Kami masih tidak tahu bagaimana saklar ini mematikan komputer. Ada hipotesis bahwa korsleting kecil terjadi di dekat kontak tanah, dan terjemahan posisi sakelar mengubah kapasitansi listrik sehingga rangkaian terputus ketika pulsa dengan durasi sepersejuta detik melewatinya. Tapi kami tidak tahu pasti. Kami hanya dapat mengatakan bahwa sakelar itu ajaib.



Itu masih di ruang bawah tanah saya. Ini mungkin konyol, tapi saya biasanya menyimpannya dalam posisi "lebih ajaib".



Pada tahun 1994, penjelasan lain untuk cerita ini diajukan. Perhatikan bahwa badan sakelar itu terbuat dari logam. Misalkan kontak tanpa kabel kedua telah dihubungkan ke tubuh (biasanya tubuh di-ground, tetapi ada pengecualian). Badan sakelar terhubung ke casing komputer, yang mungkin terhubung ke ground. Kemudian sirkuit arde di dalam mesin mungkin memiliki potensi yang berbeda dari rangkaian arde rangka, dan mengubah posisi sakelar menyebabkan penurunan atau lonjakan tegangan, dan mesin di-boot ulang. Efek ini mungkin ditemukan oleh seseorang yang mengetahui tentang perbedaan potensial dan memutuskan untuk membuat lelucon seperti itu.



OpenOffice tidak mencetak pada hari Selasa



Di blog hari ini, saya menemukan penyebutan bug yang menarik. Beberapa orang mengalami masalah saat mencetak dokumen. Belakangan, seseorang memperhatikan bahwa istrinya mengeluh karena tidak dapat mencetak pada hari Selasa!



Dalam laporan bug, beberapa awalnya mengeluh bahwa ini pasti bug OpenOffice, karena dari semua aplikasi lain ini dicetak tanpa masalah. Yang lain telah memperhatikan bahwa masalah datang dan pergi. Salah satu pengguna menemukan solusi: hapus instalan OpenOffice dan hapus sistem, lalu instal ulang (tugas sederhana apa pun di Ubuntu). Pengguna tersebut melaporkan pada hari Selasa bahwa masalah pencetakannya telah diselesaikan.



Dua minggu kemudian, dia menulis (pada hari Selasa) bahwa solusinya masih tidak berhasil. Sekitar empat bulan kemudian, istri peretas Ubuntu mengeluh bahwa OpenOffice tidak mencetak pada hari Selasa. Bayangkan situasi ini:



Istri: Steve, printer tutup pada hari Selasa.



Steve: Ini hari libur di percetakan, tentu saja tidak mencetak di hari Selasa.



Istri: Saya serius! Saya tidak dapat mencetak dari OpenOffice pada hari Selasa.



Steve: (tidak percaya) Oke, tunjukkan.



Istri: Saya tidak bisa menunjukkannya.



Steve: (memutar matanya) Mengapa?



Istri: Hari ini Rabu!



Steve: (mengangguk, berbicara perlahan) Benar.



Masalahnya ditelusuri kembali ke program bernama file. Utilitas * NIX ini menggunakan templat untuk mendeteksi jenis file. Misalnya, jika file dimulai dengan%!dan kemudian berjalan PS-Adobe-, lalu PostScript. Sepertinya OpenOffice sedang menulis data ke file semacam itu. Pada hari Selasa dia mengambil seragamnya %%CreationDate: (Tue MMM D hh:mm:...). Kesalahan dalam template untuk file JAM Erlang berarti bahwa Tuefile PostScript dikenali sebagai file Erlang JAM, dan oleh karena itu, mungkin, itu tidak dikirim untuk dicetak.



Template untuk file Erlang JAM terlihat seperti ini:



4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2


Dan akan terlihat seperti ini:



4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2


Mengingat banyaknya jenis file yang coba dikenali oleh program ini (lebih dari 1600), kesalahan template tidaklah mengejutkan. Tetapi urutan perbandingan juga sering menyebabkan kesalahan positif. Dalam kasus ini, tipe Erlang JAM dipetakan ke tipe PostScript.



Paket kematian



Saya mulai memanggil mereka begitu karena mereka adalah paket kematian.



Star2Star telah bermitra dengan produsen perangkat keras yang telah membuat dua versi terakhir dari sistem klien lokal kami.



Sekitar setahun yang lalu kami merilis pembaruan untuk perangkat keras ini. Semuanya dimulai dengan sangat sederhana, mengikuti hukum biasa Moore. Lebih besar, lebih baik, lebih cepat, lebih murah. Perangkat keras baru itu 64-bit, memiliki memori 8 kali lebih banyak, memiliki lebih banyak drive, dan memiliki empat port Intel Gigabit Ethernet (produsen pengontrol Ethernet favorit saya). Kami memiliki (dan masih) banyak ide tentang bagaimana menggunakan port ini. Secara umum, potongan besi itu luar biasa.



Kebaruan melesat melalui uji kinerja dan fungsionalitas. Baik kecepatannya tinggi maupun keandalannya. Idealnya. Kemudian kami perlahan-lahan menyebarkan peralatan ke beberapa lokasi pengujian. Tentu saja masalah mulai muncul.



Pencarian cepat Google menunjukkan bahwa pengontrol Ethernet Intel 82574L memiliki setidaknya beberapa masalah. Secara khusus, masalah dengan EEPROM, bug di ASPM, trik dengan MSI-X, dll. Kami telah menyelesaikan masing-masing selama beberapa bulan. Dan kami pikir kami sudah selesai.



Tapi tidak. Itu hanya bertambah buruk.



Saya pikir saya merancang dan menerapkan image perangkat lunak (dan BIOS) yang sempurna. Namun, kenyataannya berbeda. Modul terus gagal. Terkadang mereka pulih setelah reboot, terkadang tidak. Namun, setelah modul dipulihkan, perlu dilakukan pengujian.



Wow. Situasinya semakin aneh.



Keanehan terus berlanjut, dan akhirnya saya memutuskan untuk menyingsingkan lengan baju saya. Saya beruntung menemukan pengecer yang sangat sabar dan membantu yang tetap bersama saya di ponsel selama tiga jam saat saya mengumpulkan data. Pada titik klien tersebut, untuk beberapa alasan, pengontrol Ethernet dapat jatuh saat mentransmisikan lalu lintas suara melalui jaringan.



Saya akan membahas ini lebih detail. Ketika saya mengatakan bahwa pengontrol Ethernet "bisa saja mati", itu berarti pengontrol itu BISA hilang. Sistem dan antarmuka Ethernet tampak baik-baik saja, dan setelah mengirimkan sejumlah lalu lintas acak, antarmuka dapat melaporkan kesalahan perangkat keras (kehilangan komunikasi dengan PHY) dan kehilangan koneksi. LED pada sakelar dan antarmuka benar-benar mati. Pengontrol sudah mati.



Itu mungkin untuk menghidupkannya kembali hanya dengan mematikan dan menghidupkannya. Mencoba mem-boot ulang modul kernel atau mesin mengakibatkan kesalahan pemindaian PCI. Antarmuka tetap mati sampai mesin secara fisik dicabut dan dicolokkan kembali. Dalam kebanyakan kasus, untuk klien kami, ini berarti melepas peralatan.



Saat men-debug dengan pengecer yang sangat sabar ini, saya mulai berhenti menerima paket ketika antarmuka macet. Pada akhirnya, saya mengidentifikasi sebuah pola: paket terakhir dari antarmuka selalu 100 Trying provisional response, dan selalu memiliki panjang tertentu. Bukan itu saja, saya akhirnya menelusuri tanggapan ini (dari Asterisk) kembali ke permintaan INVITE asli yang spesifik untuk salah satu ponsel produsen.



Saya menelepon pengecer, mengumpulkan orang-orang dan menunjukkan buktinya. Meskipun saat itu hari Jumat malam, semua orang ikut serta dalam pekerjaan dan memasang meja uji dari peralatan dan telepon baru kami dari pabrikan ini.



Kami duduk di ruang konferensi dan mulai memutar nomor secepat mungkin. Ternyata kita bisa mereproduksi masalahnya! Tidak di setiap panggilan dan tidak di setiap perangkat, tetapi dari waktu ke waktu kami berhasil mengaktifkan pengontrol Ethernet, dan dari waktu ke waktu kami tidak melakukannya. Setelah kehilangan tenaga, kami mencoba lagi, dan kami berhasil. Bagaimanapun, seperti yang diketahui oleh siapa pun yang telah mencoba mendiagnosis masalah teknis, langkah pertama adalah mereproduksi masalah tersebut. Kami akhirnya berhasil.



Percayalah, butuh waktu lama. Saya tahu cara kerja tumpukan OSI. Saya tahu bagaimana perangkat lunak dikelompokkan. Saya tahu bahwa isi paket SIP seharusnya tidak mempengaruhi adaptor Ethernet. Itu semua tidak masuk akal.



Akhirnya, kami berhasil mengisolasi masalah paket dalam interval antara kedatangan mereka di perangkat kami dan di port mirroring di sakelar. Ternyata masalahnya ada pada permintaan INVITE, bukan tanggapannya 100 Trying. Tidak 100 Tryingada respons dalam data yang diambil di port cermin .



Itu perlu untuk menangani ini INVITE. Apakah masalah terkait dengan penanganan paket ini oleh daemon userspace? Mungkin transmisi masalahnya 100 Trying? Seorang kolega menyarankan untuk menutup aplikasi SIP dan melihat apakah masalahnya masih ada. Tanpa aplikasi ini, paket100 Tryingtidak ditularkan.



Itu perlu entah bagaimana meningkatkan transmisi paket masalah. Kami mengisolasi paket yang dikirimkan dari telepon INVITEdan memutarnya menggunakan tcpreplay. Berhasil. Untuk pertama kalinya dalam beberapa bulan, kami dapat melepaskan port sesuai perintah dengan satu paket. Ini adalah kemajuan yang signifikan, dan sudah waktunya untuk pulang, yaitu mengulang bangku tes di laboratorium rumah!



Sebelum saya melanjutkan cerita saya, saya ingin memberi tahu Anda tentang aplikasi sumber terbuka hebat yang saya temukan. Ostinato mengubah Anda menjadi master paket. Kemungkinannya secara harfiah tidak terbatas. Tanpa aplikasi ini, saya tidak akan bisa maju lebih jauh.



Berbekal alat paket serbaguna ini, saya mulai bereksperimen. Saya kagum dengan apa yang saya temukan.



Semuanya dimulai dengan permainan SIP / SDP yang aneh. Lihatlah SDP ini:



v=0
o=- 20047 20047 IN IP4 10.41.22.248
s=SDP data
c=IN IP4 10.41.22.248
t=0 0
m=audio 11786 RTP/AVP 18 0 18 9 9 101
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:0 PCMU/8000
a=rtpmap:18 G729/8000
a=fmtp:18 annexb=no
a=rtpmap:9 G722/8000
a=rtpmap:9 G722/8000
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
a=ptime:20
a=sendrecv


Ya itu betul. Proposal transmisi suara diduplikasi. Ini adalah masalah, tetapi sekali lagi, apa hubungannya pengontrol Ethernet dengan ini ?! Terlepas dari kenyataan bahwa tidak ada yang lain yang meningkatkan ukuran frame Ethernet ... Tapi tunggu, ada banyak frame Ethernet yang berhasil dalam paket yang sedang dikirim. Beberapa dari mereka lebih kecil, beberapa lagi. Tidak ada masalah dengan mereka. Saya harus menggali lebih jauh. Setelah beberapa trik kung fu dengan Ostinato dan banyak penyambungan kembali listrik, saya dapat mengidentifikasi hubungan yang bermasalah (dengan bingkai masalah). Catatan: kita akan melihat nilai heksadesimal.



Kerusakan antarmuka dimulai oleh nilai byte tertentu pada offset tertentu. Dalam kasus kami, itu adalah nilai heksadesimal 32c 0x47f. Dalam ASCII, heksadesimal 32adalah2... Tebak dari mana asalnya 2.



a=ptime:20


Semua SDP kami identik (termasuk ptime). Semua URI sumber dan tujuan identik. Satu-satunya perbedaan adalah nomor pemanggil, tag, dan ID sesi unik. Paket masalah memiliki kombinasi ID panggilan, tag, dan cabang, yang ptimemenghasilkan nilai 2dengan offset 0x47f.



Ledakan! Dengan ID, tag dan cabang yang benar (atau sembarang sampah), "paket bagus" bisa berubah menjadi paket "pembunuh" segera setelah baris ptimeberakhir di alamat tertentu. Itu sangat aneh.



Saat membuat paket, saya bereksperimen dengan nilai heksadesimal yang berbeda. Situasinya menjadi lebih rumit. Ternyata perilaku pengontrol sepenuhnya bergantung pada nilai khusus ini yang terletak di alamat yang ditentukan dalam paket pertama yang diterima. Gambarnya seperti ini:



 0x47f = 31 HEX (1 ASCII) -  
 0x47f = 32 HEX (2 ASCII) -  
 0x47f = 33 HEX (3 ASCII) -  
 0x47f = 34 HEX (4 ASCII) -  (inoculation) 


Ketika saya mengatakan "tidak mempengaruhi", maksud saya tidak hanya tidak membunuh antarmuka, tetapi juga tidak menginokulasi (lebih atau kurang). Dan ketika saya mengatakan bahwa "antarmuka rusak", ingat deskripsi saya? Antarmuka sedang sekarat. Sama sekali.



Setelah pengujian baru, saya menemukan bahwa masalah tetap ada dengan setiap versi Linux yang dapat saya temukan, dengan FreeBSD, dan bahkan menyalakan mesin tanpa media yang dapat di-boot! Ini tentang perangkat keras, bukan OS. Wow.



Selain itu, dengan bantuan Ostinato, saya dapat membuat berbagai versi paket pembunuh: HTTP POST, permintaan gema ICMP, dan lainnya. Hampir semua yang saya inginkan. Dengan server HTTP yang dimodifikasi yang menghasilkan data dalam nilai byte (berdasarkan header, host, dll.), Mudah untuk membuat permintaan HTTP ke-200 yang berisi paket kematian dan mematikan mesin klien di belakang firewall!



Saya sudah menjelaskan betapa anehnya seluruh situasi itu. Tapi yang paling aneh adalah dengan vaksinnya. Ternyata jika paket yang diterima pertama berisi nilai apa pun (dari yang saya uji), dengan pengecualian 1, 2atau 3, jika antarmuka menjadi kebal terhadap kematian paket apa pun (berisi nilai 2atau 3). Selain itu, kode dan atribut ptimetelah kelipatan 10: 10, 20, 30, 40. Bergantung pada kombinasi Call ID, Tag, Branch, IP, URI, dan lainnya (dengan SDP buggy ini), atribut valid ini ptimeberbaris dalam urutan yang sempurna. Luar biasa!



Tiba-tiba menjadi jelas mengapa masalah itu terjadi secara sporadis. Sungguh menakjubkan bahwa saya bisa mengetahuinya. Saya telah bekerja dengan jaringan selama 15 tahun dan belum pernah melihat yang seperti ini. Dan aku ragu aku akan bertemu denganmu lagi. Mudah-mudahan ...



Saya menghubungi dua insinyur di Intel dan mengirimi mereka demo sehingga mereka dapat mereproduksi masalahnya. Setelah bereksperimen selama beberapa minggu, mereka menemukan bahwa masalahnya ada pada EEPROM di pengontrol 82574L. Mereka mengirimi saya EEPROM baru dan alat tulis. Sayangnya, kami tidak dapat mendistribusikannya, dan selain itu, modul kernel e1000e harus dibongkar dan dimuat ulang, sehingga alat tersebut tidak cocok untuk lingkungan kami. Untungnya (dengan sedikit pengetahuan tentang skema EEPROM) saya dapat menulis skrip bash dan kemudian secara ajaibethtoolmenyimpan nilai "tetap" dan mendaftarkannya dalam sistem tempat bug terwujud. Sekarang kami dapat mengidentifikasi perangkat yang bermasalah. Kami telah menghubungi vendor kami untuk menerapkan patch ke semua perangkat sebelum mengirimkannya kepada kami. Tidak diketahui berapa banyak pengontrol Intel Ethernet yang telah terjual.



Satu palet lagi



Pada tahun 2005, saya mengalami masalah yang tidak dapat dijelaskan di tempat kerja. Sehari setelah pematian yang tidak direncanakan (karena badai), saya mulai menerima panggilan dari pengguna yang mengeluh tentang batas waktu saat menyambung ke database. Karena kami memiliki jaringan yang sangat sederhana untuk 32 node dan dengan bandwidth yang tidak terpakai, saya khawatir bahwa server dengan database melakukan ping secara normal selama 15-20 menit, dan kemudian tanggapan "permintaan waktu habis" muncul dalam waktu sekitar dua menit. Server ini menjalankan pemantauan kinerja dan alat lainnya serta melakukan ping dari berbagai lokasi. Dengan pengecualian server, mesin lainnya dapat berkomunikasi dengan anggota jaringan lain sepanjang waktu. Saya mencari sakelar atau koneksi yang gagal tetapi tidak dapat menemukan penjelasan untuk kegagalan acak dan terputus-putus.



Saya meminta rekan kerja untuk melihat LED pada sakelar di gudang saat saya melakukan perutean dan menghubungkan kembali perangkat yang berbeda. Butuh waktu 45-50 menit, seorang rekan mengatakan kepada saya di radio "yang ini mati, yang ini bangun." Saya bertanya apakah dia memperhatikan pola apa pun.



- Ya ... saya perhatikan. Tapi Anda akan mengira saya gila. Setiap kali forklift mengeluarkan palet dari aula pengiriman, waktu tunggu terjadi setelah dua detik di server.



- APA???



- Ya. Dan server dipulihkan saat loader mulai mengirimkan pesanan baru.



Saya berlari untuk melihat forklift dan yakin bahwa dia menandai berhasil menyelesaikan pesanan dengan menyalakan beberapa magnetron raksasa. Tidak diragukan lagi, gelombang elektromagnetik dari kapasitor menyebabkan putusnya kontinum ruang-waktu dan untuk sementara mengganggu pengoperasian kartu jaringan server yang terletak di ruangan lain yang berjarak 50 meter. Tidak. Forklift hanya menumpuk kotak yang lebih besar di atas palet dengan kotak yang lebih kecil di atasnya, sambil memindai setiap kotak dengan pemindai kode batang nirkabel. Aha! Mungkin pemindai yang mengakses server database, menyebabkan kueri lain gagal. Nggak. Saya memeriksa dan menemukan bahwa pemindai tidak ada hubungannya dengan itu. Router nirkabel dan UPS-nya di aula pengiriman telah dikonfigurasi dengan benar dan berfungsi normal. Alasannya hal lain, karena sebelum penutupan karena badai, semuanya berjalan dengan baik.



Segera setelah waktu tunggu berikutnya dimulai, saya berlari ke aula pengiriman dan melihat loader mengisi palet berikutnya. Segera setelah dia meletakkan empat kotak besar sampo di atas nampan kosong, servernya mati lagi! Saya tidak percaya pada absurditas dari apa yang terjadi, dan selama lima menit saya melepas dan meletakkan kotak sampo, dengan hasil yang sama. Saya baru saja akan berlutut dan berdoa untuk belas kasihan Dewa Intranet ketika saya melihat bahwa router di aula pengiriman tergantung sekitar 30 cm di bawah level kotak di palet. Ada petunjuk!



Ketika kotak besar diletakkan di atas palet, router nirkabel kehilangan pandangan ke gudang luar. Setelah sepuluh menit, saya menyelesaikan masalah. Inilah yang terjadi. Selama badai, terjadi pemadaman listrik yang menjatuhkan satu-satunya perangkat yang tidak terhubung ke UPS - router nirkabel uji di kantor saya. Pengaturan default entah bagaimana mengubahnya menjadi repeater untuk satu-satunya router nirkabel lain yang tergantung di aula pengiriman. Kedua perangkat hanya dapat berkomunikasi satu sama lain ketika tidak ada palet di antara mereka, tetapi sinyalnya pun tidak terlalu kuat. Ketika router berbicara, mereka membuat loop di jaringan kecil saya, dan kemudian semua paket lain ke server database hilang. Server memiliki sakelar sendiri dari router utama, oleh karena itu, sebagai node jaringan, itu lebih jauh.Sebagian besar komputer lain menggunakan sakelar 16-port yang sama, jadi saya dapat melakukan ping di antara mereka tanpa masalah.



Dalam satu detik, saya memecahkan masalah yang telah saya siksa selama empat jam: Saya mematikan daya ke router uji. Tidak ada lagi waktu tunggu di server.



Seperti film Tron, hanya di komputer Apple IIgs



Salah satu film favorit saya saat kecil adalah Tron, yang dibuat pada awal 1980-an. Ini bercerita tentang seorang programmer yang "digital" dan terserap di dunia komputer yang dihuni oleh program-program yang dipersonalisasi. Protagonis bergabung dengan kelompok perlawanan dalam upaya untuk menggulingkan Program Pengendalian Master (MCP) penindas, program pemberontakan yang berkembang, mendapatkan nafsu untuk kekuasaan dan mencoba untuk mengambil alih sistem komputer Pentagon.



Dalam salah satu adegan program yang paling mengesankan, para karakter berlomba dengan sepeda ringan - mobil roda dua yang terlihat seperti sepeda motor yang meninggalkan tembok. Salah satu protagonis memaksa pepelats musuh untuk menabrak tembok di arena, membuat lubang tembus. Para pahlawan berurusan dengan lawan mereka dan melarikan diri melalui lubang menuju kebebasan - langkah pertama menuju penggulingan MCP.



Ketika saya menonton film itu, saya tidak tahu bahwa bertahun-tahun kemudian saya akan secara tidak sengaja menciptakan kembali dunia Tron, program pemberontak dan segala sesuatu lainnya di komputer Apple IIgs.



Ini adalah bagaimana hal itu terjadi. Ketika saya mulai belajar program, saya memutuskan untuk membuat game siklus ringan dari Tron. Bersama teman saya Marco, saya menulis program di Apple IIgs di ORCA / Pascal dan assembler 65816. Selama permainan, layarnya dicat hitam dengan garis tepi putih. Setiap baris mewakili salah satu pemain. Kami menampilkan skor game berturut-turut di bagian bawah layar. Secara grafis, ini bukanlah program yang paling canggih, tetapi sederhana dan menyenangkan. Dia terlihat seperti ini:





Permainan mendukung hingga empat pemain jika mereka duduk di depan satu keyboard. Itu tidak nyaman, tapi berhasil. Kami jarang bisa mendapatkan cukup orang untuk menggunakan keempat siklus cahaya, jadi Marco menambahkan pemain yang dikendalikan komputer yang dapat bersaing secara wajar.



Perlombaan senjata



Permainannya sudah sangat lucu, tapi kami ingin bereksperimen. Kami telah menambahkan roket agar pemain bisa lolos dari kecelakaan yang akan terjadi. Seperti yang dijelaskan Marco nanti:



Manusia dan AI masing-masing memiliki tiga rudal yang dapat digunakan selama pertandingan. Ketika roket menghantam dinding, terjadi "ledakan", yang latar belakangnya dicat hitam, sehingga menghilangkan bagian jejak yang ditinggalkan oleh siklus cahaya sebelumnya.


Segera, pemain dan komputer dapat meledakkan jalan keluar dari situasi sulit dengan roket. Meski para puritan Tron akan tertawa mendengarnya, program-program dalam film tersebut tidak memiliki kemewahan seperti roket.



Pelarian



Seperti semua kejadian yang tidak biasa dan ganjil, itu juga tidak terduga.



Suatu ketika, ketika Marco dan saya bermain melawan dua pemain komputer, kami menjebak salah satu loop AI di antara dindingnya sendiri dan tepi bawah layar. Mengantisipasi kecelakaan yang akan terjadi, dia menembakkan roket, seperti yang selalu dia lakukan sebelumnya. Tapi kali ini, alih-alih tembok, dia membidik di perbatasan layar, yang tampak seperti jejak salah satu siklus cahaya. Rudal itu menghantam perbatasan, meninggalkan lubang seukuran siklus cahaya, dan komputer segera keluar dari arena permainan melalui itu. Kami menatap dengan bingung pada siklus cahaya yang melewati garis skor. Dia dengan mudah menghindari tabrakan dengan simbol dan kemudian meninggalkan layar sama sekali.



Dan segera setelah itu, sistem macet.





Pikiran kami bergoyang saat kami mencoba memahami apa yang telah terjadi. Komputer menemukan cara untuk keluar dari permainan. Ketika siklus cahaya meninggalkan layar, itu lolos ke memori komputer, seperti di film. Kami ternganga saat menyadari apa yang telah terjadi.



Apa yang kami lakukan ketika kami menemukan cacat pada program kami yang secara teratur dapat merusak seluruh sistem? Kami melakukannya lagi. Pertama kami mencoba keluar dari batasan sendiri. Kemudian mereka memaksa komputer untuk kabur lagi. Setiap kali kami dihadiahi dengan sistem crash yang mempesona. Terkadang lampu drive berkedip saat drive menggerutu tanpa henti. Di lain waktu, layar dipenuhi dengan karakter yang tidak berarti, atau pembicara membuat jeritan atau senandung rendah. Dan terkadang semuanya terjadi sekaligus, dan komputer berada dalam kondisi berantakan total.



Kenapa ini terjadi? Untuk memahami ini, mari kita lihat arsitektur komputer Apple IIgs.



(Tidak) memori yang dilindungi



Sistem operasi Apple IIgs tidak memiliki memori yang dilindungi, yang muncul di sistem operasi yang lebih baru ketika area memori ditetapkan ke program dan dilindungi dari akses luar. Oleh karena itu, program untuk Apple IIgs dapat membaca dan menulis apa saja (kecuali untuk ROM). IIgs menggunakan I / O yang terikat memori untuk mengakses perangkat seperti floppy drive, sehingga floppy drive dapat diaktifkan dengan membaca dari area memori tertentu. Arsitektur ini memungkinkan program grafik untuk membaca dan menulis langsung ke memori layar.



Gim ini menggunakan salah satu mode grafis Apple IIgs - Super Hi-Res: resolusi luar biasa 320x200 piksel dengan palet 16 warna. Untuk memilih palet, programmer menentukan 16 entri (dinomori dari 0 hingga 15 atau dari $ 0 hingga F dalam format heksadesimal) untuk nilai warna 12-bit. Untuk menggambar di layar, Anda dapat membaca dan menulis warna langsung ke memori video.



Algoritme deteksi tabrakan



Kami memanfaatkan fitur ini dan menerapkan detektor kerusakan dengan membaca langsung dari memori video. Permainan menghitung untuk setiap siklus cahaya posisi berikutnya berdasarkan arah saat ini, dan membaca piksel ini dari memori video. Jika posisinya kosong, yaitu diwakili oleh piksel hitam (entri di palet $ 0), maka permainan dilanjutkan. Tetapi jika posisi itu diambil, pemain menabrak siklus cahaya atau bingkai putih layar (entri di palet 15 atau $ F). Contoh:





Sudut kiri atas layar ditampilkan di sini. Warna $ F menunjukkan batas putih, dan warna $ 1 menunjukkan siklus lampu hijau pemain. Itu bergerak ke kiri seperti yang ditunjukkan oleh panah, yaitu, piksel berikutnya kosong, warnanya $ 0. Jika pemain terus bergerak ke arah ini selama lebih dari satu putaran, dia akan bertabrakan dengan dinding (warna $ F) dan pecah.



Melampaui



Algoritma untuk menentukan piksel berikutnya menggunakan matematika assembler dengan cepat menghitung alamat memori dari satu piksel di atas, di bawah, ke kiri, atau ke kanan dari piksel saat ini. Karena piksel apa pun di layar adalah alamat di memori, algoritme hanya menghitung alamat baru untuk dibaca. Dan ketika siklus cahaya meninggalkan layar, algoritme menentukan tempat di memori sistem untuk memeriksa tabrakan dengan dinding. Ini berarti bahwa siklus cahaya sekarang melintasi memori sistem, tanpa tujuan mengaktifkan bit dan "menabrak" ke dalam memori.



Menulis ke lokasi acak dalam memori sistem bukanlah keputusan arsitektur yang bijaksana. Tidak mengherankan, game tersebut mengalami crash karena hal ini. Seorang pemain manusia tidak akan mengendarai secara membabi buta dan biasanya akan langsung menabrak, yang membatasi ruang lingkup masalah sistem. Dan AI tidak memiliki kelemahan seperti itu. Komputer langsung memindai posisi di sekitarnya untuk menentukan apakah itu menabrak dinding dan mengubah arah. Artinya, dalam tampilan komputer, memori sistem tidak berbeda dengan memori layar. Seperti yang dijelaskan Marco:



, , . , , 0. «» , . «», - - , , — . , - , .


Hasilnya, kami tidak hanya menciptakan kembali perlombaan siklus cahaya dari film, tetapi juga pelarian itu sendiri. Seperti di film, pelarian itu memiliki konsekuensi besar.



Hal ini sulit diulang hari ini, karena sistem operasi telah memperoleh memori yang dilindungi. Tapi saya masih bertanya-tanya apakah ada program seperti Tron yang mencoba melarikan diri dari "ruang terlindung" mereka dalam upaya untuk mencegah kode AI pemberontak mengambil alih Pentagon.



Saya kira untuk mengetahuinya, kita perlu menunggu penemuan digitalisasi kesadaran.



Duduklah untuk masuk



Setiap programmer tahu bahwa debugging itu sulit. Meskipun, untuk debugger hebat, pekerjaan itu terlihat sangat sederhana. Pemrogram yang putus asa mendeskripsikan bug yang mereka tangkap selama berjam-jam, master mengajukan beberapa pertanyaan, dan setelah beberapa menit pemrogram melihat kode yang salah di depan mereka. Seorang ahli debugging tidak lupa bahwa selalu ada penjelasan logis, tidak peduli betapa misteriusnya sistem itu pada pandangan pertama.



Sikap ini diilustrasikan oleh sebuah cerita yang terjadi di IBM Yorktown Heights Research Center. Programmer baru saja menginstal workstation baru. Semuanya baik-baik saja ketika dia duduk di depan komputer, tetapi dia tidak bisa masuk saat dia berdiri. Perilaku ini selalu direproduksi: programmer selalu login sambil duduk, sambil berdiri - dia tidak bisa sekali pun.



Banyak dari kita hanya duduk di sana dan bertanya-tanya. Bagaimana komputer tahu jika mereka berdiri di depannya atau duduk? Namun, debugger yang baik tahu pasti ada alasannya. Hal pertama yang terlintas dalam pikiran adalah listrik. Kabel rusak di bawah karpet, atau muatan statis? Tapi masalah listrik jarang terjadi 100% setiap saat. Salah satu rekan akhirnya menanyakan pertanyaan yang tepat: bagaimana programmer log in sambil duduk dan berdiri? Cobalah sendiri.



Alasannya adalah keyboard: kedua tombol itu terbalik. Ketika programmer sedang duduk, dia akan mengetik secara membabi buta, dan masalahnya tidak diperhatikan. Dan ketika dia berdiri, itu membuatnya bingung, dia mencari tombol dan menekannya. Berbekal petunjuk ini dan obeng, ahli debugging menukar tombol dan semuanya berhasil.



Sistem perbankan yang diterapkan di Chicago bekerja dengan baik selama berbulan-bulan. Tapi itu berhenti tiba-tiba saat pertama kali digunakan untuk memproses data internasional. Programmer mencari-cari kode selama berhari-hari, tetapi tidak dapat menemukan satu perintah pun yang menyebabkan penghentian program. Ketika mereka melihat lebih dekat pada perilakunya, mereka menemukan bahwa program akan berhenti ketika data Ekuador dimasukkan. Analisis menunjukkan bahwa ketika pengguna mengetik nama ibu kota (Quito), program menafsirkannya sebagai perintah keluar!



Suatu hari Bob Martin menemukan sistem yang "bekerja sekali dua kali". Dia memproses transaksi pertama dengan benar, dan dalam semua transaksi berikutnya ada masalah kecil. Saat sistem di-boot ulang, transaksi pertama diproses lagi dengan benar dan gagal pada semua transaksi berikutnya. Ketika Bob mendeskripsikan perilaku ini sebagai "berjalan sekali dua kali," pengembang segera menyadari bahwa mereka perlu mencari variabel yang diinisialisasi dengan benar saat program dimuat, tetapi tidak diatur ulang setelah transaksi pertama. Dalam semua kasus, pertanyaan yang tepat memungkinkan pemrogram yang bijak dengan cepat mengidentifikasi kesalahan yang tidak menyenangkan: “Apa yang Anda lakukan secara berbeda saat Anda berdiri dan duduk? Tunjukkan bagaimana Anda login dalam kedua kasus "," Apa sebenarnya yang Anda masukkan sebelum program berakhir? " “Apakah programnya bekerja dengan benar sebelum crash dimulai? Berapa kali?"



Rick Lemons mengatakan pelajaran debugging terbaik yang dia pelajari adalah ketika dia melihat penampilan pesulap. Dia telah melakukan selusin trik yang mustahil, dan Lemons merasa bahwa dia mempercayainya. Dia kemudian mengingatkan dirinya sendiri bahwa yang tidak mungkin itu tidak mungkin, dan dia menguji setiap trik untuk membuktikan ketidakkonsistenan yang jelas ini. Lemon mulai dengan kebenaran yang tak tergoyahkan - hukum fisika, dan dari situ ia mulai mencari penjelasan sederhana untuk setiap trik. Sikap ini menjadikan Lemon salah satu debugger terbaik yang pernah saya temui.



Buku debugging terbaik menurut saya adalah The Medical Detectives, ditulis oleh Berton Roueche dan diterbitkan oleh Penguin pada tahun 1991. Para pahlawan dalam buku ini men-debug sistem yang kompleks, dari orang yang sakit sedang hingga kota yang sangat sakit. Metode pemecahan masalah yang digunakan di sana dapat langsung digunakan dalam debugging sistem komputer. Kisah nyata ini sama memesona seperti fiksi apa pun.



Kasus Email 500 Mil



Ini adalah situasi yang kedengarannya tidak dapat dibayangkan ... Saya hampir menolak untuk membicarakannya karena ini adalah sepeda yang bagus untuk konferensi. Saya sedikit mengubah cerita untuk melindungi pelakunya, untuk membuang detail yang tidak relevan dan membosankan, dan secara keseluruhan untuk membuat cerita lebih menarik.



Beberapa tahun lalu, saya mengelola sistem email di kampus. Kepala departemen statistik menelepon saya.



- Kami punya masalah dengan pengiriman surat.



- Apa masalahnya?



“Kami tidak dapat mengirim surat lebih dari 500 mil.



Kopi saya tersedak.



- Tidak dipahami.



“Kami tidak dapat mengirim surat dari departemen lebih dari 500 mil. Bahkan, sedikit lebih jauh. Kira-kira 520 mil. Tapi ini batasnya.



“Hmm… Sebenarnya, email tidak berfungsi seperti itu,” jawabku, mencoba untuk mengontrol kepanikan dalam suaraku. Anda tidak dapat menunjukkan kepanikan dalam percakapan dengan kepala departemen, bahkan salah satunya seperti departemen statistik. - Mengapa Anda memutuskan bahwa Anda tidak dapat mengirim surat lebih dari 500 mil?



"Saya belum memutuskan ," jawabnya berat. - Anda tahu, ketika kami melihat apa yang terjadi beberapa hari yang lalu ...



- Anda menunggu beberapa HARI? Aku memotongnya dengan suara gemetar. - Dan kamu tidak bisa mengirim surat selama ini?



- Kami bisa mengirim. Tidak lebih jauh ...



"" Lima ratus mil, ya, "aku menyelesaikannya. - Bersih. Tapi kenapa kamu tidak menelepon lebih awal?



“Nah, sampai saat ini kami tidak memiliki cukup data untuk memastikan apa yang terjadi.



Tepatnya, ini adalah kepala statistik .



- Ngomong-ngomong, saya meminta salah satu ahli geostatistik untuk menangani ini ...



- Ahli geostatistik ...



- Ya, dan dia membuat peta yang menunjukkan radius di mana kami dapat mengirim surat, sekitar 500 mil. Ada beberapa tempat di zona ini dimana surat kita tidak sampai sama sekali atau berkala, tapi diluar radius kita tidak bisa mengirimkan apapun.



"Begitu," kataku, dan menundukkan kepalaku ke tanganku. - Kapan itu dimulai? Anda mengatakan itu beberapa hari yang lalu, tetapi kami belum mengubah apa pun di sistem Anda.



- Seorang konsultan datang, menambal dan me-reboot server kami. Tetapi saya meneleponnya, dan dia mengatakan bahwa dia tidak menyentuh sistem surat.



"Oke, izinkan saya melihat dan menelepon Anda kembali," jawab saya, hampir tidak percaya bahwa saya berpartisipasi dalam hal seperti itu. Hari ini bukanlah yang pertama di bulan April. Saya mencoba mengingat apakah seseorang berhutang lelucon kepada saya.



Saya masuk ke server departemen mereka dan mengirim beberapa email verifikasi. Ini terjadi di North Carolina Research Triangle, dan surat itu tiba di kotak surat saya tanpa masalah. Begitu pula surat-surat yang dikirim ke Richmond, Atlanta dan Washington. Ada juga surat yang dikirim ke Princeton (400 mil).



Tapi kemudian saya mengirim surat ke Memphis (600 mil). Itu tidak datang. Di Boston, itu tidak datang. Di Detroit, itu tidak datang. Saya mengeluarkan buku alamat saya dan mulai mengirim surat melaluinya. Itu datang ke New York (420 mil), tetapi tidak sampai ke Providence (580 mil).



Saya mulai meragukan kewarasan saya. Menulis untuk seorang teman di Carolina Utara yang penyedia di Seattle. Untungnya, surat itu tidak sampai. Jika masalahnya terletak pada lokasi penerima, bukan server email mereka, saya mungkin akan menangis.



Setelah mengetahui bahwa masalahnya memang ada (luar biasa) dan dapat direkonstruksi, saya mulai menganalisis file sendmail.cf. Dia tampak baik-baik saja. Seperti biasa. Saya membandingkannya dengan sendmail.cf di direktori home saya. Tidak ada perbedaan - itu adalah file yang saya tulis. Dan saya cukup yakin saya tidak menyertakan opsi tersebut FAIL_MAIL_OVER_500_MILES. Dalam kebingungan, saya telnetted port SMTP. Server merespon dengan gembira dengan banner Sendmail dari SunOS.



Tunggu ... banner Sendmail dari SunOS? Saat itu, Sun masih mengapalkan Sendmail 5 dengan sistem operasinya, meski Sendmail 8 sudah diimplementasikan secara penuh. Karena saya adalah seorang sysadmin yang baik, saya memperkenalkan Sendmail 8 sebagai standar. Selain itu, karena saya adalah seorang sysadmin yang baik, saya menulis sendmail.cf, yang menggunakan opsi dokumentasi mandiri yang panjang dan keren serta nama variabel yang tersedia di Sendmail 8, alih-alih kode tanda baca samar yang digunakan di Sendmail 5.



Semuanya sesuai. dan saya tersedak lagi kopi saya yang sudah dingin. Sepertinya ketika konsultan "menambal server" dia mengupgrade versi SunOS dimana dia meluncurkan versi lama Sendmail. Untungnya, file sendmail.cf bertahan, tetapi sekarang tidak berfungsi.



Ternyata Sendmail 5 - setidaknya versi yang dikirim Sun yang memiliki sejumlah perbaikan - dapat bekerja dengan sendmail.cf untuk Sendmail 8, karena sebagian besar aturannya sama. Tetapi opsi konfigurasi lama yang baru tidak lagi dikenali dan dibuang. Dan karena tidak ada default di biner Sendmail untuk kebanyakan dari mereka, program tidak menemukan nilai yang cocok di sendmail.cf dan mengatur ulang ke nol.



Salah satu nilai nol ini adalah waktu tunggu sambungan ke server SMTP jauh. Setelah beberapa percobaan, ternyata pada mesin khusus ini, di bawah beban normal, waktu tunggu nol mengarah ke pemutusan dalam waktu sedikit lebih dari tiga milidetik.



Pada saat itu, jaringan kampus sepenuhnya beralih. Paket keluar tidak ditunda sampai mencapai router di sisi lain melalui POP. Artinya, durasi koneksi ke host jarak jauh yang dimuat dengan lemah di jaringan tetangga sebagian besar bergantung pada jarak yang ditempuh dengan kecepatan cahaya, dan bukan pada penundaan acak oleh router.



Merasa sedikit pusing, saya masuk di baris perintah:



$ units
1311 units, 63 prefixes

You have: 3 millilightseconds
You want: miles
        * 558.84719
        / 0.0017893979


"500 mil atau lebih."






Bersambung.



All Articles