Là in ra console / stdout là một chiến lược sửa lỗi tốt?


10

Hãy nói rằng chúng ta có một chức năng như thế này:

public void myStart()
{
    for (int i = 0; i<10; i++) myFunction(i); 
}


private int myFunction(int a)
{

    a = foo(a);
    a = bar(a);
    return a; 
}

private int foo(int a)
{
    //do something here

    //something gnarly here

    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Bây giờ vì lý do gì, mã của chúng tôi không hoạt động. Có lẽ đó là một lỗi, có lẽ nó trả về giá trị sai, có lẽ nó bị kẹt trong một vòng lặp vô hạn.

Điều đầu tiên mà bất kỳ lập trình viên năm đầu tiên, là in ra console / std out, (đã học cách in Hello World trước khi học cách sử dụng trình gỡ lỗi).

Ví dụ để gỡ lỗi mã này, họ có thể làm như sau:

private int myFunction(int a)
{
    print("before foo: a=" + a); 
    a = foo(a);
    print("before bar: a=" + a);
    a = bar(a);

    return a; 
}

private int foo(int a)
{
    //do something here
    print ("foo step1: a=" + a); 

    //something gnarly here
    print ("foo step2: a=" + a + " someOtherValue="+ someOtherValue + " array.length= " + someArray.length()); 
    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Bây giờ họ chạy mã, họ nhận được một giao diện điều khiển lớn được in ra, họ có thể đi qua để theo dõi nơi mà mọi thứ đang sai.

Tất nhiên, một cách khác là đặt các điểm dừng và chuyển qua mã tại mỗi điểm.

Một lợi thế lớn của việc in ra bàn điều khiển là nhà phát triển có thể thấy dòng chảy của các giá trị trong một lần mà không cần phải nhấp qua các bước, v.v.

Nhưng nhược điểm là, mã của bạn sau đó bị đánh đố với tất cả các câu lệnh in sau đó cần phải được loại bỏ.

(Có lẽ có thể yêu cầu trình gỡ lỗi chỉ in một số giá trị nhất định ra nhật ký?, Các điểm dừng sau đó có thể dễ dàng được thêm hoặc xóa mà không thực sự sửa đổi mã.)

Tôi vẫn sử dụng in giao diện điều khiển như một phương pháp gỡ lỗi chính, tôi tự hỏi mức độ phổ biến / hiệu quả của nó so với những thứ khác ngoài kia.


1
Bạn cần học cách sử dụng trình gỡ lỗi và sử dụng khung ghi nhật ký thích hợp. Nó sẽ làm cho bạn hạnh phúc hơn nhiều so với việc in ra bàn điều khiển (điều đó không luôn tồn tại).

7
Điều quan trọng là học cách sử dụng trình gỡ lỗi, tuy nhiên, có nhiều tình huống bạn có thể gặp phải trong đó gỡ lỗi printf là phương pháp gỡ lỗi duy nhất có sẵn.
tên của

Câu trả lời:


25

Báo cáo in và trình gỡ lỗi không loại trừ lẫn nhau. Chúng chỉ là các công cụ khác nhau có sẵn cho bạn để xác định vị trí / xác định lỗi. Có những người sẽ tuyên bố làm thế nào họ không bao giờ chạm vào trình gỡ lỗi và có những người không có một câu lệnh ghi / in duy nhất ở bất cứ đâu trong mã mà họ viết. Lời khuyên của tôi là bạn không muốn thuộc một trong những nhóm đó.

Thay vào đó hãy học cách sử dụng đăng nhập và học cách sử dụng trình gỡ lỗi. Với kinh nghiệm bạn sẽ (hầu như không phải suy nghĩ về nó) chọn công cụ phù hợp và hoàn thành công việc một cách chính xác và hiệu quả. Nếu không có kinh nghiệm, đôi khi bạn sẽ chọn cái này qua cái khác và có thể nó sẽ khiến bạn mất nhiều thời gian hơn để tìm hiểu các biến hoặc sàng lọc thông qua các tệp nhật ký, nhưng đó là tất cả quá trình học tập.

Vì vậy, để trả lời câu hỏi cụ thể của bạn. Đúng. Sử dụng các bản in để theo dõi thực hiện là chiến lược gỡ lỗi tốt và được sử dụng rộng rãi. Tuy nhiên...

Thay vì sử dụng báo cáo in, hãy xem xét sử dụng khung đăng nhập. Các khung ghi nhật ký có một khái niệm về các mức ghi nhật ký để bạn có thể thêm một loạt các thông điệp tường trình nhưng chọn một cấp cho mỗi cấp. Khi ứng dụng của bạn chạy trong điều kiện bình thường, cấp độ của bạn sẽ là LRI hoặc CẢNH BÁO để chỉ những nội dung quan trọng được báo cáo. Tuy nhiên, khi bạn đang theo dõi mã và cần hiểu luồng thực thi, bạn có thể thay đổi logger thành INFO hoặc DEBUG và bây giờ tất cả các câu lệnh "in" mà bạn đã có trong mã sẽ báo cáo thông tin bổ sung.

Sử dụng khung đăng nhập ...

  1. bạn sẽ không cần phải xóa tất cả các bản in sau khi hoàn thành.
  2. các bản in bạn để lại trong mã, có thể giúp bạn hoặc bất kỳ nhà phát triển nào gỡ lỗi cùng mã đó trong tương lai
  3. bạn sẽ có thể gỡ lỗi mã này trong trường mà không phải xây dựng lại mã mỗi lần chỉ để thêm các bản in mà bạn đã xóa.
  4. bạn sẽ có thể chuyển hướng thông điệp đăng nhập bất cứ nơi nào bạn muốn, không chỉ là bảng điều khiển. Họ có thể đi đến một tệp, syslog, DB, socket ... vv

Cập nhật: Tôi chỉ nhận thấy ở cuối bạn đang hỏi, "Có lẽ có thể bảo trình gỡ lỗi chỉ in một số giá trị nhất định ra nhật ký". Tùy thuộc vào trình gỡ lỗi bạn sử dụng. Nhiều trình gỡ lỗi hiện đại cho phép bạn xác định một hành động để gọi khi điểm dừng được nhấn. Trong một số (tôi đã thực hiện điều này trong VS và WinDbg), có thể chỉ định "in này và tiếp tục". Visual Studio gọi chúng là "tracepoints" thay vì "breakpoint"


+1 cho đoạn đầu tiên. Trình gỡ lỗi và nhật ký giải quyết hai vấn đề rất khác nhau.
Blrfl

1
Nhưng bạn không đồng ý rằng để lại các báo cáo nhật ký trong mã xấu đi?
dwjohnston

1
phụ thuộc vào loại báo cáo nhật ký bạn để lại tại chỗ. Tôi vừa tìm và xóa cái này: "logger.error (" CÁI GÌ ")". Mặt khác, tôi coi mã đăng nhập giống như phần còn lại của mã của tôi. Định dạng nó, làm cho nó trông đẹp và làm cho nó nhiều thông tin. Vâng, rắc một tuyên bố in mỗi dòng khác là một chút quá nhiều và có những lúc tôi đã phải dùng đến điều đó. Nhưng nhìn chung, có 10-20 câu lệnh nhật ký trong toàn bộ tệp (tệp / lớp có kích thước hợp lý và không khổng lồ) không tệ chút nào.
DXM

Tôi nhận thấy rằng việc để lại một số báo cáo nhật ký có thể hữu ích, ví dụ: nếu bạn có một hệ thống sản xuất, bạn có thể muốn ghi lại các biến quan trọng khác nhau khi chúng được sử dụng để nếu một số lỗi xuất hiện, bạn có thể thấy ngay những gì đã xảy ra trong sản phẩm của mình Môi trường. Tuy nhiên, đối với bối cảnh phát triển có vẻ lộn xộn. Ví dụ: bạn đang viết chức năng phân tích cú pháp của mình và bạn hoàn toàn không có quyền regex của mình - vì vậy bạn đưa vào một loạt các báo cáo nhật ký chỉ để kiểm tra những gì đang diễn ra, và cuối cùng sắp xếp nó. Tôi không nghĩ rằng nó tăng thêm giá trị trong tương lai để đưa họ vào.
dwjohnston

1
@Izkata: tất cả sẽ phụ thuộc vào chi tiết cụ thể của lỗi cụ thể của bạn và vào mức độ đăng nhập mã của bạn. Điểm tôi đang cố gắng vượt qua là luôn có giá trị của việc có các báo cáo ghi nhật ký và có chúng ở các cấp độ khác nhau: ERR -> WARN ... -> DEBUG. Nếu bạn cần nhiều hơn cho một cái gì đó rất cụ thể, chắc chắn bằng mọi cách hãy bắt đầu thêm các câu lệnh in. Nhưng câu trả lời của tôi cho ai đó sử dụng "in" làm câu lệnh ghi nhật ký, sẽ luôn được chuyển sang một khung và bắt đầu sử dụng nó.
DXM

3

Ghi nhật ký / in và gỡ lỗi là các kỹ thuật bổ sung có các điểm mạnh và điểm yếu khác nhau - tốt nhất nên sử dụng cả hai. Nhưng nhìn chung, tôi muốn nói rằng trình gỡ lỗi là công cụ ưu việt trong hầu hết các trường hợp và nên được sử dụng trước tiên, với việc ghi / in chỉ được sử dụng cho những thứ thực sự tốt hơn.

Ưu điểm của trình gỡ lỗi:

  • Bạn có thể kiểm tra toàn bộ trạng thái chương trình, không chỉ các giá trị bạn nghĩ sẽ in ra trước. Điều này có thể ồ ạt đẩy nhanh quá trình gỡ lỗi bằng cách giảm chu kỳ phản hồi cho ít hơn một giây. Đặc biệt quan trọng khi phải mất một thời gian để tiếp cận lỗi.
  • Bạn có thể thấy các cuộc gọi đến từ đâu và thậm chí kiểm tra các giá trị theo dõi ngăn xếp.
  • Bạn có thể (ở một mức độ nào đó phụ thuộc vào mã gỡ lỗi ngôn ngữ / platfrom) mà bạn không thể dễ dàng sửa đổi vì bạn chỉ có mã nhị phân hoặc mã byte được biên dịch.

Ưu điểm của Ghi / in:

  • Nó không yêu cầu xây dựng hoặc cấu hình gỡ lỗi đặc biệt. Nó luôn hoạt động.
  • Có thể được sử dụng để phân tích các lỗi khó tái tạo và hiếm khi xảy ra
  • Có thể được sử dụng để phân tích các lỗi phụ thuộc thời gian trong đó việc tạm dừng gây ra bởi trình gỡ lỗi có thể dễ dàng làm cho lỗi biến mất.
  • Cung cấp cho bạn thông tin vĩnh viễn mà bạn có thể phân tích lúc rảnh rỗi. Bạn có thể nhảy qua lại giữa đầu ra tại các điểm khác nhau trong luồng chương trình.

Một lợi thế khác của việc đăng nhập là khi bạn chỉ gặp phải vấn đề trong lần chuyển thứ nhất thông qua mã của mình và thực sự có thể sử dụng một số thông tin về cách bạn đến đó. Hầu hết các trình gỡ lỗi không có nút đảo ngược, nhưng ghi nhật ký những giá trị mà hàm cấp cao hơn được gọi sẽ hoạt động và thường ít nhất giúp bạn đến gần hơn với một trường hợp có thể lặp lại nhỏ.
Christopher Creutzig

1

In theo tiêu chuẩn đầu ra theo cách có thể là một chiến lược tốt để gỡ lỗi mã của bạn, ví dụ

  • tôi sử dụng rất nhiều câu lệnh in để xem những gì đang diễn ra ở các cấp mã khác nhau của mình đặc biệt là nếu tôi không hiểu đầy đủ về lỗi

  • hoặc có thể lỗi không có bất kỳ thông tin chi tiết nào có thể chỉ cho tôi phần chính xác của mã gây ra sự cố.

Tuy nhiên, bạn cần phải làm quen với các công cụ gỡ lỗi, có rất nhiều thứ ngoài kia tùy thuộc vào ngôn ngữ hoặc nền tảng bạn sử dụng.

Ngoài ra, một phương pháp khác là ghi nhật ký, tôi ghi nhật ký lỗi mọi lúc khi làm việc trên các ứng dụng Android, ngoài việc xử lý ngoại lệ, người ta có thể dễ dàng ghi lại dấu vết ngăn xếp hoặc thông báo lỗi của ngoại lệ được nêu ra.


3
bài này khá khó đọc (tường văn bản). Bạn có phiền chỉnh sửa ing nó thành một hình dạng tốt hơn?
gnat

Tôi làm cho nó một chút dễ đọc. Xin lỗi vì trước đây!
Plaix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.