"Infidel" và lỗi bộ nhớ kỳ lạ bị bỏ sót suốt 40 năm
Một lỗi lập trình trong game "Infidel" của Infocom, phát hành từ năm 1983, vừa được phát hiện sau hơn 40 năm. Lỗi này ghi đè bộ nhớ ngoài ý muốn nhưng hầu như không ảnh hưởng đến trải nghiệm người chơi, khiến nó tồn tại âm thầm trong mọi bản sao của trò chơi.
"Infidel" và lỗi bộ nhớ kỳ lạ bị bỏ sót suốt 40 năm
Một lỗi lập trình trong trò chơi Infidel của hãng Infocom vừa được phát hiện sau hơn bốn thập kỷ tồn tại âm thầm. Điều đáng chú ý là lỗi này ghi đè bộ nhớ một cách ngẫu nhiên nhưng hầu như không ai nhận ra, kể cả những người chơi kỳ cựu lẫn đội ngũ kiểm thử của Infocom.
Câu chuyện này là một ví dụ thú vị về cách các lỗi phần mềm có thể "sống sót" qua nhiều thế hệ nếu chúng không gây ra hậu quả rõ ràng trong quá trình sử dụng thông thường.
Bối cảnh: Trò chơi và cơ chế "sa mạc vô tận"
Infidel là một trò chơi phiêu lưu văn bản (interactive fiction) lấy bối cảnh sa mạc Ai Cập xa xôi. Người chơi bắt đầu tại trại của mình, với sông Nile ở phía tây và một vùng sa mạc rộng lớn ở phía đông.
Điểm đặc biệt của trò chơi nằm ở cơ chế ENDLESS-DESERT (sa mạc vô tận) — một kỹ thuật lần đầu xuất hiện trong trò chơi Enchanter. Thay vì tạo ra vô số phòng riêng biệt, trò chơi chỉ dùng một phòng duy nhất để đại diện cho mọi vị trí sa mạc chưa được lập bản đồ. Khi người chơi di chuyển, trò chơi theo dõi vĩ độ và kinh độ, rồi xử lý các đối tượng được thả xuống thông qua một mảng gọi là DESERT-TABLE.
Cơ chế này hoạt động như sau:
- Khi người chơi thả đồ vật xuống sa mạc, tọa độ và ID đối tượng được ghi vào mảng DESERT-TABLE
- Khi người chơi quay lại tọa độ cũ, trò chơi sẽ khôi phục các đối tượng từ mảng này
- Có một xác suất một phần ba rằng đồ vật bị cát vùi lấp và mất vĩnh viễn
Phát hiện lỗi: Khi mảng bộ nhớ "biến mất"
Tác giả Andrew Plotkin, người đang làm công cụ gỡ lỗi cho các trò chơi Infocom, đã phát hiện ra điều bất thường khi cố hiển thị nội dung của DESERT-TABLE trong công cụ của mình. Mảng này liên tục trống rỗng, dù các đối tượng rõ ràng đang được dịch chuyển vào và ra khỏi phòng.
Khi dịch ngược mã của hàm DESERT-TO-TABLE, ông phát hiện ra vấn đề nằm ở cách trình biên dịch ZIL xử lý các đối số mặc định.
"Không ai nghĩ đến trường hợp này — một đối số có giá trị mặc định là một biến toàn cục."
Cụ thể, thay vì gán giá trị mặc định của TBL là địa chỉ bộ nhớ 11129 (vị trí thực của mảng DESERT-TABLE), trình biên dịch lại gán giá trị 30 — vốn chỉ là số thứ tự của biến toàn cục DESERT-TABLE trong bảng biến của Z-machine.
Hậu quả: Ghi đè dữ liệu nén văn bản
Kết quả là khi trò chơi ghi các số đối tượng vào bộ nhớ, nó không ghi vào địa chỉ 11129 mà ghi đè lên các địa chỉ từ 30 trở đi.
Trong kiến trúc Z-machine phiên bản 3, 30 byte đầu tiên là dữ liệu header quan trọng. May mắn thay, các địa chỉ từ 30 đến 63 không được sử dụng — nhưng địa chỉ 64 là điểm bắt đầu của bảng viết tắt (abbreviations table), một phần của hệ thống nén văn bản.
Điều này dẫn đến những hiện tượng kỳ lạ:
- Nếu thả đủ chín đồ vật xuống sa mạc, đồ vật cuối cùng sẽ ghi đè lên đầu bảng viết tắt
- Văn bản hiển thị trong trò chơi bắt đầu bị thay thế từ ngữ một cách vô lý
- Trong một số trường hợp, trò chơi có thể bị treo vì vòng lặp vô hạn trong quá trình in văn bản
Một ví dụ về văn bản bị hỏng mà Plotkin ghi lại:
"You are in the desert, a vast wasteland of sand and heat. A small lizard pokes its head up from You sands and asks You shortest route to Times Square..."
Từ "the" (viết tắt đầu tiên) bị thay bằng "You" (viết tắt thứ hai) — dấu hiệu rõ ràng của việc dữ liệu bị ghi đè.
Tại sao lỗi này tồn tại quá lâu?
Có một số lý do khiến lỗi này không bị phát hiện trong suốt hơn 40 năm:
- Hiếm khi gây hậu quả rõ ràng: Người chơi phải thả hơn tám đồ vật xuống sa mạc vô tận để kích hoạt lỗi
- Không có lý do để làm vậy: Sa mạc vô tận không dẫn đến đâu cả, không có manh mối nào ở đó
- Cơ chế vùi cát: Xác suất một phần ba đồ vật bị mất khiến việc tái hiện lỗi càng khó khăn
- Không có công cụ gỡ lỗi bộ nhớ: Infocom không có công cụ tương đương "Visible Zorker" để kiểm tra bộ nhớ
Plotkin nhận định rằng ngay cả đội ngũ kiểm thử của Infocom cũng khó có thể tình cờ gặp lỗi này, vì vùng sa mạc vô tận "không thể được kiểm thử kỹ lưỡng".
Bài học cho lập trình viên hiện đại
Câu chuyện này mang đến một số bài học vẫn còn nguyên giá trị:
- Lỗi bộ nhớ là nghiêm trọng, ngay cả khi chúng không gây ra hậu quả tức thì. Như Plotkin — một lập trình viên C — nhấn mạnh, việc ghi đè bộ nhớ ngoài ý muốn là "tội lỗi tồi tệ nhất"
- Giá trị mặc định cần được kiểm tra chặt chẽ ở cấp độ trình biên dịch. Đáng lẽ ZIL phải báo lỗi hoặc tạo mã khởi tạo đúng
- May mắn không phải là chiến lược: Lỗi này chỉ không gây hậu quả nghiêm trọng vì vị trí biến toàn cục tình cờ rơi vào vùng bộ nhớ trống
Plotkin cũng lưu ý rằng nếu DESERT-TABLE là biến toàn cục thứ ba thay vì thứ mười lăm, lỗi này sẽ ghi đè lên số sê-ri của trò chơi — và sẽ bị phát hiện ngay lập tức.
Hiện tượng này cũng gợi nhớ đến các lỗi trong phần mềm hiện đại, nơi những sai sót tưởng chừng vô hại có thể tồn tại hàng thập kỷ trong các hệ thống quan trọng, chỉ chờ đợi một điều kiện cụ thể để bộc lộ.
Bài viết liên quan

Công nghệ
Mô hình AI hàng đầu giỏi Vật lý đến đâu? Nghiên cứu mới chỉ ra các bài kiểm tra hiện hành đang đánh giá sai
16 tháng 9, 2026

Công nghệ
Nộp đơn xin việc lẽ ra nên khó hơn. Thật đấy
25 tháng 8, 2026

Công nghệ
River Raid trên Atari 2600: Khi một cart 4KB được tái tạo bằng JavaScript đến từng byte
05 tháng 10, 2026