Chrono Mock
ภาษาไทย

ทดสอบปัญหาปี 2038 บน Windows

เมื่อ 03:14:07 UTC ของวันที่ 19 มกราคม 2038 ตัวนับวินาทีนับจากปี 1970 แบบ 32 บิตมีเครื่องหมายจะหมดลง นาฬิกาของ Windows เดินต่อไปได้ - แต่โปรแกรม รูปแบบไฟล์ และไลบรารีที่เก็บสำเนา 32 บิตของตัวเองไว้ทำไม่ได้ นี่คือวิธีหาของเหล่านั้นในแอปเดียว โดยไม่ต้องตั้งวันที่ของทั้งเครื่องเป็นปี 2038

บั๊กยังซ่อนอยู่ที่ไหนได้บ้าง

นาฬิกาของ Windows เป็นตัวนับ 64 บิตของช่วงละ 100 นาโนวินาทีนับจากปี 1601 จึงไม่มีปี 2038 ชนิด time_t ของไลบรารีรันไทม์ C เป็น 64 บิตโดยค่าเริ่มต้นตั้งแต่ Visual Studio 2005 สิ่งที่เหลืออยู่คือโค้ดที่เลือกเวลา 32 บิต หรือทำครึ่งบนหล่นหายระหว่างทาง:

  • บิลด์ 32 บิตที่คอมไพล์ด้วย _USE_32BIT_TIME_T หรือเรียก _time32 และ __time32_t โดยตรง เอกสารของ Microsoft เองก็เตือนว่าแอปแบบนี้อาจล้มเหลวหลังวันที่ 18 มกราคม 2038
  • เวลา 64 บิตที่เก็บไว้ใน int หรือ long บน Windows ทั้งสองมีขนาด 32 บิต แม้ในโปรแกรม 64 บิตก็ตาม
  • ไลบรารี รูปแบบไฟล์ โปรโตคอลเครือข่าย และคอลัมน์ในฐานข้อมูลที่เก็บวินาทีนับจากปี 1970 ไว้ใน 32 บิต
  • โค้ดที่บวกปีเข้าไป ไลเซนส์ยี่สิบปี ตารางผ่อนชำระสามสิบปี หรือใบรับรองที่ใช้ได้ถึงปี 2040 ข้ามเส้นนี้ไปนานก่อนที่ปี 2038 จะมาถึง

ข้ามเส้นแบ่งในแอปเดียว

ขีดจำกัดนี้นิยามเป็น UTC และ --at อ่านในโซนของเซสชัน ดังนั้นเมื่อเขียนช่วงเวลาเอง ให้ตรึงโซนเป็น UTC สถานการณ์สำเร็จรูปมีช่วงเวลา UTC แบบสัมบูรณ์อยู่แล้ว จึงไม่ต้องใช้โซน

# สถานการณ์: เซสชันเริ่มที่ขีดจำกัดพอดี 03:14:07 UTC
chrono run "C:\apps\test.exe" --preset year-2038 --report session.txt

# เริ่มก่อนหน้านั้นสิบเจ็ดวินาที แล้วให้แอปข้ามเส้นแบบสด ๆ
chrono run "C:\apps\test.exe" --at 2038-01-19T03:13:50 --zone +00:00 --report session.txt

# เริ่มเร็วกว่านั้นแล้วรันเร็วขึ้น 60 เท่า - ขีดจำกัดมาถึงในราว 14 วินาที
chrono run "C:\apps\test.exe" --at 2038-01-19T03:00:00 --zone +00:00 --mode x60

# หรือรันด้วยวันที่ของวันนี้ แล้วกระโดดข้ามระหว่างที่แอปเปิดอยู่
chrono run "C:\apps\test.exe" --jump-after 5:2038-01-19T03:14:05 --zone +00:00

หนึ่งวินาทีหลังขีดจำกัด ตัวนับ 32 บิตมีเครื่องหมายจะกลายเป็น -2,147,483,648 ซึ่งอ่านได้เป็น 13 ธันวาคม 1901 เวลา 20:45:52 UTC วันที่ในปี 1901 ตัวเลขติดลบ รายการที่หมดอายุขึ้นมาเฉย ๆ หรือไปอยู่หัวลำดับ ข้อยกเว้นที่โยนออกมาจากโค้ดวันที่ - การล้นมองจากภายนอกหน้าตาเป็นแบบนี้

การตั้งนาฬิกาจริงเป็นปี 2038 คืออีกทางที่พามาถึงตรงนี้ และเป็นทางที่พังมากที่สุด จะเกิดอะไรขึ้นเมื่อคุณเปลี่ยนวันที่ของระบบ →

ตรวจว่าไปถึงโปรแกรมแล้ว

การทดสอบที่ผ่านเพราะโปรแกรมไม่เคยเห็นปี 2038 แย่กว่าไม่มีการทดสอบ รายงานตอนท้ายของทุกเซสชันบอกว่าโปรแกรมอ่านนาฬิกาเรือนไหนและกี่ครั้ง:

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)

บรรทัด session ยืนยันว่านาฬิกาของแอปผ่านขีดจำกัดไปแล้ว ผลสรุป works พร้อมจำนวนการเรียกหมายความว่าโปรแกรมอ่านนาฬิกาและได้รับวันที่ปี 2038 ส่วน works partially จะระบุช่องทางที่มันอ่านผ่านเส้นทางอื่น ผลสรุปมีความหมายว่าอะไร →

สิ่งที่การทดสอบที่ผ่านไม่ได้พิสูจน์

  • เลื่อนไปเฉพาะนาฬิกาของโปรแกรมเอง วันที่ที่มันโหลดจากไฟล์หรือฐานข้อมูลก็คือสิ่งที่เก็บไว้ตรงนั้น ดังนั้นวันที่ปี 2038 ที่อยู่ในข้อมูลเป็นอีกการทดสอบหนึ่ง เครื่องคิดเลขวันที่คำนวณวันที่แบบนี้ให้คุณได้: chrono calc --base 2038-01-19T03:14:07 --zone +00:00 --shift +1s
  • เซิร์ฟเวอร์ที่โปรแกรมคุยด้วยยังทำงานบนวันที่จริง ขีดจำกัด 32 บิตฝั่งนั้นอยู่นอกเหนือการเอื้อมถึง และเซสชันจะเตือนเมื่อเห็นโปรแกรมเปิดการเชื่อมต่อเครือข่าย

ลองใช้