2011-07-25 59 views
1

我正在使用epoll進行聯網編程。我遇到了分段錯誤錯誤,但由於它在多線程上運行,因此很難通過使用日誌找到它確切地獲取錯誤的位置。如何使用gdb進行多線程聯網程序

我想使用gdb,所以我可以看到堆棧跟蹤。如果我在gdb上運行這個,那麼我從epoll_wait得到這個錯誤。如果我從不同的客戶端連接到服務器,那麼它根本不起作用。

我該如何解決這個問題,所以我可以使用gdb來找出它得到分段錯誤 在此先感謝..

epoll_wait error 
: Interrupted system call 
+0

你在C或C++嗎? – Puppy

回答

3

您需要修復程序以正確處理EINTR。 EINTR(「中斷系統調用」)不是致命錯誤;它只是意味着「請重試該系統調用」。因此,調用epoll_wait()的代碼應該檢測到它,然後只是默默地重試該調用。事情是這樣的:

int rv; 
do { 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} while (rv == -1 && errno == EINTR); 

或者,如果你有一個固定的超時時間,你需要重新計算每一個電話:

int rv; 
rv = epoll_wait(epfd, events, maxevents, timeout); 
while (rv == -1 && errno == EINTR) { 
    ...TODO: recalculate timeout here... 
    rv = epoll_wait(epfd, events, maxevents, timeout); 
} 

如果你不知道這個沒有,你可能在相同的錯誤您對其他系統呼叫的呼叫。特別是read()和write(),還有很多其他的調用 - 檢查你使用的調用的手冊頁,看看他們是否將EINTR列爲可能的錯誤。如果你使用任何使用信號的庫,或者如果你自己使用信號,那麼你可以得到EINTR,這通常是不切實際的。上次我查看時,Linux線程庫使用了信號。

2

啓用核心轉儲在您的環境中保存。運行命令ulimit -c unlimited並重新運行您的程序。當它崩潰時,在gdb中加載生成的核心轉儲並查看崩潰的後退。在多線程程序的情況下,一次只能通過一個命令從所有線程獲得回溯:(gdb) thread apply all bt