Trình tìm kiếm thoát đột ngột. Nhưng tại sao?
Báo cáo sự cố có thể dẫn đến manh mối về lý do tại sao một ứng dụng gặp sự cố trong macOS. Dưới đây là cách hiểu những báo cáo đó thực sự nói gì về máy Mac của bạn.
Có thể bạn đã thấy cảnh báo của Finder khi có ứng dụng thoát đột ngột trên máy Mac của bạn.
Trong giới lập trình được gọi là”sự cố”, những lỗi này thường xảy ra khi một đoạn mã không hợp lệ được chạy khiến hệ thống hoặc CPU không thể thực thi. Chúng cũng có thể xảy ra nếu một ứng dụng cố truy cập vào phiên bản thư viện hoặc khung bị thiếu hoặc lỗi thời và không thể thực thi đoạn mã cần thiết.
Khi macOS hiển thị một trong những cảnh báo sự cố này, bạn có thể nhấp vào nút”Bỏ qua”hoặc nhấp vào nút”Báo cáo”.
Nếu bạn nhấp vào nút”Báo cáo”, Finder sẽ hiển thị một cửa sổ có báo cáo sự cố và nút”Gửi tới Apple”. Bạn nên gửi báo cáo cho Apple nếu phần mềm của Apple gây ra lỗi.
Mỗi báo cáo sự cố được lưu trữ trong một tệp.ips trong thư mục”DisagnosticReports”bên trong thư mục người dùng của bạn tại/Users/~/Library/Logs/
Bạn cũng có thể xem và mở các báo cáo này trong ứng dụng Bảng điều khiển của Apple bằng cách chọn mục”Báo cáo sự cố”ở phía bên trái của cửa sổ Bảng điều khiển, chọn một báo cáo ở phía bên phải của cửa sổ, sau đó nhấp vào Điều khiển hoặc nhấp chuột phải vào báo cáo và chọn”Hiển thị trong Finder”từ menu bật lên.
Thao tác này sẽ mở thư mục Báo cáo chẩn đoán trong Finder, hiển thị tất cả các tệp báo cáo sự cố đã lưu. Các báo cáo này chỉ được macOS lưu giữ trong một khoảng thời gian giới hạn, sau đó hệ thống sẽ tự động bắt đầu xóa các báo cáo cũ nhất trước tiên.
Ngoài ra còn có một mục menu”Chuyển vào Thùng rác”trong menu bật lên của Bảng điều khiển nếu bạn muốn chuyển các tệp báo cáo sự cố đã chọn vào Thùng rác.
Nếu bạn nhấp đúp vào tệp.ips trong Finder, tệp đó chỉ mở lại trong ứng dụng Bảng điều khiển. Nếu bạn giữ Control khi bấm vào tệp.ips trong Finder và chọn”Mở bằng”, sau đó chọn”TextEdit”từ menu bật lên, thì bạn cũng có thể mở tệp.ips trong TextEdit.
Xin lưu ý rằng văn bản của mỗi báo cáo được lưu trữ trong tệp.ips ở định dạng JSON , vì vậy bạn cần có khả năng đọc JSON để hiểu nó.
Đọc báo cáo sự cố trong Bảng điều khiển
Dù sao đi nữa, nếu bạn chọn một báo cáo sự cố trong Bảng điều khiển, bạn có thể đọc văn bản của nó trong khung văn bản chính bên dưới nó:
Hãy xem một số trường đầu tiên trong báo cáo sự cố.”Quy trình”trong UNIX có nghĩa là một ứng dụng đang chạy. Các trường là:
Quy trình-tên ứng dụng hoặc quy trình. Đường dẫn-nơi tệp nhị phân của ứng dụng tồn tại trên đĩa. Mã định danh-thường là tên nhị phân hoặc tên gói, nhưng không phải lúc nào cũng vậy. Phiên bản-phiên bản nhị phân hay ??? nếu chưa biết. Loại mã-Intel hoặc Apple Silicon.”Phổ quát”nếu cả hai. Quy trình gốc-tệp nhị phân hoặc ứng dụng đã khởi chạy quy trình này. ID người dùng-id UNIX hoặc PID của quy trình-cùng ID quy trình như được hiển thị trong Terminal.
Tiếp theo, chúng ta có ngày/giờ, phiên bản hệ điều hành, phiên bản báo cáo và một UUID duy nhất cho báo cáo này. Ngoài ra còn có một ID ngủ/thức duy nhất.
Báo cáo cũng liệt kê xem Bảo vệ toàn vẹn hệ thống có được bật hay không.
Tiếp theo, báo cáo liệt kê chi tiết về chính vụ tai nạn. Thông tin này có thể khá kỹ thuật và thường dành cho các lập trình viên hoặc cho Apple nhằm tìm ra nơi xảy ra sự cố trong mã ứng dụng để có thể khắc phục sự cố.
Thông thường, số luồng bị lỗi sẽ được liệt kê-trong trường hợp này là luồng đầu tiên-luồng 0. Hãy nghĩ về một luồng như một đường dẫn mã chạy độc lập với mã khác. Trên các hệ thống CPU đa lõi, mỗi lõi có thể có một hoặc nhiều luồng chạy với tất cả các lõi chạy song song nếu cần. Điều này được gọi là tính toán song song.
Tiếp theo, sự cố hoặc loại ngoại lệ được liệt kê:
Loại ngoại lệ: EXC_CRASH (SIGABRT)
Trong trường hợp này, SIGABRT-tín hiệu UNIX để hủy bỏ, hoặc giết, chủ đề đã được gửi. Tín hiệu là các thông báo mà UNIX gửi tới các tiến trình đang chạy ở mức thấp để yêu cầu chúng làm điều gì đó-trong trường hợp này là thoát.
Thông tin thêm về các tín hiệu UNIX và cách chúng hoạt động có sẵn trực tuyến.
Tiếp theo là các mã ngoại lệ, nếu có, nhưng các mã này thường bằng không.
“0x”trước mỗi mã có nghĩa là giá trị mã ở dạng thập lục phân hoặc”hex”thay vì thập phân. Hệ thập lục phân là một hệ thống số cơ số 16-với mười sáu giá trị thay vì mười như hệ thống số thập phân có. Hex sử dụng 0-9 và sau đó là A-F làm giá trị bổ sung.
Bạn có thể đọc về cách hoạt động của hệ thống số hex trong bất kỳ cuốn sách hay nào về ngôn ngữ lập trình C.
Tiếp theo là lý do chấm dứt, thường là một mô tả giống như tiếng Anh về nguyên nhân gây ra sự cố. Trong trường hợp này”Không gian tên DYLD, Thiếu thư viện mã 1″.
DYLD là Dynamic Loader-một phần của HĐH tự động tải mã vào bộ nhớ từ đĩa khi cần chạy mã. Bạn có thể đọc thêm về DYLD trong Terminal bằng cách nhập man dyld và nhấn Return.
Không gian tên là quy ước đặt tên được sử dụng trong một số ngôn ngữ lập trình để tách biệt các phần mã với mã khác.”Thiếu thư viện mã 1″có nghĩa là DYLD đã cố tải một thư viện được liên kết động nhưng không được.
Trong lập trình, thư viện là các gói mã. Các thư viện có thể là tĩnh (được liên kết với ứng dụng khi xây dựng) hoặc động (được tải vào ứng dụng khi chạy).
Nếu lỗi là lỗi tải DYLD, dòng tiếp theo cho chúng tôi biết đó là thư viện nào và nó nằm ở đâu trên đĩa:
“Thư viện chưa được tải: @rpath/VBoxRT. dylib”
Trong trường hợp này, VBoxRT.dylib là một thư viện động (.dylib) dành cho ứng dụng Virtual Box của Oracle. DYLD tìm thư viện động VBoxRT.dylib nhưng không thấy nên app không chạy được và bị gửi tín hiệu SIGABRT báo thoát.
Ứng dụng dành cho macOS và iOS thực sự được tạo thành từ một số thành phần-thường là một thư mục có tên là Gói
Trong ví dụ này, chúng ta có thể thấy tệp nhị phân của ứng dụng bên trong thư mục MacOS bên trong Nội dung thư mục trong gói ứng dụng:
Ngoài ra còn có thư mục Thư viện và sau đó là cả hai Thư viện Apple Silicon và Intel x86 trong các thư mục ở định dạng.dylib cho cả hai kiến trúc nền tảng Mac. Chúng được tải vào thời gian chạy khi DYLD cần.
Một số gói ứng dụng có thể khá đơn giản, một số khác thì rất phức tạp. Mã và các tài nguyên khác có thể được lưu trữ ở nơi khác, bên ngoài gói ứng dụng.
Trong ví dụ trên,.dylib được lưu trữ bên ngoài và thường sẽ được tải khi cần trong thời gian chạy..dylibs thường là các tệp nhị phân đơn thay vì gói.
Ngoài ra còn có hỗ trợ trong iOS và macOS dành cho Khung, là các gói chứa mã và các tài nguyên khác. Bạn có thể xem bên trong các khung trong Finder giống như cách bạn có thể xem bên trong các gói ứng dụng bằng cách sử dụng menu bật lên được đề cập ở trên. Các khung luôn có số phiên bản bên trong các gói của chúng.
Các khung có thể được lưu trữ bên trong gói ứng dụng hoặc trong/Library/Frameworks và/user/~/Library/Frameworks. Bản thân phần lớn macOS và iOS được triển khai dưới dạng các khung có thể tải động.
Apple có hướng dẫn lập trình Framework dành cho nhà phát triển mô tả chi tiết quy trình tải và liên kết mã macOS và iOS. Việc kết nối hai đoạn mã có liên quan tĩnh được gọi là liên kết, thay vì liên kết và được thực hiện khi một ứng dụng được xây dựng bằng trình biên dịch.
Tất cả mã tĩnh được tải cùng một lúc, điều này có thể tiêu tốn nhiều bộ nhớ hệ thống hơn.
Apple cũng có một tài liệu riêng dành cho nhà phát triển trình bày chi tiết về thời gian chạy của Objective-C và Swift, cả hai đều chứa thông tin bổ sung về cách mã được tải trong quá trình thực thi ứng dụng.
Tải mã động đã có từ cuối những năm 1970 với các ngôn ngữ như SmallTalk. Trên các nền tảng của Apple, nó xuất hiện là kết quả của việc Apple mua NeXT vào năm 1997-và cùng với đó là việc mua lại ngôn ngữ lập trình của NeXT là Objective-C, ngôn ngữ đi tiên phong trong việc sử dụng liên kết động và xem xét nội tâm.
NeXTStep Developer-một trong những gói dành cho nhà phát triển đầu tiên sử dụng liên kết động.
Ngày nay, phần mềm của Apple vẫn được viết bằng Objective-C hoặc Swift của chính Apple, cũng sử dụng liên kết và tải động.
Tải động cho phép ứng dụng có dung lượng bộ nhớ nhỏ hơn vì không phải tất cả mã và tài nguyên của ứng dụng đều cần được tải vào bộ nhớ cùng một lúc. Nhược điểm của tải động là đôi khi chậm hơn, vì tài nguyên phải được tải từ đĩa trong khi ứng dụng đang chạy.
Đây là một trong những lý do phổ biến khiến con trỏ quả bóng bãi biển quay tròn khét tiếng của macOS.
Tiếp theo trong báo cáo sự cố, chúng tôi được cho biết quy trình gọi hoặc mã nhị phân nào gọi là mã vi phạm, được liệt kê trong phần”Được tham chiếu từ:”. Trong trường hợp này, đó là tệp nhị phân chính của ứng dụng VirtualBox được lưu trữ bên trong gói của ứng dụng.
Đoạn cuối cùng của thông tin có thể đọc được bằng tiếng Anh là”Lý do:”, cố gắng cung cấp lý do mà con người có thể đọc được tại sao lại xảy ra sự cố:
“‘/usr/lib/VBoxRT.dylib'(không có tệp như vậy, không có trong bộ đệm dyld), (chính sách bảo mật không cho phép mở rộng đường dẫn @)
(chấm dứt khi khởi chạy; bỏ qua dấu vết ngược)”.
Điều này có nghĩa là thư viện cần thiết phải có tại/usr/lib/VBoxRT.dylib trên đĩa nhưng không có (thư viện này thường được đặt ở đó bởi trình cài đặt VirtualBox khi cài đặt), DYLD chưa được tải trước đó nó và ứng dụng đã bị giết khi khởi chạy.
Tóm lại, trong ví dụ trên, VirtualBox đã được khởi chạy nhưng không thể tìm thấy thư viện động cần thiết, do đó, nó đã bị macOS tắt và ngừng hoạt động. Tất cả thông tin đã được thu thập và thêm vào báo cáo sự cố.
Thông tin bảng điều khiển bổ sung và dấu vết ngăn xếp
Phần còn lại của thông tin trong báo cáo sự cố thậm chí còn mang tính kỹ thuật hơn nên chúng tôi sẽ không đi sâu vào mọi chi tiết ở đây , nhưng có một số điều bạn có thể đọc nhanh để xác định điều gì đã xảy ra.
Cụ thể, bạn có thể theo dõi quá trình thực thi mã của ứng dụng, theo thứ tự ngược lại được liệt kê dưới mỗi số luồng, để tìm manh mối về lý do xảy ra sự cố. Không phải tất cả các sự cố đều liên quan đến thiếu thư viện, vì vậy có thể ứng dụng đã khởi chạy đúng cách nhưng đơn giản là do lỗi lập trình trong mã gây ra sự cố.
Đôi khi một lập trình viên sẽ phạm sai lầm khi gọi mã hệ thống không tồn tại hoặc đã thay đổi các tham số chức năng của nó. Hoặc đó có thể là lỗi truy cập bộ nhớ hoặc ghi đè các biến trong mã có quá nhiều dữ liệu thường ghi đè lên thứ gì đó quan trọng liền kề trong bộ nhớ.
Tất cả những lỗi này có thể gây ra sự cố.
Thông tin này thường được liệt kê ngay sau phần”Lý do:”và thường có danh sách các lệnh gọi hàm được đánh số, cùng với tên, địa chỉ trong bộ nhớ và cách chúng được tải. Lưu ý rằng trong phần này, bạn muốn đọc danh sách các chức năng (được gọi là theo dõi ngăn xếp), theo thứ tự ngược lại-từ dưới lên.
Đây là thứ tự thực thi các chức năng.
Trong trường hợp này, ngăn xếp rất ngắn và bao gồm hầu hết các tín hiệu chuẩn bị DYLD và tạm dừng/hủy do không thể tải thư viện cần thiết khi khởi chạy. Nhưng một số lỗi có thể có ngăn xếp khá phức tạp.
Thông thường, hàm cuối cùng ở đầu (cuối) của ngăn xếp là hàm gây ra sự cố-nhưng không phải lúc nào cũng vậy.
Biết điều này có thể hữu ích cho việc chẩn đoán sự cố vì ngăn xếp có thể cho bạn biết lệnh gọi hàm chính xác không thành công. Sau đó, bạn có thể tra cứu tên của chức năng đó trong tài liệu dành cho nhà phát triển của Apple để có thêm manh mối về những gì đã xảy ra.
Đôi khi, tên khung hoặc thư viện chứa chức năng gặp sự cố sẽ được liệt kê trong theo dõi ngăn xếp, điều này thậm chí còn cung cấp nhiều thông tin hơn.
Sau khối ngăn xếp trong báo cáo sự cố là một số thông tin về trạng thái luồng, thông tin này không thực sự liên quan trừ khi bạn là nhà phát triển, tiếp theo là luồng đang chạy trên CPU nào, mã lỗi nếu có, và một số Bẫy. Bẫy là các điểm chèn trong mã hệ điều hành được gọi khi một số sự kiện xảy ra.
Bộ nhớ sự cố và tóm tắt
Tiếp theo là một số thông tin về các tệp nhị phân (mã được biên dịch) liên quan đến sự cố-và những tệp này thường, nhưng không phải lúc nào cũng là thông tin tương tự như được liệt kê gần đầu báo cáo sự cố.
Sau đó, có một Tóm tắt sửa đổi bên ngoài-tóm tắt ID quy trình tương tác với quy trình này và một số thông tin Bộ nhớ ảo (VM) về phần nào của mã nằm trong bộ nhớ và phần nào vẫn còn trên đĩa. Bộ nhớ ảo đề cập đến dung lượng ổ đĩa mà HĐH sử dụng như thể đó là RAM thực để tăng tổng bộ nhớ khả dụng mà hệ thống sử dụng.
Sau đó, có một số thông tin”loại vùng”tóm tắt thông tin bổ sung về ngăn xếp, máy ảo, phân đoạn liên kết và văn bản cũng như DYLD và bộ nhớ dùng chung. Bạn thường có thể bỏ qua thông tin này trừ khi bạn là nhà phát triển.
Ở cuối mỗi báo cáo sự cố, có phần”Báo cáo đầy đủ”. Phần này về cơ bản là kết xuất JSON thô đầy đủ của toàn bộ tệp.ips ở định dạng văn bản. JSON thô có chứa một số thông tin bổ sung không được hiển thị trong cửa sổ Bảng điều khiển-chẳng hạn như ID kiểu máy Mac của Apple, loại CPU, ký mã và thông tin khác.
Cũng xin lưu ý rằng một ứng dụng có thể có nhiều luồng đang chạy, do đó, một bản tóm tắt tương tự như trên sẽ được liệt kê cho mỗi luồng. Nhưng thông thường, số luồng bị lỗi được liệt kê ở đầu báo cáo để bạn biết nên xem số luồng nào.
Tất cả những điều này có vẻ quá sức đối với người mới, nhưng một khi bạn đã quen với việc đọc các báo cáo sự cố, bạn thường có thể nhanh chóng và dễ dàng tìm ra điều gì đã xảy ra-và liệu bạn có thể làm gì với nó hay không. Trong ví dụ trên, vì thư viện bắt buộc bị thiếu nên việc cài đặt lại ứng dụng đơn giản bằng trình cài đặt của nó sẽ được thực hiện theo thứ tự.
Apple cung cấp trực tuyến Hướng dẫn sử dụng bảng điều khiển, trong đó khá nhiều thông tin và hữu ích.