內(nèi)存調(diào)試
本章是有關PHP源代碼的內(nèi)存調(diào)試的簡要介紹。 這不是一門完整的課程:內(nèi)存調(diào)試并不難, 但是你需要一些它的使用經(jīng)驗,大量的練習可能是你在設計任何C編寫的代碼時都必須要做的事情。我們將在這里介紹一個非常著名的內(nèi)存調(diào)試器: valgrind; 以及如何將其與PHP一起使用來調(diào)試內(nèi)存問題。
相關學習推薦:PHP編程從入門到精通
Valgrind簡介
Valgrind是許多Unix環(huán)境下使用的知名工具,可以在任何C/C++編寫的軟件中調(diào)試許多常見的內(nèi)存問題。 Valgrind 是有關內(nèi)存調(diào)試的多功能前端工具。最常用的底層工具稱為 “memcheck”。它的工作方式是用自己的堆分配替換每個libc的堆分配,并跟蹤你對它們所做的事情。你可能還會對 “massif” 感興趣: 它是一個內(nèi)存跟蹤器,對于了解程序的常規(guī)堆內(nèi)存使用情況非常有用。
注意
你應該閱讀Valgrind文檔,以進一步了解。 它寫得很好,帶有一些典型的例子。
為了進行內(nèi)存分配替換,你需要通過 valgrind 運行要分析的程序(此處為PHP),也就是啟動 valgrind 二進制文件。
當 valgrind 替換并跟蹤所有 libc 的堆分配時,它往往會大大降低調(diào)試程序的速度。對于PHP,你會注意到它。盡管 PHP 的速度下降并不那么劇烈,但是仍然可以清楚地感覺到;如果你注意到它,不用擔心,這是正常的。
Valgrind 不是你可能會使用的唯一工具,但是是最常用的工具。還有其他工具,例如 Dr.Memory、LeakSanitizer、Electric Fence、AddressSanitizer。
在開始之前
以下是在存儲器調(diào)試方面具有良好經(jīng)驗并減輕發(fā)現(xiàn)缺陷并減少調(diào)試時間的機會所需的步驟:
-您應始終使用PHP的調(diào)試版本。嘗試調(diào)試生產(chǎn)版本中的內(nèi)存是無關緊要的。
-您應該始終在 USE_ZEND_ALLOC = 0 環(huán)境下啟動調(diào)試器。您可能已經(jīng)在Zend Memory Manager章節(jié)中了解到,此環(huán)境var會在當前進程啟動時禁用ZendMM。強烈建議在啟動內(nèi)存調(diào)試器時這樣做。完全繞過ZendMM有助于了解valgrind生成的跟蹤。
-強烈建議在環(huán)境 ZEND_DONT_UNLOAD_MODULES = 1 下啟動內(nèi)存調(diào)試器。這樣可以防止PHP在過程結(jié)束時卸載擴展程序的.so文件。這是為了獲得更好的valgrind報告跟蹤;如果在valgrind將要顯示其錯誤時PHP將卸載擴展名,則稍后將不完整,因為從中獲取信息的文件不再是進程內(nèi)存映像的一部分。
-您可能需要一些抑制措施。當您告訴PHP在過程結(jié)束時不要卸載其擴展名時,可能會在valgrind輸出中給您誤報。將檢查PHP擴展是否泄漏,如果您在平臺上誤報,則可以使用抑制功能將其關閉像這樣??梢愿鶕?jù)這樣的示例隨意編寫自己的文件。
-與Zend Memory Manager相比,Valgrind顯然是更好的工具,可以查找泄漏和其他與內(nèi)存相關的問題。您應該始終在代碼上運行valgrind,這實際上是每個C程序員都必須執(zhí)行的步驟。無論是因為崩潰而想要找到并調(diào)試它,還是作為看起來好像沒有任何壞處的高質(zhì)量工具來運行它,valgrind都是這種工具,它可以指出隱藏的瑕疵,準備好將其吹拂一次或以后。即使您認為代碼似乎一切都很好,也可以使用它:您可能會感到驚訝。
Warning
您**必須在程序上使用valgrind(或任何內(nèi)存調(diào)試器)。對于每個強大的C程序,要不調(diào)試內(nèi)存就不可能100%充滿信心。內(nèi)存錯誤會導致有害的安全問題,并且程序崩潰通常取決于許多參數(shù),通常是隨機的。
內(nèi)存泄漏檢測示例
入門
Valgrind是一個完整的堆內(nèi)存調(diào)試器。它還可以調(diào)試過程內(nèi)存映射和功能堆棧。請在其文檔中獲取