Finder 意外退出。但為什麼呢?

崩潰報告可以提供有關應用程序在 macOS 中崩潰的原因的線索。以下是了解這些報告對您的 Mac 的實際評價的方法。

您可能已經看到 Finder 警告在 Mac 上意外退出。

在編程世界中稱為“崩潰”,這些錯誤通常發生在系統或 CPU 無法執行的錯誤代碼段運行時。如果應用程序試圖訪問庫或框架的缺失或過時版本並且無法執行所需的代碼片段,它們也會發生。

當 macOS 顯示這些崩潰警報之一時,您可以單擊“忽略”按鈕,也可以單擊“報告”按鈕。

如果您單擊“報告”按鈕,Finder 會顯示一個包含崩潰報告的窗口和一個“發送到 Apple”按鈕。如果錯誤是由 Apple 軟件引起的,您應該將報告發送給 Apple。

每個崩潰報告都存儲在位於/Users/~/Library/Logs/的用戶文件夾“DisagnosticReports”文件夾中的.ips 文件中

您還可以查看和打開通過選擇控制台窗口左側的“崩潰報告”項目,在窗口右側選擇一個報告,然後按住 Control 鍵單擊或右鍵單擊報告並選擇從彈出菜單中選擇“在 Finder 中顯示”。

這會在 Finder 中打開 DiagnosticReports 文件夾,顯示所有保存的崩潰報告文件。這些報告僅由 macOS 保留有限的時間,然後它會自動開始首先刪除最舊的報告。

如果您想將選定的崩潰報告文件移動到垃圾箱,控制台彈出菜單中還有一個“移動到垃圾箱”菜單項。

如果您在 Finder 中雙擊一個.ips 文件,它只會在控制台應用程序中重新打開它。如果您在 Finder 中按住 Control 單擊一個.ips 文件並選擇“打開方式”,然後從彈出菜單中選擇“TextEdit”,您也可以在 TextEdit 中打開該.ips 文件。

請注意,存儲在.ips 文件中的每個報告的文本都是 JSON 格式,因此您需要能夠閱讀 JSON 才能理解它。

在控制台中閱讀崩潰報告

無論如何,如果您在控制台中選擇崩潰報告,您可以在下面的主文本窗格中閱讀其文本it:

讓我們來看看崩潰報告中的前幾個字段. UNIX 中的“進程”表示正在運行的應用程序。這些字段是:

Process-應用程序或進程名稱。路徑-應用程序二進製文件在磁盤上的位置。標識符-通常是二進製文件或包名稱,但並非總是如此。版本-二進製版本或 ???如果未知。代碼類型-Intel 或 Apple Silicon。 “通用”如果兩者兼而有之。父進程-啟動此進程的二進製文件或應用程序。用戶 ID-進程的 UNIX id 或 PID-與終端中顯示的進程 ID 相同。

接下來,我們有日期/時間、操作系統版本、報告版本和此報告的唯一 UUID。還有一個唯一的睡眠/喚醒 ID。

該報告還列出了系統完整性保護是否已啟用。

接下來,報告列出了有關崩潰本身的詳細信息。此信息可能非常技術性,通常供程序員或 Apple 使用,以便跟踪應用程序代碼中出現問題的位置,以便進行修復。

通常,會列出崩潰的線程編號-在本例中為第一個線程-線程 0。將線程視為獨立於其他代碼運行的代碼路徑。在多核 CPU 系統上,每個內核可以有一個或多個線程運行,如果需要,所有內核並行運行。這稱為並行計算。

接下來,列出崩潰或異常類型:

異常類型:EXC_CRASH (SIGABRT)

在這種情況下,SIGABRT-UNIX 中止信號,或殺死,線程已發送。信號是 UNIX 發送給低級別正在運行的進程的消息,告訴它們做某事——在本例中是退出。

有關 UNIX 信號及其工作方式的更多信息可在線獲取。

接下來是異常代碼(如果有的話),但這些代碼通常為零。

每個代碼前的“0x”表示代碼值是十六進製或“十六進制”而不是十進制。十六進制是一個以 16 為基數的數字系統-有十六個值而不是十進制數字系統所具有的十個值。十六進制使用 0-9,然後是 A-F 作為附加值。

