2011-06-07 138 views
4

我可以利用海灣合作委員會的回溯在程序的任何給定點獲得堆棧跟蹤,但我想從堆棧在引發異常時的任何幀中獲得跟蹤,即在堆棧之前平倉。從函數C++ stacktrace引發異常?

例如,下面的塊

func() { 
    throw std::exception(); 
} 

try { 
    func(); 
} 
catch (std::exception) { 
    std::cout << print_trace(); 
    //do stuff 
} 

應該仍然能夠保留FUNC幀()以某種方式。

這一直是asked before,但它涉及一個未處理的異常,可能會終止程序,並可能不會給調用堆棧放鬆的機會?

有沒有辦法做到這一點,但仍然能夠捕捉和處理異常通常?

可能有一種方法,如爲所有異常處理程序,除了生成跟蹤並重新拋出異常外什麼也不做。理想情況下,我應該能夠在Exception類的構造函數中生成跟蹤,但在這裏我不一定能夠控制可能遇到的異常。

+5

如果您想知道拋出異常的位置,最好的辦法是將該信息存儲在異常中。 – 2011-06-07 20:22:36

回答

4

您可能對開發中的Boost庫感興趣:Portable Backtrace。例如:

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

int foo() 
{ 
    throw boost::runtime_error("My Error"); 
    return 10; 
} 

int bar() 
{ 
    return foo()+20; 
} 


int main() 
{ 
    try { 
     std::cout << bar() << std::endl; 
    } 
    catch(std::exception const &e) 
    { 
     std::cerr << e.what() << std::endl; 
     std::cerr << boost::trace(e); 
    } 
} 

打印:

My Error 
0x403fe1: boost::stack_trace::trace(void**, int) + 0x1b in ./test_backtrace 
0x405451: boost::backtrace::backtrace(unsigned long) + 0x65 in ./test_backtrace 
0x4054d2: boost::runtime_error::runtime_error(std::string const&) + 0x32 in ./test_backtrace 
0x40417e: foo() + 0x44 in ./test_backtrace 
0x40425c: bar() + 0x9 in ./test_backtrace 
0x404271: main + 0x10 in ./test_backtrace 
0x7fd612ecd1a6: __libc_start_main + 0xe6 in /lib/libc.so.6 
0x403b39: __gxx_personality_v0 + 0x99 in ./test_backtrace 

希望這有助於!

+0

幾乎在那裏,但並不完全......我只能指望從boost提升異常中獲得痕跡,不會對std :: bad_alloc等其他人做任何事情。太糟糕的痕跡不會嵌入到標準中在java中的異常類! – maldoz 2011-06-08 05:45:41

+0

@maldoz不是每個人都需要回溯。但我同意它可能有用 – 2011-06-08 07:02:21