2017-08-09 201 views
1

有沒有辦法獲得有關爲什麼程序在某些非常小的linux上無法插入任何日誌並且沒有pstack和gdb時卡住的信息?如何在沒有pstack和gdb的情況下獲得線程堆棧信息

+0

可能的重複[獲取所有線程的堆棧跟蹤而不附加GDB](https://stackoverflow.com/questions/12394935/getting-stacktrace-of-all-threads-without-attaching-gdb) –

+0

不是重複的,因爲當我沒有gdb或pstack時,我會特別提問。 – YotKay

回答

0

我的建議是做到以下幾點:

  1. 能夠自己的程序
  2. 內檢索操作和打印堆棧跟蹤安裝一個信號處理器(比方說,對於SIGUSR1)爲您的流程它會這樣做
  3. 發送信號到你的程序當它卡住了 - 控制將被移動到信號處理程序(假設你沒有屏蔽掉信號)。

現在(2.)和(3.)很簡單。對於(3.)它是kill -USR1 1234(對於ID爲1234的進程)。對於(2.),它是:

#include <signal.h> 
typedef void (*sighandler_t)(int); 
sighandler_t sigset(int sig, sighandler_t disp); 

(閱讀man sigset瞭解詳情)。

至於(1),這裏曾經是相當困難和棘手,但現在它已經基本解決:

升壓堆棧跟蹤Code | Documentation

它會盡可能獲得儘可能多的堆棧跟蹤信息。使用的一個簡單的例子:

#include <iostream> 
#include <boost/stacktrace.hpp> 

// ... somewhere inside the `bar(int)` function that is called recursively: 
std::cout << boost::stacktrace::stacktrace(); 

可能會導致下面的輸出:

0# bar(int) at /path/to/source/file.cpp:70 
1# bar(int) at /path/to/source/file.cpp:70 
2# bar(int) at /path/to/source/file.cpp:70 
3# bar(int) at /path/to/source/file.cpp:70 
4# main at /path/to/main.cpp:93 
5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6 
6# _start 

注:棧跟蹤是最近除了升壓(如2017年8月的);如果你的Boost版本不夠新,你可以考慮獨立獲取它。

+0

但爲了使用它,我必須修改源代碼。我不知道我的程序在哪個地方掛起。我應該在哪裏放置這些代碼?到處? – YotKay

+0

@YotKay:你應該閱讀文檔;並有幾個選項。一個是有一個信號處理程序用於分段違規。另一種方法是拋出包含堆棧跟蹤的異常,並在一個(或幾個)地方捕獲它們。 – einpoklum

+0

我承認,我絕對應該閱讀文檔。但我認爲我們誤解了對方。我的程序掛在某處,這並不意味着它崩潰。它等待一些條件變量或類似的東西。我需要找出在哪裏。你的解決方案並不能幫助我,因爲我不知道該怎麼拋出你提到的異常等。 – YotKay

相關問題