2008-11-25 65 views
11

我們有一個服務器(用C和C++編寫),它目前捕獲一個SEGV並將一些內部信息轉儲到一個文件中。我想生成一個核心文件,並在抓到SEGV時將其寫入磁盤,因此我們的支持代表和客戶不必大驚小怪,然後等待崩潰再次發生,以便獲得核心文件。過去我們使用了中止函數,但它受到ulimit規則的約束,並沒有幫助。什麼是從進程內部轉儲Linux核心文件的好方法?

我們有一些遺留代碼讀取/ proc/pid/map並手動生成核心文件,但它已過時,並且看起來不太可移植(例如,我猜測它不起作用在我們的64位版本中)。在Linux進程中生成和轉儲核心文件的最佳方式是什麼?

+0

我懷疑這是可能的,當ulimit規則禁止創建coredumps – 2008-11-25 20:02:02

回答

8

Google有一個庫,用於從正在運行的進程中生成一個叫做google-coredumper的內核。這應該忽略ulimit和其他機制。

生成核心文件的調用文檔是here。根據文檔,似乎可以在信號處理程序中生成核心文件,但不能保證始終有效。

+0

這看起來很有希望!明天我會試一試。 – 2008-12-04 01:55:40

3

一些可能的解決方案處理這種情況的^ W方式:

  1. 修復的ulimit!
  2. 接受你沒有得到核心文件並在gdb內部運行,編寫腳本在SIGSEGV上執行「線程全部應用bt」
  3. 接受你沒有得到核心文件並從內部獲取堆棧跟蹤應用程序。 Stack Backtracing Inside Your Program文章相當古老,但現在也應該有可能。
+0

感謝您的鏈接回溯。 1和2我們目前在幫助客戶時做的事情,但我正在尋找一種更加自動化的檢索核心文件的方式。在Windows中,我們調用一個生成轉儲文件的API並且可以自動檢索它。我想在我們的Linux版本中使用類似的東西。 – 2008-11-26 14:49:06

4

嘗試使用Linux命令的gcore

使用功能:gcore [-o文件名]的pid

你需要使用的系統(或執行)和GETPID()建立正確的命令從您的過程中調用它

5

我看到pmbrett's post,並認爲「嘿,這很酷」,但無法找到我的系統(Gentoo)上的任何地方的實用工具。

所以我做了一點刺激,發現GDB有這個選項。

gdb --pid=4049 --batch -ex gcore

似乎爲我工作得很好。

它並不是非常有用,因爲它捕捉當時正在使用的最低功能,但它在外面仍然做得很好(沒有內存限制,用它丟棄了350M的Firefox進程快照)

+2

僅供參考,「linux」命令'gcore'實際上是一個RedHat linux命令。它是一個調用gdb並使用gdb的gcore命令生成核心文件的bourne shell腳本。 – 2009-10-28 20:41:30

1

您還可以使用setrlimit(2)從程序中更改ulimit()。像ulimit shell命令一樣,這可以降低限制,或者像硬限制允許的那樣儘可能地提高限制。在啓動setrlimit()允許核心轉儲,你沒事。

0

系統(「殺-6」)

我給它一個嘗試,如果你還在尋找的東西

0

使用回溯和backtrace_symbols glibc的呼籲得到的痕跡,只是記住, backtrace_symbols在內部使用malloc,如果發生堆損壞,它可能會失敗。

1

我假設你有一個捕獲SEGV的信號處理程序,例如,打印一條消息並調用_exit()。 (否則,你首先會有一個核心文件!)你可以做如下的事情。

void my_handler(int sig) 
{ 
    ... 
    if (wantCore_ && !fork()) { 
     setrlimit(...); // ulimit -Sc unlimited 
     sigset(sig, SIG_DFL); // reset default handler 
     raise(sig); // doesn't return, generates a core file 
    } 
    _exit(1); 
} 
相關問題