Bài tập - Gỡ lỗi với Visual Studio Code

Đã hoàn thành

Đã đế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.

  1. Trong Mã Visual Studio, hãy chọn Tệp>Mở Thư mục.

  2. Tạo thư mục mới có tên DotNetDebugging ở vị trí bạn chọn. Sau đó, Chọn Thư mục.

  3. 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.

  4. Trong cửa sổ thiết bị đầu cuối, hãy sao chép và dán lệnh sau đây:

    dotnet new console
    

    Lệ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.

  5. 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 run
    

    Cử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

  1. Mở Program.cs bằng cách chọn.

  2. 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.

    ảnh chụp màn hình lời nhắc cài đặt phần mở rộng C# của Visual Studio Code.

  3. 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ủa bạn.

    ảnh chụp màn hình nhắc nhở Mã Visual Studio thêm tài nguyên bắt buộc để xây dựng và gỡ lỗi dự án .NET của bạn.

  4. 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...
  1. Mở Program.cs bằng cách chọn.

  2. 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 đó.

  3. Lưu tệp bằng cách chọn Ctrl+S cho Windows và Linux. Chọn Cmd+S cho Mac.

  4. 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
    

    cửa sổ Đầu cuối với đầu ra chương trình được sửa đổi.

  5. 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ố

  1. 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.

    ảnh chụp màn hình nút Bắt đầu gỡ lỗi trong Mã Visual Studio.

    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.

  2. 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

  1. 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);.

    ảnh chụp màn hình vị trí điểm ngắt trong mã.

  2. 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.

    ảnh chụp màn hình nút Bước vào.

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.

ảnh chụp màn hình pa-nen Biến số.

  • Giá trị hiển thị cho tham số n là 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?
  1. Tiếp theo, chúng ta sẽ đi vào vòng lặp for vòng lặp bằng cách sử dụng bước khiển trình gỡ lỗi.

    ảnh chụp màn hình nút Bước qua.

  2. Tiếp tục tiến cho đến khi bạn nhấn vào dòng đầu tiên bên for vò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:

  1. 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).
  2. Nếu n nhỏ hơn 2, vòng lặp sẽ không bao giờ chạy. Câu return ở cuối hàm sẽ trả về 0 nếu n bằng 0 và 1 nếu n là 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.
  3. Trường hợp thú vị hơn là khi n lớ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, n1n2 là hai giá trị trước đó và sum là 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ành sum, chúng tôi sẽ cập nhật các giá n1n2 củ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.

  1. Thêm điểm ngắt thứ hai trên dòng 13.

    ảnh chụp màn hình cho thấy điểm ngắt thứ hai đang được đặt.

    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.

  2. 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]: 2
    

    Tấ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, sum củ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.

  3. 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]: 3
    

    Hã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 sum của chúng tôi bằng 2, và nó là.

  4. Đượ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]: 4
    

    Một lần nữa, mọi thứ đều đẹp. Giá trị thứ tư trong chuỗi dự kiến là 3.

  5. 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 i bằ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?

  6. 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.

  7. 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.

    ảnh chụp màn hình hiển thị các điểm ngắt được liệt kê trong ngăn Điểm ngắt.

    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!

  8. 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]: 3
    

    Khô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á sum và các tập hợp n2 bằng sum.

    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 i là 4, không phải 5.

    Chúng ta hãy nhìn vào dòng đầu tiên của vòng for vò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 i không còn nhỏ hơn n. Điều đó có nghĩa là mã vòng lặp sẽ không chạy cho trường hợp i bằng n. Có vẻ như những gì chúng tôi muốn chạy cho đến khi i <= 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;
    }
    
  9. Dừng phiên gỡ lỗi nếu bạn chưa gỡ lỗi.

  10. 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.

  11. 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.!

  12. 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.