2012-07-31 22 views
4

我有一個多線程的程序在一兩天後崩潰。此外,核心轉儲的gdb回溯不會導致任何地方。在它崩潰的地方沒有符號。爲什麼核心文件不僅僅是虛擬內存?

現在生成核心文件的計算機具有3 Gig和5 Gig交換空間的物理內存。但我們得到的核心轉儲大約是25 Gig。是不是核心轉儲實際內存轉儲?爲什麼核心轉儲很大?

誰能給我更多的關於如何在這種情況下調試的線索?

回答

3

如果您正在運行64位操作系統,那麼您可以擁有超過可用物理內存+交換空間量多倍的文件支持映射。

由於內核版本2.6.23,Linux提供了一種機制來控制包含在覈心轉儲文件中的內容,稱爲核心轉儲過濾器。過濾器的值是一個位域通過/proc/<pid>/coredump_filter文件操作(見core(5)手冊頁):

  • 位0(0x01) - 匿名私有映射(如動態分配的內存)
  • 位1(0x02 ) - 匿名共享映射
  • 2位(0x04) - 文件後備私人映射
  • 位3(0x08) - 文件支持共享映射(例如共享庫)
  • 第4位(0x10) - ELF頭
  • 5位(0x20) - 私人巨大頁
  • 6位(0x40) - 共享

默認值爲0x33其對應於傾倒所有匿名映射以及巨大的網頁ELF頭文件(但只有在內核編譯時使用CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS)和私人大頁面。從該文件讀取將返回過濾器的十六進制值。將新的十六進制值寫入coredump_filter將更改特定過程的過濾器,例如以使得一個將所有可能的映射的轉儲:

echo 0x7f > /proc/<pid>/coredump_filter 

(其中<pid>是過程的PID)

核心轉儲濾波器的值在由fork()創建的子進程被iherited。

某些Linux發行版可能會在操作系統啓動階段早期更改init進程的過濾器值,例如,啓用轉儲文件支持的映射。這會影響後來開始的任何進程。

+0

'cat/proc//coredump_filter'給出00000003.文件支持的私有/共享映射未啓用,對吧?你能給我任何解釋文件支持映射的鏈接嗎?另外,我在64位操作系統上運行 – 2012-07-31 09:19:25

+0

請參閱'mmap(2)'手冊頁。但是,可能你的某個庫的程序會執行非常大的虛擬分配,這些分配並未被觸及,例如'malloc(16GiB)'然後只觸摸它的一小部分。 – 2012-07-31 10:15:54

+0

這是一個壓力測試,即使它不是一個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

2

核心轉儲包含的不僅僅是進程的內存狀態。有關核心轉儲中包含的其他信息(在Linux上)的示例,請參閱https://stackoverflow.com/a/5321564/91757的答案。

+0

特別是,它將任何文件[映射](http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html)的內容包含到進程的地址空間中。這將至少是它使用的可執行文件和所有共享庫,而且應用程序也可能映射了其他文件。 – Wyzard 2012-07-31 07:23:28

+0

但17 GiB更多...是不是隻是有點太多? – 2012-07-31 07:29:56

+0

也許它有一些大型文件映射。程序運行時檢查'/ proc/$ {pid}/maps'。 – Wyzard 2012-08-01 00:46:12

相關問題