Menguji masalah tahun 2038 di Windows
Pada 19 Januari 2038 pukul 03:14:07 UTC, penghitung detik sejak 1970 yang bertanda 32 bit habis. Jam Windows terus berjalan melewatinya - program, format berkas, dan pustaka yang menyimpan salinan 32 bit sendiri tidak. Berikut cara menemukannya di satu aplikasi, tanpa menyetel tanggal seluruh mesin ke 2038.
Di mana bug itu masih bisa bersembunyi
Jam Windows adalah penghitung 64 bit berisi langkah 100 nanodetik sejak 1601, jadi ia tidak
mengenal 2038. Tipe time_t pada pustaka runtime C bernilai 64 bit secara bawaan sejak
Visual Studio 2005. Yang tersisa adalah kode yang memilih waktu 32 bit atau kehilangan separuh
atasnya di tengah jalan:
- Build 32 bit yang dikompilasi dengan
_USE_32BIT_TIME_T, atau yang memanggil_time32dan__time32_tsecara langsung. Dokumentasi Microsoft sendiri memperingatkan bahwa aplikasi seperti itu bisa gagal setelah 18 Januari 2038. - Waktu 64 bit yang disimpan dalam
intataulong. Di Windows keduanya 32 bit, bahkan di program 64 bit. - Pustaka, format berkas, protokol jaringan, dan kolom basis data yang menyimpan detik sejak 1970 dalam 32 bit.
- Kode yang menambahkan tahun. Lisensi dua puluh tahun, jadwal cicilan tiga puluh tahun, atau sertifikat yang berlaku hingga 2040 melewati batas itu jauh sebelum 2038 tiba.
Melewati batas di satu aplikasi
Batas itu didefinisikan dalam UTC dan --at dibaca dalam zona sesi, jadi kunci zona ke
UTC saat Anda menulis momennya sendiri. Skenario siap pakai sudah membawa momen UTC absolut dan
tidak memerlukan zona.
# Skenarionya: sesi dimulai tepat di batas, 03:14:07 UTC chrono run "C:\apps\test.exe" --preset year-2038 --report session.txt # Mulai tujuh belas detik sebelumnya dan biarkan aplikasi melewatinya secara langsung chrono run "C:\apps\test.exe" --at 2038-01-19T03:13:50 --zone +00:00 --report session.txt # Mulai lebih awal dan jalankan dengan kecepatan x60 - batasnya tiba dalam sekitar 14 detik chrono run "C:\apps\test.exe" --at 2038-01-19T03:00:00 --zone +00:00 --mode x60 # Atau jalankan dengan tanggal hari ini dan lompati batasnya saat aplikasi terbuka chrono run "C:\apps\test.exe" --jump-after 5:2038-01-19T03:14:05 --zone +00:00
Satu detik setelah batas, penghitung 32 bit bertanda menjadi -2.147.483.648, yang terbaca sebagai 13 Desember 1901, 20:45:52 UTC. Tanggal tahun 1901, angka negatif, butir yang tiba-tiba kedaluwarsa atau terurut paling depan, pengecualian yang dilempar dari kode tanggal - begitulah wujud luapan itu dari luar.
Menyetel jam asli ke 2038 adalah cara lain untuk sampai ke sini, dan cara yang paling banyak merusak. Apa yang terjadi saat Anda mengubah tanggal sistem →
Memastikan batas itu sampai ke program
Pengujian yang lolos karena program tidak pernah melihat 2038 lebih buruk daripada tanpa pengujian. Laporan di akhir setiap sesi menyebutkan jam mana yang dibaca program dan berapa kali:
Chrono Mock - session report
target: .\build\test.exe
verdict: WORKS - time substitution took effect (processes: 1)
every process that read time saw the session clock
session: fake clock reached 2038-01-19T03:14:08
real elapsed 1.3s, fake elapsed 1.3s
covered channels (substituted, with call counts, 10 calls in all):
- pid 21240: GetSystemTimeAsFileTime (5 calls)
- pid 21240: GetLocalTime (5 calls)
Baris session memastikan jam aplikasi telah melewati batas. Putusan works dengan hitungan panggilan berarti program membaca jam dan menerima tanggal 2038; works partially menyebutkan kanal yang dibacanya lewat jalur lain. Apa arti putusan-putusan itu →
Yang tidak dibuktikan oleh pengujian yang lolos
- Hanya jam milik program itu sendiri yang bergeser. Tanggal yang ia muat dari
berkas atau basis data adalah apa yang tersimpan di sana, jadi tanggal 2038 di dalam data
adalah pengujian tersendiri. Kalkulator tanggal menghitung tanggal semacam itu untuk Anda:
chrono calc --base 2038-01-19T03:14:07 --zone +00:00 --shift +1s - Server yang diajak bicara program tetap berjalan di tanggal asli. Batas 32 bit di sisi itu berada di luar jangkauan, dan sesi memperingatkan saat melihat program membuka koneksi jaringan.