Vấn Đề Nhỏ Với Hàm ExtractAssociatedIcon
Hôm nay, sau khi nâng cấp ứng dụng Card Duel, nhóm phát triển không tiến hành kiểm thử trên hệ điều hành Vista. Đến tối, đã có người báo lỗi không thể chạy được trên Vista.
Bạn netbug đã truy cập mã nguồn từ nhà riêng và phát hiện ra lỗi nằm bên trong quá trình gọi API ExtractAssociatedIcon. Dòng mã cụ thể là:
|
|
Tuy nhiên, tài liệu MSDN không cung cấp thông tin rõ ràng nào về vấn đề này. Trước đó, ứng dụng vẫn hoạt động bình thường trên Vista. Theo bạn netbug, điểm khác biệt duy nhất là trước đây dùng trình biên dịch VC6, còn hiện tại chuyển sang VC9.
Thông thường, việc thay đổi trình biên dịch không nên gây ra lỗi với các API hệ thống. Nhưng tại sao lần này lại khác? Tôi đã tìm kiếm tài liệu chính thức của Microsoft về hàm ExtractAssociatedIcon trên Google với truy vấn: ExtractAssociatedIcon site:msdn.microsoft.com
.
Nguyên mẫu hàm được mô tả như sau:
|
|
Điều đáng chú ý là tham số thứ hai có kiểu LPTSTR (con trỏ chuỗi có thể sửa đổi) thay vì LPCTSTR (chuỗi chỉ đọc). Tôi đã gợi ý bạn netbug sửa thành:
|
|
Kỳ diệu thay, ứng dụng lại chạy ổn định! Hóa ra vấn đề nằm ở cách trình biên dịch mới VC9 quản lý bộ nhớ. Có thể VC9 đã lưu chuỗi hằng “loader.exe” vào phân đoạn chỉ đọc, trong khi hàm ExtractAssociatedIcon trên Vista lại cố gắng ghi đè lên vùng nhớ này. (Cũng có thể do sự khác biệt trong cơ chế PE Loader của Vista).
Kinh nghiệm giúp tôi nhận ra vấn đề trong vòng 30 giây là do từng gặp lỗi tương tự liên quan đến sự khác biệt giữa các phiên bản Windows. Ví dụ điển hình là hàm GetGlyphOutline:
|
|
Dù tài liệu ghi rõ tham số cuối cùng là const MAT2*, nhưng nếu truyền vào một biến static const MAT2 trên Windows 98, chương trình sẽ crash hoàn toàn! (Đây là lỗi tôi từng gặp khi phát triển game Đại Hành Động từ hơn chục năm trước).
Mẹo nhỏ về SSH Tunnel:
Khi netbug muốn truy cập SVN nội bộ từ nhà riêng mà không có VPN, tôi đã dùng tính năng tunnel của SSH. Cụ thể:
- Tôi SSH đến máy chủ công cộng và tạo remote tunnel:
1
ssh -R 3690:svn-server:3690 user@public-server
- Bạn netbug sau đó tạo local tunnel từ máy nhà:
1
ssh -L 3690:localhost:3690 user@public-server
Kết quả: Bạn ấy có thể truy cập SVN nội bộ như đang ngồi trong văn phòng!
Cập nhật ngày 14/02/2009:
netbug phát hiện tài liệu MSDN thực ra đã cảnh báo: Tham số thứ hai của ExtractAssociatedIcon có thể bị ghi đè. Tuy nhiên, tài liệu lại chỉ ghi chú là [in] thay vì [in,out]. Điều đáng lo là không có tham số chỉ định độ dài tối đa, dẫn đến nguy cơ tràn bộ đệm nếu chuỗi trả về quá dài. Nên khai báo an toàn như sau:
|
|
Vấn đề tưởng nhỏ nhưng lại là lời nhắc nhở quan trọng về sự khác biệt tinh tế giữa các nền tảng Windows và tầm quan trọng của việc kiểm thử đa hệ điều hành.