Trình gỡ lỗi là gì và làm thế nào nó có thể giúp tôi chẩn đoán sự cố?
Đây là một câu hỏi có mục đích chung để hỗ trợ các lập trình viên mới gặp sự cố với chương trình, nhưng không biết cách sử dụng trình gỡ lỗi để chẩn đoán nguyên nhân của sự cố.
Câu hỏi này bao gồm ba lớp câu hỏi cụ thể hơn:
- Khi tôi chạy chương trình của mình, nó không tạo ra đầu ra mà tôi mong đợi cho đầu vào mà tôi đã đưa.
- Khi tôi chạy chương trình của mình, nó bị treo và cho tôi một dấu vết ngăn xếp. Tôi đã kiểm tra dấu vết ngăn xếp , nhưng tôi vẫn không biết nguyên nhân của sự cố vì dấu vết ngăn xếp không cung cấp cho tôi đủ thông tin.
- Khi tôi chạy chương trình của mình, nó bị treo do lỗi phân đoạn (SEGV).
Trả lời
Trình gỡ lỗi là một chương trình có thể kiểm tra trạng thái chương trình của bạn trong khi chương trình của bạn đang chạy. Các phương tiện kỹ thuật mà nó sử dụng để thực hiện việc này không quan trọng đối với việc hiểu những điều cơ bản về cách sử dụng trình gỡ lỗi. Bạn có thể sử dụng trình gỡ lỗi để tạm dừng việc thực thi chương trình của mình khi nó đến một vị trí cụ thể trong mã của bạn, sau đó kiểm tra các giá trị của các biến trong chương trình. Bạn có thể sử dụng trình gỡ lỗi để chạy chương trình của mình rất chậm, mỗi lần một dòng mã (được gọi là bước đơn ), trong khi bạn kiểm tra các giá trị của các biến của nó.
Sử dụng trình gỡ lỗi là một kỹ năng cơ bản được mong đợi
Trình gỡ lỗi là một công cụ rất mạnh để giúp chẩn đoán sự cố với chương trình. Và trình gỡ lỗi có sẵn cho tất cả các ngôn ngữ lập trình thực tế. Do đó, có thể sử dụng trình gỡ lỗi được coi là một kỹ năng cơ bản của bất kỳ lập trình viên chuyên nghiệp hoặc đam mê nào. Và việc tự mình sử dụng một trình gỡ lỗi được coi là công việc cơ bản bạn nên tự làm trước khi nhờ người khác giúp đỡ. Vì trang web này dành cho các lập trình viên chuyên nghiệp và đam mê, không phải là trang web trợ giúp hoặc cố vấn, nếu bạn có câu hỏi về sự cố với một chương trình cụ thể nhưng chưa sử dụng trình gỡ lỗi, câu hỏi của bạn rất có thể bị đóng và bị loại bỏ. Nếu bạn vẫn tiếp tục với những câu hỏi như vậy, cuối cùng bạn sẽ bị chặn đăng thêm.
Trình gỡ lỗi có thể giúp bạn như thế nào
Bằng cách sử dụng trình gỡ lỗi, bạn có thể phát hiện ra liệu một biến có giá trị sai hay không và giá trị của nó bị thay đổi thành giá trị sai ở đâu trong chương trình của bạn.
Sử dụng một bước duy nhất, bạn cũng có thể khám phá liệu luồng điều khiển có như bạn mong đợi hay không. Ví dụ, liệu một if
nhánh có được thực thi khi bạn mong đợi hay không.
Lưu ý chung về việc sử dụng trình gỡ lỗi
Các chi tiết cụ thể của việc sử dụng trình gỡ lỗi phụ thuộc vào trình gỡ lỗi và ở mức độ thấp hơn, ngôn ngữ lập trình bạn đang sử dụng.
Bạn có thể đính kèm trình gỡ lỗi vào một quy trình đã chạy chương trình của bạn. Bạn có thể làm nếu chương trình của bạn bị kẹt.
Trong thực tế, việc chạy chương trình của bạn dưới sự điều khiển của trình gỡ lỗi thường dễ dàng hơn ngay từ đầu.
Bạn chỉ ra nơi chương trình của bạn sẽ dừng thực thi bằng cách chỉ ra tệp mã nguồn và số dòng của dòng mà tại đó việc thực thi sẽ dừng hoặc bằng cách chỉ ra tên của phương thức / chức năng mà tại đó chương trình sẽ dừng lại (nếu bạn muốn dừng lại ngay sau khi thực thi vào phương thức). Phương tiện kỹ thuật mà trình gỡ lỗi sử dụng để khiến chương trình của bạn dừng được gọi là điểm ngắt và quá trình này được gọi là thiết lập điểm ngắt .
Hầu hết các trình gỡ lỗi hiện đại là một phần của IDE và cung cấp cho bạn GUI thuận tiện để kiểm tra mã nguồn và các biến của chương trình của bạn, với giao diện trỏ và nhấp để thiết lập các điểm ngắt, chạy chương trình của bạn và chỉ một bước.
Việc sử dụng trình gỡ lỗi có thể rất khó trừ khi các tệp thực thi chương trình hoặc tệp bytecode của bạn bao gồm thông tin ký hiệu gỡ lỗi và các tham chiếu chéo đến mã nguồn của bạn. Bạn có thể phải biên dịch (hoặc biên dịch lại) chương trình của mình hơi khác một chút để đảm bảo rằng thông tin có sẵn. Nếu trình biên dịch thực hiện tối ưu hóa rộng rãi, các tham chiếu chéo đó có thể trở nên khó hiểu. Do đó, bạn có thể phải biên dịch lại chương trình của mình khi tắt tối ưu hóa .
Tôi muốn nói thêm rằng trình gỡ lỗi không phải lúc nào cũng là giải pháp hoàn hảo và không phải lúc nào cũng là giải pháp phù hợp để gỡ lỗi. Dưới đây là một số trường hợp trình gỡ lỗi có thể không hoạt động với bạn:
- Phần chương trình bị lỗi của bạn thực sự lớn (có lẽ là mô-đun hóa kém?) Và bạn không chắc chắn chính xác nơi bắt đầu bước qua mã. Bước qua tất cả các bước có thể quá tốn thời gian.
- Chương trình của bạn sử dụng rất nhiều lệnh gọi lại và các phương pháp điều khiển luồng phi tuyến tính khác, điều này khiến trình gỡ lỗi bị nhầm lẫn khi bạn bước qua nó.
- Chương trình của bạn là đa luồng. Hoặc thậm chí tệ hơn, vấn đề của bạn là do tình trạng chủng tộc.
- Mã có lỗi sẽ chạy nhiều lần trước khi lỗi. Điều này có thể đặc biệt có vấn đề trong các vòng lặp chính, hoặc tệ hơn nữa, trong các động cơ vật lý, trong đó vấn đề có thể là số. Ngay cả việc thiết lập một điểm ngắt, trong trường hợp này, đơn giản là bạn sẽ đánh nó nhiều lần mà lỗi không xuất hiện.
- Chương trình của bạn phải chạy trong thời gian thực. Đây là một vấn đề lớn đối với các chương trình kết nối với mạng. Nếu bạn thiết lập một điểm ngắt trong mã mạng của mình, đầu kia sẽ không đợi bạn bước qua, nó chỉ đơn giản là hết thời gian. Các chương trình dựa vào đồng hồ hệ thống, ví dụ như trò chơi với khung hình, cũng không tốt hơn nhiều.
- Chương trình của bạn thực hiện một số dạng hành động phá hoại, chẳng hạn như ghi vào tệp hoặc gửi e-mail và bạn muốn giới hạn số lần bạn cần chạy qua nó.
- Bạn có thể nói rằng lỗi của bạn là do các giá trị đến hàm X không chính xác, nhưng bạn không biết các giá trị này đến từ đâu. Việc phải chạy đi chạy lại chương trình, đặt các điểm ngắt ngày càng xa, có thể là một rắc rối lớn. Đặc biệt nếu hàm X được gọi từ nhiều nơi trong suốt chương trình.
Trong tất cả các trường hợp này, việc chương trình của bạn dừng đột ngột có thể khiến kết quả cuối cùng khác nhau hoặc thực hiện theo cách thủ công để tìm kiếm một dòng mà lỗi gây ra quá phức tạp. Điều này có thể xảy ra như nhau cho dù lỗi của bạn là hành vi không chính xác hoặc sự cố. Ví dụ: nếu hỏng bộ nhớ gây ra sự cố, vào thời điểm sự cố xảy ra, nó quá xa so với nơi xảy ra lỗi bộ nhớ đầu tiên và không còn thông tin hữu ích nào.
Vì vậy, các lựa chọn thay thế là gì?
Đơn giản nhất chỉ đơn giản là ghi nhật ký và xác nhận. Thêm nhật ký vào chương trình của bạn ở nhiều điểm khác nhau và so sánh những gì bạn nhận được với những gì bạn đang mong đợi. Ví dụ, hãy xem liệu chức năng mà bạn cho rằng có lỗi có được gọi ngay từ đầu hay không. Xem liệu các biến ở đầu một phương pháp có đúng như bạn nghĩ không. Không giống như các điểm ngắt, không sao cả khi có nhiều dòng nhật ký trong đó không có gì đặc biệt xảy ra. Bạn có thể chỉ cần tìm kiếm thông qua nhật ký sau đó. Khi bạn đạt đến một dòng nhật ký khác với những gì bạn đang mong đợi, hãy thêm nhiều dòng khác vào cùng một khu vực. Thu hẹp nó ngày càng xa, cho đến khi nó đủ nhỏ để có thể ghi lại mọi dòng trong khu vực bị nghe trộm.
Các xác nhận có thể được sử dụng để bẫy các giá trị không chính xác khi chúng xảy ra, thay vì một khi chúng có tác dụng hiển thị cho người dùng cuối. Bạn bắt được một giá trị không chính xác càng nhanh, bạn càng gần với dòng tạo ra nó.
Refactor và kiểm tra đơn vị. Nếu chương trình của bạn quá lớn, bạn nên kiểm tra một lớp hoặc một hàm tại một thời điểm. Cung cấp cho nó đầu vào, và xem xét đầu ra, và xem cái nào không như bạn mong đợi. Khả năng thu hẹp một lỗi từ toàn bộ chương trình thành một chức năng duy nhất có thể tạo ra sự khác biệt lớn về thời gian gỡ lỗi.
Trong trường hợp bộ nhớ bị rò rỉ hoặc bộ nhớ ngừng hoạt động, hãy sử dụng các công cụ thích hợp có khả năng phân tích và phát hiện chúng trong thời gian chạy. Bước đầu tiên có thể phát hiện ra nơi tham nhũng thực sự xảy ra. Sau đó, bạn có thể sử dụng nhật ký để quay lại nơi các giá trị không chính xác được đưa vào.
Hãy nhớ rằng gỡ lỗi là một quá trình đi ngược lại. Bạn có kết quả cuối cùng - một lỗi - và tìm nguyên nhân, dẫn đến nó. Đó là làm việc theo cách của bạn lùi lại và, thật không may, trình gỡ lỗi chỉ bước về phía trước. Đây là nơi mà việc ghi nhật ký tốt và phân tích sau khám nghiệm có thể cho bạn kết quả tốt hơn nhiều.