Đó là một tuần lớn. Tôi hiện đang xem xét bản thảo cuối cùng của cuốn sách sửa lỗi sắp tới của mình . Đây luôn là một khoảnh khắc tỉnh táo và thú vị. Một khoảnh khắc mà tất cả những tháng làm việc đột nhiên trở thành "thật".
Tôi cũng đã quay 9 video cho youtube, nâng tổng số video trong khóa học lên 29 (và nhiều video nữa đang được triển khai). Tôi đang bắt đầu thêm hai khóa học miễn phí, một khóa học dành cho những người mới bắt đầu .
Một phần khác là về lập trình Java hiện đại mà tôi sẽ sớm ra mắt. Cả hai sẽ miễn phí trên (bắt buộc phải "thích, đăng ký và chia sẻ").
Trong bài viết tuần này, chúng ta sẽ nói về breakpoint. Đó là một thời gian dài vì những gì chúng ta muốn nói khi chúng ta nói điểm ngắt thực sự chỉ là "điểm ngắt dòng". Có rất nhiều hơn nữa cho họ như bạn có thể thấy dưới đây.
Chào mừng bạn quay trở lại với phần thứ tư của quá trình gỡ lỗi ở Quy mô nơi chúng tôi đá đít và lấy tên. Tên biến!
Trong phần này, chúng tôi thảo luận về các điểm dừng là đơn vị công việc cơ bản nhất khi gỡ lỗi. Nhưng có rất nhiều thứ đối với họ hơn là chỉ phá vỡ.
Chúng tôi đã nói về điểm dừng cơ bản nhất trong phần đầu tiên của chúng tôi. Lần này, chúng ta sẽ tìm hiểu sâu hơn một chút và vào một số sắc thái ít được biết đến.
Chúng tôi bắt đầu với các điểm dừng có điều kiện. Điểm dừng có điều kiện cho phép chúng tôi xác định điều kiện cho lần truy cập điểm dừng. Điều này ngăn luồng dừng liên tục trên một điểm dừng. Tôi đã thảo luận điều này trước đây với đối tượng đánh dấu myThread mà chúng ta đã tạo trong video trước.
Trong trường hợp này, chúng tôi chỉ dừng lại nếu nó khác với luồng hiện tại. Điều đó có nghĩa là điểm dừng này sẽ chỉ đạt nếu một chuỗi khác gọi nó. Đó là một cách tuyệt vời để phát hiện các vấn đề liên quan đến luồng như bế tắc hoặc cuộc đua. Tính năng này đáng được lặp lại vì đây là một tính năng quan trọng.
Điểm dừng phương pháp là khá có vấn đề.
Để làm mới lại, chúng ta có thể đặt một điểm ngắt dòng trên bất kỳ dòng nào trong phương thức và điểm dừng sẽ dừng ở đó. Điều này phổ biến đến mức chúng tôi chỉ gọi nó là “điểm dừng”.
Chúng ta có thể chuyển đổi điểm ngắt dòng tiêu chuẩn bằng control-F8 hoặc cách khác trên máy mac bằng Command-F8
.
Điểm ngắt phương thức dừng khi chúng ta nhập một phương thức. Bạn có thể nghĩ rằng điều này là vô ích. Tại sao không sử dụng điểm ngắt dòng?
Bạn sẽ đúng. Các điểm dừng phương thức chậm hơn nhiều và bạn không nên sử dụng chúng: vì điều này… Tuy nhiên, có một trường hợp sử dụng cho các điểm ngắt phương thức.
Lưu ý rằng vì các điểm ngắt phương thức rất chậm nên chúng thường được mô phỏng bởi IDE. Nó chỉ sử dụng các điểm ngắt dòng để mô phỏng các điểm ngắt của phương thức. Điều này gần như liền mạch đối với chúng tôi với tư cách là người dùng IDE nhưng chúng tôi cần biết về nó bởi vì, trước đây, điều này không đúng.
Bạn vẫn có thể tìm thấy thông báo từ người dùng trên StackOverflow phàn nàn về sự chậm chạp của các điểm ngắt phương thức.
Để xem trường hợp sử dụng cho các điểm dừng phương thức, hãy vào cửa sổ quản lý điểm ngắt. Giả sử chúng ta muốn phá vỡ tất cả các phương thức bắt đầu bằng chữ cái I và S trong các lớp có tên bắt đầu bằng Prime.
Chúng ta có thể làm điều này bằng cách sử dụng một biểu thức như thế này để dừng tất cả các phương thức như vậy dựa trên một mẫu. Điều này có vẻ xa vời nhưng thực sự rất hữu ích nếu bạn có một lớp cơ sở trừu tượng có các lớp con tuân theo quy ước đặt tên và chúng có nhiều phương thức liên quan.
Bạn muốn theo dõi mọi thứ và bạn có thể làm điều đó bằng phương pháp này. Lưu ý rằng bạn cũng có thể sử dụng các điểm theo dõi ở đây và ghi nhật ký rất sâu. Chúng ta sẽ thảo luận về các điểm theo dõi trong vài phút nữa.
Điểm theo dõi trường không phải là điểm dừng điển hình của bạn. Một điểm theo dõi sẽ dừng mỗi khi giá trị của trường thay đổi hoặc mỗi khi nó được đọc. Đây là một cách đặc biệt thú vị để nắm bắt trường hợp trong đó một số mã thay đổi một biến hoặc tìm hiểu cách một giá trị trường truyền vào mã.
Lưu ý rằng chúng ta có thể điều chỉnh xem nó dừng ở thao tác đọc, thao tác ghi hay cả hai bằng cách sử dụng hộp thoại này. Chúng tôi cũng có thể đặt điều kiện cho điểm theo dõi giống như chúng tôi có thể làm với bất kỳ điểm dừng nào khác.
Nó được gọi là điểm theo dõi chứ không phải điểm ngắt vì đó không phải là điểm dừng mã. Nó dừng lại ở điểm truy cập, không phải trên lĩnh vực này.
IDE cung cấp giao diện người dùng quản lý cho tất cả các điểm dừng. Chúng tôi có thể quản lý các điểm dừng mà chúng tôi đã có và tạo các điểm dừng mới trong menu điểm dừng xem. Tôi có thể mở nó thông qua tùy chọn menu điểm dừng xem hoặc tôi có thể sử dụng tổ hợp Shift-Control-F8
.
Lưu ý rằng, trên máy mac, chúng ta cần sử dụng lệnh thay vì phím điều khiển.
Trong hộp thoại này, chúng ta có thể vô hiệu hóa, xóa và chỉnh sửa các điểm dừng. Bạn sẽ nhận thấy chúng tôi có rất nhiều lựa chọn ở đây mà chúng tôi sẽ sớm thảo luận. Chúng ta có thể thêm các điểm ngắt từ đây. Có một số tùy chọn thú vị, nhưng bây giờ, tôi sẽ chỉ thêm một điểm ngắt trường đơn giản.
Chúng ta có thể đặt điểm dừng để dừng khi ném ngoại lệ. Nhưng đó là một chút vấn đề. Tôi có hai lựa chọn. Đầu tiên, tôi có thể bắt một ngoại lệ cụ thể theo tên. Điều này rất hữu ích nếu bạn biết trước ngoại lệ sẽ được ném ra.
Nhưng tôi không thể nghĩ ra nhiều trường hợp điều này xảy ra và tôi đã không biết dòng ném ngoại lệ.
Trường hợp sử dụng có giá trị hơn là bắt tất cả các ngoại lệ. Lý do điều này hữu ích là đôi khi tôi có thể không nhìn vào bảng điều khiển trong khi gỡ lỗi. Các trường hợp ngoại lệ có thể được ghi lại ở đó và tôi có thể bỏ lỡ chúng hoàn toàn.
Tôi có thể khởi động lại phiên gỡ lỗi và có thể bỏ lỡ những ngoại lệ này. Nhưng nếu một điểm dừng đột ngột dừng lại ở một ngoại lệ, thì rất khó để bỏ lỡ. Vấn đề là việc bắt tất cả các ngoại lệ bị hỏng theo mặc định!
Thật không may, điều này khó thể hiện trong một ứng dụng chính đơn giản, vì vậy tôi đã chuyển bản trình diễn sang một ứng dụng khởi động mùa xuân đơn giản. Nội dung của ứng dụng không quan trọng trong trường hợp này. Hãy kích hoạt bắt bất kỳ ngoại lệ nào và xem điều gì sẽ xảy ra…
Sau khi kích hoạt tính năng bắt, tôi cố gắng tiếp tục, nhưng nó ngay lập tức chạm điểm dừng hết lần này đến lần khác. Mã thăm dò một WebService trong nền. Dịch vụ web đó thiếu tiêu đề HTTP nên mã phân tích cú pháp tiêu đề đó không thành công trên NumberFormatException.
Chúng tôi bị mắc kẹt với mã đưa ra ngoại lệ hợp lệ đó vì Java không cung cấp một cách khác để phân tích các tiêu đề số khi mã đó được viết.
Vậy chúng ta có thể làm gì? Điều này thực sự làm cho việc dừng bất kỳ ngoại lệ nào trở nên vô dụng đối với hầu hết mọi ứng dụng trong thế giới thực.
Hãy di chuyển cửa sổ một chút rồi phóng to để xem chúng ta đang làm gì ở đây.
Bây giờ chúng ta có thể định nghĩa bộ lọc lớp. Lưu ý rằng tôi đặt trước cả hai bộ lọc một ký tự dấu trừ để biến bộ lọc này thành bộ lọc loại trừ. Ở đây, tôi định nghĩa một bộ lọc cho tất cả các gói java và tất cả các gói sun. Điều đó có nghĩa là mọi ngoại lệ được xử lý trong các gói này sẽ không bị hỏng.
Khi tôi nhấn OK, tôi có thể nhấn tiếp tục và ứng dụng sẽ chạy mà không vi phạm các ngoại lệ có vấn đề. Các trường hợp ngoại lệ khác sẽ hoạt động như bình thường và cho chúng tôi biết khi mã của chúng tôi bị lỗi!
Thật ngạc nhiên khi đây không phải là mặc định của IDE. Không có nó, tính năng này thực tế là vô dụng.
Tracepoints hoặc LogPoints là một số loại breakpoint quan trọng nhất mà chúng tôi có. Chúng ta có thể thêm một điểm theo dõi bằng cách nhấn shift trên máng xối. Điều này sẽ mở ra một hộp thoại điểm dừng quen thuộc, nhưng có vẻ hơi khác một chút. Trước hết, hãy chú ý điều này:
Tùy chọn tạm dừng không được chọn; lưu ý rằng chúng tôi có thể chuyển đổi bất kỳ điểm dừng nào thành điểm theo dõi bằng cách bỏ chọn hộp kiểm tạm dừng. Theo mặc định, một breakpoint ngắt. Nó dừng luồng hiện tại và tạm dừng nó để chúng ta có thể nhàn nhã kiểm tra ngăn xếp ứng dụng và xem điều gì đang xảy ra.
Một điểm theo dõi không tạm dừng luồng hiện tại. Ứng dụng đạt đến điểm dừng và sau đó tiếp tục chạy mà không dừng lại. Điều này là khá đột phá, làm thế nào để bạn bước qua?
Vâng, bạn không. Thay vào đó, chúng ta có thể làm một số việc khác…
Chúng tôi có thể ghi lại các từ “điểm ngắt” bất cứ khi nào chúng tôi đạt đến điểm ngắt, nhưng điều này không hữu ích trừ khi chúng tôi chỉ có một điểm theo dõi và chỉ muốn biết liệu chúng tôi có đạt đến điểm đó hay không. Chúng tôi có thể in dấu vết ngăn xếp mỗi khi chúng tôi đạt đến điểm theo dõi, điều này thực sự hữu ích hơn. Nhưng không nhiều.
Thật khó để đọc nhiều dấu vết trong một danh sách và theo dõi. Những gì tôi muốn tập trung vào là một cái gì đó khác.
Lưu ý rằng đánh giá và ghi nhật ký đã có giá trị cnt
trong đó vì tôi đã chọn giá trị cnt
trong IDE trước khi nhấp shift trong máng xối.
Chúng tôi có thể viết bất kỳ biểu thức nào chúng tôi muốn in ở đây. Tôi có thể gọi một phương thức để viết các chuỗi mô tả, v.v. Đây thực sự là một câu lệnh nhật ký tiêu chuẩn mà tôi có thể thêm động vào mã. Lưu ý rằng tôi vẫn có thể làm cho điểm theo dõi này có điều kiện giống như bất kỳ điểm dừng có điều kiện nào.
Điều đó có nghĩa là tôi có thể in bất kỳ giá trị nào tại thời điểm này. Cũng giống như bất kỳ logger. Đây là một tính năng ngoạn mục. Hãy tưởng tượng các điểm dừng phương pháp mà chúng ta đã thảo luận trước đó với các điểm theo dõi này; chúng tôi có thể đăng nhập ngay lập tức ở quy mô. Hãy nhấn OK.
Và sau đó chạy chương trình này; chúng tôi có thể thấy nhật ký mà chúng tôi đã thêm trong điểm theo dõi được in ra bảng điều khiển như thể chúng tôi đã viết nó trong mã!
Nhóm và đặt tên là rất quan trọng khi chúng tôi mở rộng quy mô gỡ lỗi của mình.
Chúng ta có thể đặt tên cho một điểm dừng bằng cách sử dụng mô tả để chỉ ra ý nghĩa ngữ nghĩa của nó. Điều này rất hữu ích khi chúng ta làm việc với nhiều breakpoint. Chúng tôi cũng có thể nhóm chúng dựa trên các tệp, gói, v.v.
Nhưng điều thú vị là chúng ta có thể tạo các nhóm tùy chỉnh cho các điểm dừng và vô hiệu hóa các điểm ngắt trong nhóm bằng một lần chuyển đổi. Điều đó rất tiện lợi!'
Nó giúp chúng ta không phải nhấn tiếp tục một cách tẻ nhạt khi cố gắng đạt đến một trạng thái và cho phép chúng ta quản lý nhiều điểm dừng.
Nhưng giá trị thực sự ở đây là ở quy mô. Giả sử bạn có một phiên gỡ lỗi phức tạp với nhiều điểm theo dõi chạy đồng thời.
Bạn có thể nhóm phiên và vô hiệu hóa các điểm dừng trong khi chuyển sang một nhánh khác để gỡ lỗi thứ khác. Sau đó quay trở lại nơi bạn đã ở khi bạn hoàn thành.
Đôi khi, một điểm dừng liên tục bị tấn công và chúng tôi chỉ cần một ngăn xếp cụ thể.
Chúng ta có thể vô hiệu hóa một điểm ngắt cho đến khi một điểm dừng khác hoặc một ngoại lệ được nhấn, tại thời điểm đó, điểm ngắt sẽ tự động được bật. Điều này giúp chúng tôi không cần phải nhấn tiếp tục mọi lúc nếu chúng tôi chỉ muốn kiểm tra một lộ trình cụ thể.
Điều này cũng hoạt động với các ngoại lệ và điểm dừng ngoại lệ và chúng tôi có thể quyết định hành vi sau đó. Chúng tôi muốn vô hiệu hóa nó một lần nữa hoặc tiếp tục như bình thường?
Điều này rất hữu ích cho trường hợp hỏng hóc chỉ đi qua một con đường cụ thể. Tôi có thể thêm một điểm theo dõi vào phương pháp đầu tiên. Sau đó vô hiệu hóa điểm ngắt thực tế mà tôi muốn trong điểm theo dõi đó.
Bộ lọc phiên bản cho phép chúng tôi chỉ chấp nhận một điểm ngắt từ một phiên bản đối tượng cụ thể.
Lưu ý trường hợp của đối tượng hiện tại được đánh dấu là “this” trong đồng hồ. Lưu ý rằng nó có ký hiệu at theo sau là số 656.
Đây là ID đối tượng Java tương đương với một con trỏ trong các ngôn ngữ lập trình khác. Trong các bộ lọc phiên bản, chúng tôi có thể giới hạn điểm ngắt để nó chỉ đạt được đối với một đối tượng cụ thể.
Giả sử điểm ngắt dòng này bị nhiều trường hợp tấn công nhưng tôi chỉ quan tâm đến kết quả từ một trường hợp đối tượng cụ thể và muốn lọc tất cả nhiễu. Tôi có thể mở hộp thoại chi tiết nâng cao bằng cách nhấp vào đây.
Tôi cần kiểm tra tùy chọn bộ lọc phiên bản, sau đó nhập ID đối tượng của phiên bản mà tôi muốn lọc. Điều này có nghĩa là điểm dừng sẽ không dừng đối với các loại phiên bản khác. Để áp dụng thay đổi này, tôi nhấn xong.
Tại thời điểm này, chúng ta có thể thấy bộ lọc phiên bản vẫn đang dừng tại điểm dừng được mong đợi…
Vì vậy, bước tiếp theo là thay đổi bộ lọc đối tượng thành một đối tượng khác. Tôi đang tạo ra một con số vì đây chỉ là một bài kiểm tra.
Lưu ý rằng khi tôi nhấp chuột phải vào điểm dừng, tôi nhận được phiên bản tùy chỉnh của hộp thoại này vì chúng tôi có sẵn bộ lọc phiên bản. Đây là một tính năng thực sự gọn gàng giúp giao diện người dùng dễ làm việc hơn rất nhiều.
Bây giờ chúng tôi đã thực hiện thay đổi đó, điểm dừng không còn bị hỏng nữa.
Bộ lọc lớp không có ý nghĩa đối với điểm ngắt dòng điển hình. Bộ lọc lớp có ý nghĩa khi sử dụng điểm theo dõi trường hoặc điểm dừng ngoại lệ.
Trong trường hợp này, tôi có một lĩnh vực công cộng. Tôi lọc quyền truy cập vào trường để bỏ qua tất cả quyền truy cập từ lớp chính nguyên tố. Nếu một lớp khác truy cập vào trường, điểm ngắt sẽ xảy ra.
Điều này rất hữu ích, nếu không, tôi có thể nhận được nhiều lượt truy cập vào điểm theo dõi từ lớp hiện tại. Nhưng tôi muốn xem các trường hợp khác.
Bộ lọc người gọi triển khai bộ lọc dựa trên chữ ký của phương thức gọi. Để sử dụng nó, chúng ta lại cần vào menu nâng cao. Nó hỗ trợ các ký tự đại diện để tôi có thể giới hạn người gọi chỉ cho phép phương thức chạy.
Lưu ý rằng nó sử dụng ký hiệu JVM cho chữ ký phương thức, đây là một chủ đề khá phức tạp mà tôi sẽ thảo luận sau. Tôi có một phần bao gồm điều đó trong cuốn sách gỡ lỗi của mình.
Phương thức tiếp tục dừng tại điểm ngắt như mong đợi bởi vì, như chúng ta có thể thấy ở đây, phương thức chạy thực sự nằm trong dấu vết ngăn xếp. Vì vậy, bộ lọc được áp dụng đúng cách và đạt đến điểm dừng.
Chúng ta có thể tùy chỉnh lại điểm ngắt trong giao diện người dùng chỉnh sửa nhanh cho bộ lọc. Trong trường hợp này, tôi đã thay đổi bộ lọc để tìm một phương thức có tên là stop không tồn tại và thực sự, điểm ngắt không còn bị ngắt nữa.
Đây là một video dài, tôi hy vọng bạn thấy nó mang tính giáo dục và toàn diện. Trong video tiếp theo, chúng ta sẽ nói về cách gỡ lỗi luồng và bộ sưu tập.
Nếu bạn có bất kỳ câu hỏi nào, vui lòng sử dụng phần bình luận. Cảm ơn bạn!