如何找到正在運行的進程的記憶體洩漏?

如何找到正在運行的進程的記憶體洩漏?

有沒有辦法可以找到正在運行的進程的記憶體洩漏?我可以使用 Valgrind 在進程啟動之前查找記憶體洩漏。我可以使用 GDB 將其附加到正在運行的進程。如何調試正在運行的進程的記憶體洩漏?

答案1

以下是幾乎可以保證找到記憶體洩漏的步驟:

  1. 找出導致記憶體洩漏的進程的PID。

    ps -aux
    
  2. 捕獲/proc/PID/smaps並保存到某個文件中,例如BeforeMemInc.txt.

  3. 等到記憶體增加了。
  4. 再次捕獲/proc/PID/smaps並保存它afterMemInc.txt
  5. smaps找出第一個和第二個之間的差異smaps,例如

    diff -u beforeMemInc.txt afterMemInc.txt

  6. 記下記憶體增加的位址範圍,例如:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
    
  7. 使用 GDB 轉儲正在運行的進程的記憶體或使用以下命令獲取核心轉儲gcore -o process

  8. 我在運行進程中使用 gdb 將記憶體轉儲到某個檔案。

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
    
  9. 現在,使用strings命令或hexdump -C列印dump_outputfile.dump

    strings outputfile.dump
    
  10. 您將獲得可讀的形式,您可以在其中將這些字串定位到原始程式碼中。

  11. 分析您的來源以查找洩漏。

答案2

我認為記憶力正是你想要的。

它透過附加正在運行的進程來偵錯記憶體洩漏,無需重新編譯程式或重新啟動目標進程。非常方便,適合生產環境。

它適用於 GNU/Linux 和 FreeBSD。

筆記:我是作者,有什麼建議歡迎留言。

==編輯==

我還寫了另一個工具利布拉克,它通過 LD_PRELOAD 掛鉤內存函數。

無需修改目標程式。雖然您必須使用 LD_PRELOAD 重新啟動進程,但您可以在運行期間啟用/停用檢測。

由於沒有訊號陷阱,對性能的影響要小得多。

與類似工具(例如 mtrace)相比,它在可疑記憶體洩漏點列印完整的呼叫堆疊。

答案3

在 Linux 上,您可以啟用追蹤在你的程式中,但這是一個程式碼更改。

在 OpenBSD 上,你可以嘗試malloc 統計訊息

谷歌的洩漏檢查器也可能值得一看,與 mtrace 不同,您可以使用它LD_PRELOAD來避免重新編譯。

答案4

IBM的淨化可能是所有工具中最古老、最複雜的工具。它將標記程式碼中導致記憶體洩漏的行號。

相關內容