[英]Detect C/C++ command line memory leaks using Instruments
我正在嘗試檢測 macOS 上 C(和 C++)程序中的 memory 泄漏。 在 Linux 和 Windows 中,我可以使用valgrind
輕松做到這一點,但不幸的是,它在 macOS 上不可用。
由於我有 ObjC 和 iOS 開發的背景經驗,我想使用 Instruments 來進行 memory 泄漏檢查。 乍一看,這聽起來很適合這份工作。
我寫了這個非常簡單的泄露程序:
#include <stdlib.h>
#include <stdio.h>
int* allocSomething() {
return malloc(sizeof(int));
}
int main(int argc, const char * argv[]) {
int* p = allocSomething();
*p = 5;
printf("*p = %d\n", *p);
p = NULL;
return 0;
}
我通過 Clang Static Analyzer 運行它,它完成了這項工作,但我希望它也能被 Instruments 捕獲,因為我正在尋找合適的 Valgrind 替代品。 因此:
如您所見,沒有報告泄漏。 在網上搜索后,我在 xcode 9 個儀器中遇到 Can't detect C leaks ,其中作者使用了sleep
,所以我想可能 Instruments 實際上並沒有覆蓋malloc
采樣技術,而是使用了 agrind 采樣技術,在這么短的時間內對其進行采樣,因此我將程序更改為:
int main(int argc, const char * argv[]) {
int* p = allocSomething();
p = NULL;
sleep(600000);
return 0;
}
這完全沒有意義,因為這是一個明顯的 memory 泄漏。 我會說它必須做一些優化,但我又一次明確地禁用了它。 另外,如果我malloc
更多字節,它確實檢測到它。 或者可能是儀器中的錯誤?
所以我想知道這是否是儀器無法檢測到小分配的問題? 我必須指出,Valgrind 可以很好地處理它,所以我很驚訝。
你有什么建議嗎?
Leaks 工具(Leaks 模板中的一種工具)的工作方式與您的預期不同。
首先,為什么它不會檢測任何短期進程:它是基於計時器的。 它每隔一段時間就會停止該過程並檢查它是否存在泄漏。 對於一個短暫的進程,檢查永遠不會在進程退出之前發生。
其次,它為什么會漏掉一些泄漏:它檢查所有線程的堆棧、所有線程的寄存器以及尋找分配地址的全局變量。 如果在這些位置中的任何一個找到分配的地址,則該分配不被視為已泄漏。
在您的情況下,分配的地址可能仍在寄存器或堆棧 memory 中。 在“真正的”程序中,堆棧和寄存器最終會被重用,並且這些陳舊的數據將被消除。
Allocations 工具確實跟蹤所有分配和解除分配(假設該過程由 Instruments 啟動)。 您泄露的分配在分配列表中,並且仍然列為“實時”(又名創建和持久)。 問題是 Allocations 工具沒有明確地將此類分配稱為泄漏。
此外,系統庫還進行了旨在保留到進程退出並且沒有明確清理的分配。 因此,您的泄漏有點隱藏在不相關的信息中。 您可以過濾和排序分配列表以發現您的泄漏,但這需要做一些事情。
在更真實的程序的上下文中,Instruments 非常擅長發現泄漏。
顯然, Clang 支持LeakSanitizer ,作為 AddressSanitizer 的一部分或獨立。 這可能需要一個比 Apple 作為 Xcode 和/或 Catalina 的一部分提供的版本更新的 Clang 版本。 (我在 Mojave 上使用 Xcode 11.3.1 進行了測試。它不支持-fsanitize=leak
選項,也不支持ASAN_OPTIONS=detect_leaks=1
。)假設你可以讓它工作,那可能更像你'期待。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.