我有一個多線程的程序在一兩天後崩潰。此外,核心轉儲的gdb回溯不會導致任何地方。在它崩潰的地方沒有符號。爲什麼核心文件不僅僅是虛擬內存?
現在生成核心文件的計算機具有3 Gig和5 Gig交換空間的物理內存。但我們得到的核心轉儲大約是25 Gig。是不是核心轉儲實際內存轉儲?爲什麼核心轉儲很大?
誰能給我更多的關於如何在這種情況下調試的線索?
我有一個多線程的程序在一兩天後崩潰。此外,核心轉儲的gdb回溯不會導致任何地方。在它崩潰的地方沒有符號。爲什麼核心文件不僅僅是虛擬內存?
現在生成核心文件的計算機具有3 Gig和5 Gig交換空間的物理內存。但我們得到的核心轉儲大約是25 Gig。是不是核心轉儲實際內存轉儲?爲什麼核心轉儲很大?
誰能給我更多的關於如何在這種情況下調試的線索?
如果您正在運行64位操作系統,那麼您可以擁有超過可用物理內存+交換空間量多倍的文件支持映射。
由於內核版本2.6.23,Linux提供了一種機制來控制包含在覈心轉儲文件中的內容,稱爲核心轉儲過濾器。過濾器的值是一個位域通過/proc/<pid>/coredump_filter
文件操作(見core(5)
手冊頁):
0x01
) - 匿名私有映射(如動態分配的內存)0x02
) - 匿名共享映射0x04
) - 文件後備私人映射0x08
) - 文件支持共享映射(例如共享庫)0x10
) - ELF頭0x20
) - 私人巨大頁0x40
) - 共享默認值爲0x33
其對應於傾倒所有匿名映射以及巨大的網頁ELF頭文件(但只有在內核編譯時使用CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
)和私人大頁面。從該文件讀取將返回過濾器的十六進制值。將新的十六進制值寫入coredump_filter
將更改特定過程的過濾器,例如以使得一個將所有可能的映射的轉儲:
echo 0x7f > /proc/<pid>/coredump_filter
(其中<pid>
是過程的PID)
核心轉儲濾波器的值在由fork()
創建的子進程被iherited。
某些Linux發行版可能會在操作系統啓動階段早期更改init
進程的過濾器值,例如,啓用轉儲文件支持的映射。這會影響後來開始的任何進程。
核心轉儲包含的不僅僅是進程的內存狀態。有關核心轉儲中包含的其他信息(在Linux上)的示例,請參閱https://stackoverflow.com/a/5321564/91757的答案。
'cat/proc//coredump_filter'給出00000003.文件支持的私有/共享映射未啓用,對吧?你能給我任何解釋文件支持映射的鏈接嗎?另外,我在64位操作系統上運行 –
2012-07-31 09:19:25
請參閱'mmap(2)'手冊頁。但是,可能你的某個庫的程序會執行非常大的虛擬分配,這些分配並未被觸及,例如'malloc(16GiB)'然後只觸摸它的一小部分。 – 2012-07-31 10:15:54
這是一個壓力測試,即使它不是一個16GB malloc,也可能是1000MB的16MB malloc。 :) 你能告訴我這一點。當前程序正在運行VIRT 11.7 GB和RES 2.2 GB。交換幾乎是免費的(253312k使用總計5079032k)。所以休息(11.7-2.2)GB是一些文件支持的內存映射。 – 2012-07-31 11:05:01