2013-04-23 201 views
6

我正在開發一個作爲守護程序運行的高流量網絡C服務器應用程序。在某些情況下,應用程序崩潰(始終沒有核心)。我如何使用gdb調試正在運行的守護進程以找到生成SIGSEGV的地方?使用gdb調試正在運行的守護進程

解釋性說明:

  1. 我知道如何使用gdb來連接到使用附加命令

  2. 連接到過程後正在運行的進程,它停止。如果我運行然後「繼續」,如果程序沒有崩潰,gdb仍然被阻塞。如果我按CTRL-C,進程正在退出,我無法簡單地分離gdb。

所以問題是:有沒有辦法繼續進程沒有被卡住的gdb,但能夠分離如果進程沒有崩潰?

+0

您是否嘗試過改變coredump設置與例如'ulimit'命令?和/或運行調試版本?或者可能添加更多日誌記錄來縮小可能的崩潰位置? – 2013-04-23 12:16:00

+0

我試過所有的可能性。 該進程在Ubuntu服務器上作爲新貴服務運行,並在服務啓動時被setuid-ed給某個用戶。 limits.conf包含該用戶的nofile和core的無限值。 我在/etc/sysctl.conf中設置了fs.suid_dumpable和kernel.core_uses_pid 我添加了更多的日誌記錄,但是它是一個高流量的服務器,它會產生太多的輸出。 – 2013-04-23 12:19:06

回答

3

此頁面attach/detach表示detach命令將在gdb內工作。

如果您想要捕捉應用程序中的分段錯誤,您必須從調試器運行應用程序。然後當信號被捕獲時,您可以使用wherebt來查看應用程序的堆棧跟蹤。當然,你的應用程序出現故障後無法繼續使用,它應該如何恢復?如果您希望儘快觸發錯誤,您可以附加到正在運行的進程並再次等待調試器中的錯誤。

如果您想要在發生故障後進行堆棧跟蹤,那麼您確實需要一個核心文件,因爲不需要附加任何進程。現在,如果您的守護進程作爲系統的一部分啓動,則可能很難將配置轉儲到內核,而且您可能不希望其他應用程序在整個地方留下核心轉儲。所以我建議停止系統守護進程並在用戶空間中重新啓動它,然後您可以允許它轉儲核心。如果它作爲系統的一部分啓動真的非常重要,那麼請查看守護進程的啓動是否侷限於一個子外殼,並在該子外殼中使用ulimit -c來爲內核設置適當的最大大小傾倒。

+0

我知道,但是在運行「continue」命令後,退出gdb的唯一方法是按CTRL-C,這會停止正在運行的進程。 – 2013-04-23 12:25:48

+0

使用'detach'而不是'continue',然後使用'quit'。適用於我。 – 2013-04-23 12:56:21

+0

我明白了,但如果進程崩潰,我希望能夠獲得回溯。 – 2013-04-23 13:40:27

6

嘗試異步模式和 「繼續&」:

保存下面非stop.gdb

set target-async on 
set pagination off 
set non-stop on 

然後運行:

$ gdb -x non-top.gdb 
(gdb) !pgrep YOUR-DAEMON 
1234 
(gdb) attach 1234 
(gdb) continue -a & 
(gdb) 
+0

謝謝。我會嘗試這個,並會發布反饋。 – 2013-04-23 14:28:52