Sử dụng WinDbg để debug crash

Chắc các bạn cũng hiểu được sự nguy hiểm của việc phần mềm bị crash phải không? Tôi có một tình huống sau: Khách hàng đang sử dụng sản phẩm của bạn một cách bình thường,vui vè như bao ngày và đột nhiên, bang!

Image result for your program has stopped working

Vâng! App của bạn toi rồi đó. Khách hàng có khó chịu không? Tất nhiên rồi, chẳng ai muốn bị gián đoạn cả, khách hàng lại điên lên, tạo ticket critical bug cho team bạn.Team bạn xin (support package – những file log/database/config… của sản phẩm trong máy khách hàng). Team bạn bắt đầu đọc log, luôn là như thế. OK, dòng log cuối cùng kết thúc ở dòng 333, trong file badassfunction.cpp. Ngon, dzô đây đọc coi bị sao:

Đậu phụ, chẳng có gì hết, chỉ là một đoạn log vô dụng! Tức là chương trình của bạn đã bị crash đâu đó ở tận lúc sau của đoạn code này rồi. Nhưng đâu đó là đâu đó? Bạn có thể tiếp tục đọc code, tiếp tục suy luận. Nhưng, chắc gì đã ra?

Lúc này chính là lúc bạn cần tới file crash dump + một phần mềm có thể hỗ trợ debug được file đó: Windbg

Mở bài hơi dài dòng một chút nhưng tôi nghĩ nó là cần thiết để các bạn hiểu tại sao lại cần tới Windbg. Tôi sẽ hướng dẫn các bạn debug với Windbg từ A-Z, bắt đầu nào!

PHẦM MỀM GIẢ LẬP

Trước hết chúng ta có ở đây một đoạn code ngắn, mà nó chắc chắn sẽ bị crash, mục đích chủ yếu là để giả lập nên nó khá đơn giản như sau

Ở đây, tôi sử dụng Visual Studio để build, khi build ra bạn sẽ được một file exe và một file pdb (dùng để debug). Tôi chọn mode debug để dễ trace và dễ ví dụ, chứ trên thực tế, sản phẩm mình gửi tới khách hàng phải sử dụng mode Release hoặc là Release With Debug Info. Lúc này thông tin để debug sẽ có ít hơn và vì thế khó trace hơn. Tôi sẽ nói rõ về những mode này ở bài sau.

Khi build xong chúng ta có 2 file như này

CẤU HÌNH ĐỂ WINDOWS TẠO RA FILE CRASH DUM

Bạn nào chưa biết file crash dump có thể xem thêm ở đây: Memory Dump là gì?

Về việc cấu hình để Windows tạo ra file crash dump thì có một số cách, ở đây tôi chọn config bằng file registry. Mở bất cứ một phần mềm editor nào đó, tạo một file text bình thường, lưu lại với tên: crashdump.reg. Nội dung như dưới đây

Các bạn nhớ tháy ConsoleApplication1.exe thành tên chương trình của bạn

DumpFolder: Nơi file crash dump sẽ được tạo ra. Những option khác các bạn có thể tham khảo ở trang này của Microsoft: Collecting User-Mode Dumps

DEBUG VỚI WINDBG

Ok thế là mình đã có đủ tất cả những thứ cần thiết để debug. Giờ thì chạy chương trình lên cho nó crash, và nó sẽ ra được một file như này: ConsoleApplication1.exe.7368.dmp

Mở Windbg lên -> File -> Open Crash Dump -> mở file crash dump ở trên ra

Load file exe lên bằng cách gõ vô ô lệnh ở dưới cùng

Reload

Load file symbol lên (pdb)

Reload

Sau mỗi lần reload các bạn sẽ thấy chữ *BUSY* tức là chương trình đang xử lý, nhớ kiên nhẫn và đợi một chút. Sau khi đã load hết tất cả mọi thứ mình cần, giờ là đến lúc debug thôi, gõ câu lệnh sau để debug

Sau khi gõ câu lệnh trên, màn hình sẽ hiện ra như này

Các bạn lăn lên trên một xúi, tèn tén ten:

Tham khảo thêm một số câu lệnh của Windbg: Common WinDbg Commands

Khá dễ phải không nào? Nồ nố no! Công đoạn để chuẩn bị debug là khá dễ, tuy nhiên việc debug thực sự không dễ dàng như ở trên. Trên đây chỉ là một ví dụ siêu nhỏ + mình build bằng mode debug, thì việc này quá dễ dàng. Tuy nhiên, với mode Release + một chương trình vài triệu dòng code, thì việc này thực sự là một công việc phức tạp và đòi hỏi nhiều công sức

KẾT LUẬN

Kĩ năng debug là một kĩ năng rất quan trọng của mỗi lập trình viên. Việc debug luôn luôn là một trong những công đoạn tốn nhiều thời gian cũng như công sức nhất. Trong công việc, tôi đã gặp rất nhiều bạn không muốn sử dụng tool (có thể do bảo thủ, hoặc do lười học cách sử dụng/setup) chỉ debug bằng mắt + ghi ra log. Ở đây, tôi không muốn nói cách làm nào đúng cách làm nào sai, sự lựa chọn là ở mỗi bạn. Tuy nhiên, nếu chúng ta biết kết hợp tư duy logic + phần mềm hỗ trợ thì mọi việc sẽ trở nên dễ dàng hơn. Make life easier!