Một chương trình được viết ra không bao giờ là hoàn hảo, luôn tồn tại những lỗ hổng mà các hacker có thể khai thác và lợi dụng, thậm chí phá hỏng chương trình hay đánh sập cả một hệ thống. Một chương trình có thể tồn tại những lỗi về logic mà ta khó nhận ra, đòi hỏi kỹ năng tư duy logic cao để phát hiện và sửa lỗi.
Chưa đề cập đến các lỗi logic, để hỗ trợ tìm kiếm và fix các lỗi lập trình hầu hết các IDE đều hỗ trợ khả năng gỡ rối (debug) chương trình bằng cách chạy từng dòng lệnh (step by step) và xem xét sự thay đổi trạng thái của chương trình như các biến, cách vận hành của mã.
Debug là gì?
Debug là quá trình tìm kiếm và fix bug (sửa lỗi) của chương trình. Quá trình debug thường mất nhiều thời gian hơn việc viết chương trình, vì những lỗi liên quan đến logic thường rất khó phát hiện. Visual Studio cung cấp nhiều công cụ trực quan để đơn giản hoá quá trình debug, tìm và sửa lỗi chương trình một cách dễ dàng hơn.
Visual Studio debugger?
Visual Studio và các phiên bản khác của IDE hỗ trợ rất tốt việc kiểm tra lỗi và được gọi là debugger, nhờ tính trực quan và ổn định nên rất được tin tưởng sử dụng, thậm chí các mã nguồn ứng dụng của C++ viết trên iOS hoặc Android đều có thể có phiên bản Win32 để kiểm thử nhanh trước, các IDE khác nhau có thể sẽ có sự khác biệt về thao tác đôi chút nhưng tư tưởng vẫn tương tự.
Một số khái niệm liên quan
Chạy chương trình
Một chương trình sẽ lần lượt duyệt qua các dòng code có trong các hàm. Trong đó, có những đoạn “thẳng”, có những đoạn rẽ nhánh (if/switch), có những đoạn vòng (for/while/…), có những đoạn đường nhỏ hơn (các function).
Để sửa lỗi chương trình, cần tìm ra được những đoạn rối của nó, tức là xác định xem đoạn code ở vị trí nào có khả năng phát sinh lỗi.
Breakpoints
Breakpoints là vị trí mà chương trình sẽ dừng lại để lập trình viên xem xét sự thay đổi của trạng thái chương trình, các biến qua từng dòng lệnh, từ đó phát hiện ra vị trí gây lỗi.
Breakpoints được đánh dấu bằng chấm tròn màu đỏ ở đầu dòng code. Để tạo ra một breakpoint, cách đơn giản nhất là click chuột vào đầu dòng code (như trong hình). Để huỷ breakpoints, chỉ cần click chuột vào breakpoint đó một lần nữa. Ngoài ra các bạn cũng có thể tạo/huỷ breakpoint bằng phím F9.
Watch Windows
Trong quá trình Debug, khi chương trình dừng lại ở một breakpoint, điều cần thiết của là kiểm tra sự thay đổi giá trị của các biến, hàm, … qua từng dòng code để nhìn ra sai sót trong thuật toán. Watch windows là tập hợp các công cụ giúp lập trình viên quan sát được giá trị hiện tại của biến. Các cửa sổ này có thể được tìm thấy trong menu Debug → Windows (chỉ xuất hiện khi đang trong quá trình debug).
Data Tip
Khi di chuyển con trỏ chuột đến tên biến ở bất kì vị trí nào trong phạm vi cặp dấu { } (scope) hiện tại, giá trị của biến sẽ được hiển thị trên màn hình. Khi đó có thể “ghim” biến đó lên màn hình để tiện quan sát, hoặc add vào cửa sổ Watch, copy giá trị, thay đổi giá trị của biến, …
Locals
Cửa sổ Locals sẽ hiển thị tất cả các biến có liên quan đến dòng code hiện tại một cách tự động. Các biến hiển thị ở đây sẽ được thay đổi qua từng dòng code. Ngoài ra, màu sắc của các biến giúp ta phân biệt được những biến nào vừa thay đổi giá trị.
Autos
Tương tự như Locals, cửa sổ Autos hiển thị các biến vừa được sử dụng trong các dòng code trước. Visual Studio sẽ tự động nhận diện biến nào không còn cần thiết và loại bỏ ra khỏi cửa sổ Autos.
Watch
Visual Studio không thể nhận diện được tất cả những gì lập trình viên cần. Trong một số trường hợp, cần theo dõi cụ thể một giá trị nào đó, chẳng hạn như phần tử thứ 10 trong một mảng số nguyên hay kí tự thứ 5 của chuỗi Stdio Tutorial, … Cần sử dụng đến cửa sổ Watch. Nó cho phép lập trình viên nhập vào tên biến, hàm, … cụ thể trong scope hiện tại. Giá trị của các biến, hàm sẽ được hiển thị bên cạnh tên biến.
Debug chương trình
Trước khi debug, cần tạo ra các breakpoints cần thiết để tìm và sửa lỗi chương trình. Để bắt đầu tiến hành debug một chương trình, vào menu Debug → Start Debugging hoặc nhấn phím F5 trên bàn phím. Visual Studio sẽ tiến hành Build chương trình. Sau khi Build xong và không có lỗi biên dịch (compile error), cửa sổ Debug sẽ xuất hiện. Nếu không có các lệnh dừng màn hình chờ nhập dữ liệu (như scanf, gets, …), chương trình sẽ dừng lại tại breakpoint đầu tiên.
Một thanh công cụ Debug sẽ xuất hiện. Trong đó, có các nút công cụ quan trọng như sau:
- Step Over: Chạy step by step, lướt qua hàm (chỉ nhận giá trị return của hàm).
- Step Into: Chạy step by step, đi vào nội dung của các hàm con.
- Step Out: “Nhảy” đến breakpoint kế tiếp. Nếu không còn breakpoint nào thì sẽ kết thúc debug. Ngoài ra nó còn có chức năng chạy lướt qua hàm con hiện tại.
Một số phím tắt hữu ích
- F5: Bắt đầu quá trình Debug.
- Shift + F5: Thoát Debug.
- Ctrl + F5: Chạy chương trình không dùng công cụ Debug.
- F9: Tạo/huỷ một breakpoint.
- F10: Step Over.
- F11: Step Into.
- Shift + F11: Step Out.