您可以在任何有關 C 編程語言的好書中了解十六進制數字系統的工作原理。

接下來是終止原因,通常是對導致崩潰的原因的類似英文的描述。在這種情況下,“命名空間 DYLD,缺少代碼 1 庫”。

DYLD 是動態加載器-操作系統的一部分,它在需要運行時將代碼從磁盤動態加載到內存中。您可以通過鍵入 man dyld 並按回車鍵在終端中閱讀有關 DYLD 的更多信息。

命名空間是一些編程語言中使用的命名約定,用於將代碼段與其他代碼隔離開來。 “代碼 1 庫丟失”表示 DYLD 嘗試加載動態鏈接庫但無法加載。

在編程中,庫是代碼包。庫可以是靜態的(在構建時鏈接到應用程序中),也可以是動態的(在運行時加載到應用程序中)。

如果錯誤是 DYLD 加載錯誤,下一行會告訴我們它是哪個庫,以及它在磁盤上的位置:

“庫未加載:@rpath/VBoxRT。 dylib”

在這種情況下,VBoxRT.dylib 是 Oracle Virtual Box 應用程序的動態庫 (.dylib)。 DYLD 尋找 VBoxRT.dylib 動態庫但找不到它,因此應用程序無法運行並被發送 SIGABRT 信號告訴它退出。

macOS 和 iOS 的應用程序實際上由幾個組件組成-通常是一個名為 Bundle 的文件夾

在這個例子中,我們可以在 Contents 的 MacOS 文件夾中看到應用程序二進製文件應用程序包中的文件夾:

還有一個 Libraries 文件夾,然後兩個文件夾中的 Apple Silicon 和 Intel x86 庫以.dylib 格式用於兩種 Mac 平台架構。它們根據 DYLD 的需要在運行時加載。

有些應用程序包可能非常簡單,有些則非常複雜。代碼和其他資源可以存儲在應用程序包之外的其他地方。

在上面的示例中,.dylib 存儲在外部,通常會在運行時需要時加載。.dylibs 通常是單個二進製文件而不是包。

iOS 和 macOS 也支持框架,它們是包含代碼和其他資源的捆綁包。您可以在 Finder 中查看框架內部,就像使用上面提到的彈出菜單查看應用程序包內部一樣。框架在它們的包中總是有一個版本號。

Frameworks 可以存儲在應用程序包內,或/Library/Frameworks 和/user/~/Library/Frameworks 中。許多 macOS 和 iOS 本身都是作為動態可加載框架實現的。

Apple 有一個開發者框架編程指南,詳細描述了 macOS 和 iOS 代碼的加載和綁定過程。連接兩段靜態相關代碼稱為鏈接,而不是綁定,這是在使用編譯器構建應用程序時完成的。

靜態代碼全部加載一次,這會消耗更多的系統內存。

Apple 還有一個單獨的開發人員文檔,其中詳細介紹了 Objective-C 和 Swift 運行時,兩者都包含有關在應用程序執行期間如何加載代碼的附加信息。

動態代碼加載可以追溯到 70 年代後期的 SmallTalk 等語言。在 Apple 的平台上,它是由於 Apple 於 1997 年收購了 NeXT 而產生的-並隨之收購了 NeXT 的編程語言 Objective-C,該語言率先使用了動態鏈接和 內省

NeXTStep Developer-首批開發包之一

今天,Apple 軟件仍然使用 Objective-C 或 Apple 自己的 Swift 編寫,後者也使用動態鏈接和加載。

動態加載允許應用佔用更小的內存,因為並非應用的所有代碼和資源都需要一次加載到內存中。動態加載的缺點是有時速度較慢,因為必須在應用程序運行時從磁盤加載資源。

這是臭名昭著的 macOS 旋轉沙灘球光標的常見原因之一。

接下來在崩潰報告中,我們被告知哪個調用進程或代碼二進製文件調用了有問題的代碼,列在“引用自:”下。在這種情況下,它是存儲在應用程序包中的主要 VirtualBox 應用程序二進製文件。

英文可讀信息的最後一位是“Reason:”,它試圖提供一個人類可讀的崩潰發生原因:

“‘/usr/lib/VBoxRT.dylib’(沒有這樣的文件,不在 dyld 緩存中),(安全策略不允許@路徑擴展)

