Bài tập - Gỡ lỗi với Visual Studio Code
Đã đến lúc đưa kiến thức gỡ lỗi mới có được của bạn vào thực hành. Đó là ngày đầu tiên của bạn trong công việc và đã đến lúc phải nâng cao kỹ năng gỡ lỗi .NET của bạn bằng cách khắc phục lỗi trong sản phẩm hàng đầu của công ty, một máy tính Fibonacci.
Tạo dự án .NET mẫu để gỡ lỗi
Để thiết lập Mã Visual Studio để gỡ lỗi .NET, trước tiên chúng tôi cần một dự án .NET. Visual Studio Code bao gồm một thiết bị đầu cuối tích hợp, làm cho việc tạo ra một dự án mới dễ dàng.
Trong Mã Visual Studio, hãy chọn Tệp>Mở Thư mục.
Tạo thư mục mới có tên
DotNetDebuggingở vị trí bạn chọn. Sau đó, Chọn Thư mục.Mở thiết bị đầu cuối tích hợp từ Visual Studio Code bằng cách chọn View>terminal từ menu chính.
Trong cửa sổ thiết bị đầu cuối, hãy sao chép và dán lệnh sau đây:
dotnet new consoleLệnh này tạo ra một tệp Program.cs trong thư mục của bạn với một chương trình "Hello World" cơ bản đã được viết sẵn. Thao tác này cũng tạo tệp dự án C# có dotNetDebugging.csproj.
Trong cửa sổ thiết bị đầu cuối, hãy sao chép và dán lệnh sau đây để chạy chương trình "Hello World".
dotnet runCửa sổ thiết bị đầu cuối hiển thị "Hello World!" dưới dạng đầu ra.
Thiết lập Mã Visual Studio để gỡ lỗi .NET
Mở Program.cs bằng cách chọn.
Lần đầu tiên mở tệp C# trong Visual Studio Code, bạn sẽ nhận được lời nhắc cài đặt tiện ích mở rộng được đề xuất cho C#. Nếu bạn thấy lời nhắc này, hãy chọn cài đặt trong lời nhắc.
Visual Studio Code sẽ cài đặt phần mở C# và hiển thị lời nhắc khác để thêm tài sản bắt buộc để xây dựng và gỡ lỗi dự án của bạn. Chọn nút có của bạn.
Bạn có thể đóng mở rộng: Tab C# để tập trung vào mã mà chúng tôi sẽ gỡ lỗi.
Thêm lô-gic chương trình Fibonacci
Dự án hiện tại của chúng tôi viết một thông điệp "Hello World" vào bảng điều khiển, điều này không cung cấp cho chúng tôi nhiều để gỡ lỗi. Thay vào đó, bạn sẽ sử dụng một chương trình .NET ngắn để tính toán số N của trình tự Fibonacci.
Chuỗi Fibonacci là một bộ số bắt đầu bằng các số 0 và 1, với mỗi số khác sau đây là tổng của hai số trước đó. Trình tự này sẽ tiếp tục như minh họa ở đây:
0, 1, 1, 2, 3, 5, 8, 13, 21...
Mở Program.cs bằng cách chọn.
Thay thế nội dung Program.cs bằng mã sau:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { int n1 = 0; int n2 = 1; int sum; for (int i = 2; i < n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }Ghi
Mã này chứa lỗi, chúng tôi sẽ gỡ lỗi sau trong mô-đun này. Chúng tôi khuyên bạn không nên sử dụng ứng dụng này trong bất kỳ ứng dụng Fibonacci quan trọng nào cho đến khi chúng tôi khắc phục được lỗi đó.
Lưu tệp bằng cách chọn Ctrl+S cho Windows và Linux. Chọn Cmd+S cho Mac.
Chúng ta hãy xem mã cập nhật hoạt động như thế nào trước khi chúng tôi gỡ lỗi. Chạy chương trình bằng cách nhập lệnh sau đây trong thiết bị đầu cuối:
dotnet run
Kết quả, 3, được hiển thị trong đầu ra thiết bị đầu cuối. Khi bạn tham khảo biểu đồ trình tự Fibonacci này hiển thị vị trí trình tự dựa trên không cho mỗi giá trị trong dấu ngoặc đơn, bạn sẽ thấy kết quả phải là 5. Đã đến lúc làm quen với trình gỡ lỗi và khắc phục chương trình này.
0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
Phân tích sự cố
Bắt đầu chương trình bằng cách chọn tab Chạy và Gỡ lỗi ở bên trái, sau đó chọn nút Bắt đầu gỡ lỗi. Trước tiên, bạn có thể nút Chạy và Gỡ lỗi, rồi chọn tệp Program.cs bạn.
Bạn sẽ thấy chương trình kết thúc nhanh chóng. Điều đó là bình thường vì bạn chưa thêm bất kỳ điểm ngắt nào.
Nếu bảng điều khiển gỡ lỗi không xuất hiện, hãy chọn Ctrl+Shift+Y cho Windows và Linux hoặc Cmd+Shift+Y cho Mac. Bạn sẽ thấy một số dòng thông tin chẩn đoán, tiếp theo là các dòng sau đây ở cuối:
... Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 3 The program '[88820] DotNetDebugging.dll' has exited with code 0 (0x0).
Các dòng ở trên cùng cho bạn biết rằng cài đặt gỡ lỗi mặc định sẽ bật tùy chọn "Chỉ Mã của Tôi". Điều này có nghĩa là trình gỡ lỗi sẽ chỉ gỡ lỗi mã của bạn và sẽ không bước vào mã nguồn cho .NET trừ khi bạn tắt chế độ này. Tùy chọn này cho phép bạn tập trung vào việc gỡ lỗi mã của mình.
Ở cuối đầu ra bảng điều khiển gỡ lỗi, bạn sẽ thấy chương trình viết 3 vào bảng điều khiển và sau đó thoát với mã 0. Thông thường, mã thoát chương trình là 0 cho biết rằng chương trình đã chạy và thoát mà không gặp sự cố. Tuy nhiên, có một sự khác biệt giữa lỗi và trả về giá trị chính xác. Trong trường hợp này, chúng tôi đã yêu cầu chương trình tính toán giá trị thứ năm của trình tự Fibonacci:
0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
Giá trị thứ năm trong danh sách này là 5, nhưng chương trình của chúng tôi trả về 3. Hãy sử dụng trình gỡ lỗi để chẩn đoán và khắc phục lỗi này.
Sử dụng điểm ngắt và thực thi từng bước
Thêm điểm ngắt bằng cách bấm vào lề trái ở đường 1 trên trên
int result = Fibonacci(5);.
Bắt đầu gỡ lỗi một lần nữa. Chương trình bắt đầu thực hiện. Nó ngắt (tạm dừng thực hiện) trên dòng 1 vì điểm dừng bạn đặt. Sử dụng các điều khiển trình gỡ lỗi để bước vào hàm
Fibonacci()của bạn.
Kiểm tra trạng thái biến số
Bây giờ, hãy dành chút thời gian để kiểm tra các giá trị của các biến khác nhau bằng cách sử dụng biến số bảng.
- Giá trị hiển thị cho tham số
nlà gì? - Khi bắt đầu thực thi hàm, các giá trị cho các biến số cục bộ là
n1,n2, vàsum?
Tiếp theo, chúng ta sẽ đi vào vòng lặp
forvòng lặp bằng cách sử dụng bước khiển trình gỡ lỗi.
Tiếp tục tiến cho đến khi bạn nhấn vào dòng đầu tiên bên
forvòng lặp, trên dòng đọc:sum = n1 + n2;
Ghi
Bạn có thể đã nhận thấy rằng để di chuyển qua đường for(...) {} yêu cầu nhiều bước trong lệnh. Tình huống này xảy ra bởi vì có nhiều báo cáo trên dòng này. Khi bạn bước, bạn di chuyển sang câu lệnh tiếp theo trong mã của bạn. Thông thường, có một câu lệnh trên mỗi dòng. Nếu không phải như vậy, bạn cần thực hiện nhiều bước để chuyển sang dòng tiếp theo.
Hãy nghĩ về mã
Một phần quan trọng của việc gỡ lỗi là ngừng và đưa ra một số dự đoán sáng suốt về những gì bạn nghĩ các phần của mã (cả hàm và khối, chẳng hạn như vòng lặp) đang cố gắng thực hiện. Sẽ không sao nếu bạn không chắc chắn, đó là một phần của quy trình gỡ lỗi. Nhưng việc tích cực tham gia vào quá trình gỡ lỗi sẽ giúp bạn xác định vị trí lỗi nhanh hơn nhiều.
Trước khi chúng ta tìm kéo thêm, hãy nhớ rằng chuỗi Fibonacci là một chuỗi các số bắt đầu bằng các số 0 và 1, với mỗi số khác sau đây là tổng của hai số trước đó.
Điều đó có nghĩa là:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)
Hiểu rõ định nghĩa đó và nhìn vào vòng lặp for này, chúng ta có thể suy ra rằng:
- Vòng lặp được đếm từ 2 đến
n(số trình tự Fibonacci mà chúng tôi đang tìm kiếm). - Nếu
nnhỏ hơn 2, vòng lặp sẽ không bao giờ chạy. Câureturnở cuối hàm sẽ trả về 0 nếunbằng 0 và 1 nếunlà 1 hoặc 2. Đây là các giá trị bằng không, thứ nhất và thứ hai trong chuỗi Fibonacci, theo định nghĩa. - Trường hợp thú vị hơn là khi
nlớn hơn 2. Trong những trường hợp đó, giá trị hiện tại được xác định là tổng của hai giá trị trước đó. Vì vậy, đối với vòng lặp này,n1vàn2là hai giá trị trước đó vàsumlà giá trị cho lần lặp hiện tại. Do đó, mỗi lần chúng tôi tìm ra tổng của hai giá trị trước đó và đặt nó thànhsum, chúng tôi sẽ cập nhật các gián1vàn2của mình.
Được rồi, chúng ta không cần phải ghi đè chuyện đó. Chúng ta có thể dựa vào trình gỡ lỗi của mình một chút. Tuy nhiên, bạn nên suy nghĩ về mã để xem mã có thực hiện những gì chúng tôi mong đợi và được thông báo thêm khi mã đó không hoạt động hay không.
Xác định vị trí lỗi với điểm ngắt
Bước qua mã của bạn có thể hữu ích nhưng tẻ nhạt, đặc biệt là khi bạn đang làm việc với các vòng lặp hoặc mã khác được gọi nhiều lần. Thay vì đi qua vòng lặp nhiều lần, chúng ta có thể đặt một điểm ngắt mới trên dòng đầu tiên của vòng lặp.
Khi chúng ta làm điều này, điều quan trọng là phải chiến lược về nơi chúng ta đặt điểm ngắt của mình. Chúng tôi đặc biệt quan tâm đến giá trị của sum, vì nó đại diện cho giá trị Fibonacci tối đa hiện tại. Bởi vì điều đó, chúng ta hãy đặt điểm ngắt của chúng tôi trên đường kẻ sau khisum được thiết lập.
Thêm điểm ngắt thứ hai trên dòng 13.
Ghi
Nếu bạn nhận thấy rằng bạn tiếp tục chạy mã của bạn và sau đó bước một hoặc hai dòng, bạn có thể dễ dàng cập nhật điểm ngắt của bạn để đường hiệu quả hơn.
Bây giờ chúng ta đã có một điểm ngắt tốt được đặt trong vòng lặp, hãy sử dụng điều khiển trình gỡ lỗi Tiếp tục để chuyển tiếp cho đến khi điểm ngắt được nhấn. Nhìn vào các biến số cục bộ của chúng tôi, chúng tôi thấy các dòng sau:
n [int]: 5 n1 [int]: 0 n2 [int]: 1 sum [int]: 1 i [int]: 2Tất cả các dòng này có vẻ chính xác. Lần đầu tiên đi qua vòng lặp,
sumcủa hai giá trị trước đó là 1. Thay vì di chuyển qua từng dòng, chúng ta có thể tận dụng các điểm ngắt của mình để chuyển sang lần tiếp theo thông qua vòng lặp.Chọn Tiếp tục tiếp tục dòng chương trình cho đến khi điểm ngắt tiếp theo bị nhấn, điểm này sẽ nằm trên đường đi tiếp theo qua vòng lặp.
Ghi
Đừng quá lo lắng về việc bỏ qua lỗi này khi bạn sử dụng Tiếp tục. Bạn nên nghĩ rằng bạn thường sẽ gỡ lỗi thông qua mã nhiều lần để tìm vấn đề. Nó thường nhanh hơn để chạy qua nó một vài lần như trái ngược với quá thận trọng khi bạn bước qua.
Lần này, chúng ta sẽ thấy các giá trị sau:
n [int]: 5 n1 [int]: 1 n2 [int]: 1 sum [int]: 2 i [int]: 3Hãy nghĩ về nó. Các giá trị này có còn ý nghĩa không? Có vẻ như họ làm vậy. Đối với số Fibonacci thứ ba, chúng tôi mong đợi sẽ thấy số lượng
sumcủa chúng tôi bằng 2, và nó là.Được rồi, chúng ta hãy chọn tiếp Tiếp tục lặp lại.
n [int]: 5 n1 [int]: 1 n2 [int]: 2 sum [int]: 3 i [int]: 4Một lần nữa, mọi thứ đều đẹp. Giá trị thứ tư trong chuỗi dự kiến là 3.
Tại thời điểm này, bạn có thể bắt đầu tự hỏi mã có đúng không và bạn tưởng tượng ra lỗi đó! Chúng ta hãy giữ nó trong lần cuối thông qua vòng lặp. Chọn Tiếp tục một lần nữa.
Chờ chút. Chương trình kết thúc chạy và in ra 3! Điều đó không đúng.
Được rồi, đừng lo. Chúng ta đã không thất bại, chúng ta đã học được. Bây giờ chúng ta biết rằng mã chạy qua vòng lặp một cách chính xác cho đến khi
ibằng 4, nhưng sau đó nó thoát ra trước khi tính toán giá trị cuối cùng. Tôi bắt đầu nhận được một số ý tưởng về vị trí của lỗi. Phải không?Chúng ta hãy đặt thêm một điểm ngắt trên dòng 17 với nội dung:
return n == 0 ? n1 : n2;Điểm ngắt này sẽ cho phép chúng tôi kiểm tra trạng thái chương trình trước khi chức năng thoát. Chúng tôi đã học được tất cả những gì chúng ta có thể mong đợi từ các điểm ngắt trước đó trên dòng 1 và 13, vì vậy chúng ta có thể xóa chúng.
Loại bỏ các điểm ngắt trước đó trên dòng 1 và 13. Bạn có thể thực hiện điều đó bằng cách bấm vào chúng ở lề bên cạnh số dòng hoặc bằng cách xóa hộp kiểm điểm chấm cho các dòng 1 và 13 trong ngăn Điểm chấm ở phía dưới bên trái.
Bây giờ chúng ta đã hiểu rõ hơn về những gì đang diễn ra tốt hơn và đã thiết lập một điểm ngắt được thiết kế để bắt kịp chương trình của chúng tôi trong hành động hành vi sai lầm, chúng ta sẽ có thể bắt được lỗi này!
Khởi động trình gỡ lỗi một lần cuối cùng.
n [int]: 5 n1 [int]: 2 n2 [int]: 3 sum [int]: 3Không đúng. Chúng tôi đặc biệt yêu cầu Fibonacci(5), và chúng tôi đã nhận Fibonacci(4). Hàm này trả về
n2, và mỗi lần lặp vòng lặp tính toán giásumvà các tập hợpn2bằngsum.Dựa trên thông tin này và lần chạy gỡ lỗi trước đó của chúng tôi, chúng ta có thể thấy rằng vòng lặp đã thoát khi
ilà 4, không phải 5.Chúng ta hãy nhìn vào dòng đầu tiên của vòng
forvòng gần hơn một chút.for (int i = 2; i < n; i++)Được rồi, chờ một chút! Điều đó có nghĩa là nó sẽ thoát ra ngay khi phần trên cùng của vòng lặp cho thấy rằng
ikhông còn nhỏ hơnn. Điều đó có nghĩa là mã vòng lặp sẽ không chạy cho trường hợpibằngn. Có vẻ như những gì chúng tôi muốn chạy cho đến khii <= n, thay vào đó:for (int i = 2; i <= n; i++)Vì vậy, với thay đổi đó, chương trình cập nhật của bạn sẽ trông giống như ví dụ sau:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { int n1 = 0; int n2 = 1; int sum; for (int i = 2; i <= n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }Dừng phiên gỡ lỗi nếu bạn chưa gỡ lỗi.
Tiếp theo, hãy thực hiện thay đổi trước đó đối với dòng 10 và để điểm ngắt của chúng tôi ở dòng 17.
Khởi động lại trình gỡ lỗi. Lần này, khi chúng ta nhấn điểm ngắt trên dòng 17, chúng ta sẽ thấy các giá trị sau đây:
n [int]: 5 n1 [int]: 3 n2 [int]: 5 sum [int]: 5Ê! Dường như chúng tôi đã nhận được nó! Tuyệt vời, bạn đã lưu ngày cho Fibonacci, Inc.!
Chọn tiếp để đảm bảo chương trình trả về giá trị chính xác.
5 The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).Và điều đó sẽ trả về đầu ra chính xác.
Bạn đã làm điều đó! Bạn đã gỡ lỗi một số mã mà bạn không viết bằng cách sử dụng trình gỡ lỗi .NET trong Mã Visual Studio.
Trong đơn vị tiếp theo, bạn sẽ tìm hiểu làm thế nào để làm cho mã bạn viết dễ dàng hơn để gỡ lỗi bằng cách sử dụng các tính năng ghi nhật ký và theo dõi được xây dựng vào .NET.