(在啟動時終止;忽略回溯)”。

這意味著所需的庫應該在磁盤上的/usr/lib/VBoxRT.dylib 但不是(它通常在安裝時由 VirtualBox 安裝程序放在那裡),DYLD 之前沒有加載它,並且該應用程序在啟動時被殺死。

所以總結一下,在上面的例子中,VirtualBox 啟動了,但是找不到所需的動態庫,所以它被 macOS 殺死並退出了。所有信息都已收集並添加到崩潰報告中。

其他控制台信息和堆棧跟踪

崩潰報告中的其餘信息更具技術性,因此我們不會在這裡詳述每個細節,但有些內容您可以快速閱讀以確定發生了什麼。

特別是,您可以按照每個線程編號下列出的相反順序跟踪應用程序的代碼執行,以查找崩潰發生原因的線索。並非所有崩潰都與缺少庫有關,因此應用程序可能會正確啟動,但只是代碼中的編程錯誤導致了崩潰。

有時程序員會錯誤地調用不存在的系統代碼,或者更改了它的函數參數。或者它可能是內存訪問錯誤,或者用太多數據覆蓋代碼中的變量,這通常會覆蓋內存中重要的相鄰內容。

所有這些錯誤都可能導致崩潰。

此信息通常緊跟在“原因:”部分之後列出,並且通常有一個編號的函數調用列表,包括它們的名稱、內存中的地址以及它們是如何加載的。請注意,在本節中,您希望以相反的順序從下到上閱讀函數列表(稱為堆棧跟踪)。

這是函數實際執行的順序。

在這種情況下,堆棧非常短,主要由 DYLD 準備和暫停/中止信號組成,因為所需的庫無法在啟動時加載。但是有些錯誤可能有相當複雜的堆棧。

通常,堆棧頂部(末端)的最後一個函數是導致問題的函數-但並非總是如此。

知道這一點可以方便地診斷崩潰,因為堆棧可以告訴您失敗的確切函數調用。然後,您可以在 Apple 的開發人員文檔中查看該函數的名稱,以獲取有關發生的事情的更多線索。

有時,包含崩潰函數的框架或庫名稱會列在堆棧跟踪中,從而提供更多信息。

崩潰報告中的堆棧塊之後是一些線程狀態信息,除非您是開發人員,否則這些信息並不真正相關,然後是線程在哪個 CPU 上運行,如果有錯誤代碼,和一個陷阱號。陷阱是操作系統代碼中的插入點,當某些事件發生時會被調用。

崩潰記憶和總結

接下來有一些關於崩潰中涉及的二進製文件(編譯代碼)的信息——這些通常是,但不總是與崩潰報告頂部附近列出的信息相同。

在那之後,有一個外部修改摘要-與此進程交互的進程 ID 的摘要,以及一些關於代碼的哪些部分在內存中,哪些仍在磁盤上的虛擬內存 (VM) 信息。虛擬內存是指操作系統使用的磁盤空間,就好像它是真實 RAM 一樣,以增加系統使用的總可用內存。

然後是一些“區域類型”信息,它總結了有關堆棧、VM、鏈接和文本段以及 DYLD 和共享內存的附加信息。除非您是開發人員,否則通常可以忽略此信息。

在每個崩潰報告的末尾,都有一個“完整報告”部分,它本質上是整個.ips 文件的文本格式的完整原始 JSON 轉儲。原始 JSON 確實包含一些未在控制台窗口中顯示的附加信息-例如 Apple Mac 型號 ID、CPU 類型、代碼簽名和其他信息。

另請注意,一個應用程序可能有多個線程在運行,因此將為每個線程列出與上麵類似的摘要。但通常,崩潰的線程號列在報告的最頂部,因此您知道要查看哪個線程號。

對於新手來說,所有這些似乎都讓人不知所措,但是一旦您掌握了閱讀崩潰報告的竅門,您通常可以快速輕鬆地弄清楚發生了什麼-以及您是否可以採取任何措施。在上面的示例中,由於缺少所需的庫,因此可以使用其安裝程序簡單地重新安裝應用程序。

Apple 在線提供了詳細的控制台用戶指南,其中信息量很大,很有幫助。

Categories: IT Info