天天看點

boost stacktrace堆棧列印

在windows下最友善的是minidump,其他2個平台麻煩不少,google-breakpad使用起來又太麻煩.

最近boost1.65版本出了個stacktrace使用起來簡單友善,隻是無法看實際資料,對于快速定位BUG還是很有幫助的.

要注意的是異常的處理需要寫檔案,應用重新開機之後再讀取檢視~  用其他應用讀取或者修改應用之後讀取都會無法正确顯示!!!

boost stacktrace堆棧列印
boost stacktrace堆棧列印
1 #pragma once
 2 //異常生成dump時立刻檢視會死鎖,隻能重新開機應用後才能檢視
 3 
 4 #ifndef BOOST_ENABLE_ASSERT_DEBUG_HANDLER
 5 #define BOOST_ENABLE_ASSERT_DEBUG_HANDLER
 6 #endif
 7 
 8 #include <string>
 9 #include <boost/noncopyable.hpp>
10 #include <boost/function.hpp>
11 #include <boost/stacktrace.hpp>
12 
13 class plugin_dump : 
14     private boost::noncopyable
15 {
16 public:
17     plugin_dump();
18     ~plugin_dump();
19 
20     //顯示dump資訊回調
21     typedef boost::function1<void, const boost::stacktrace::stacktrace&> ON_DUMP;
22 
23     void set_handler(ON_DUMP _handler);
24 
25     static std::string gen_filename();
26 private:
27     void show_last_dump();
28     ON_DUMP m_handler;
29 };      
boost stacktrace堆棧列印
boost stacktrace堆棧列印
boost stacktrace堆棧列印
1 #include "stdafx.h"
 2 #include "plugin_dump.h"
 3 
 4 #include <signal.h>     // ::signal, ::raise
 5 #include <strstream>
 6 #include <stdexcept>    // std::logic_error
 7 #include <iostream>     // std::cerr
 8 #include <boost/filesystem.hpp>
 9 #include <enable_process_info.hpp>
10 
11 void g_signal_handler(int signum) {
12     ::signal(signum, SIG_DFL);    
13     std::string filename = plugin_dump::gen_filename();
14     if (boost::filesystem::exists(filename.c_str()))
15         boost::filesystem::remove(filename.c_str());
16     boost::stacktrace::safe_dump_to(3, boost::stacktrace::detail::max_frames_dump, filename.c_str());
17     ::raise(SIGABRT);
18 }
19 
20 plugin_dump::plugin_dump()
21 {
22     ::signal(SIGSEGV, &g_signal_handler);
23     ::signal(SIGABRT, &g_signal_handler);
24     if (!boost::filesystem::exists("./dumps"))
25         boost::filesystem::create_directory("./dumps");
26 }
27 
28 plugin_dump::~plugin_dump()
29 {    
30     
31 }
32 
33 void plugin_dump::set_handler(ON_DUMP _handler)
34 {
35     m_handler = _handler;
36     show_last_dump();
37 }
38 
39 void plugin_dump::show_last_dump()
40 {
41     std::string filename = plugin_dump::gen_filename();
42     if (boost::filesystem::exists(filename.c_str())) {
43 
44         std::ifstream ifs(filename.c_str());
45         boost::stacktrace::stacktrace st = boost::stacktrace::stacktrace::from_dump(ifs);
46 
47         if (!m_handler.empty())
48             m_handler(st);
49         else
50             std::cout << st;
51 
52         ifs.close();
53         std::getchar();
54     }
55 }
56 
57 std::string plugin_dump::gen_filename()
58 {
59     std::string file = "./dumps/" + enable_process_info::get_processname() + ".dump";
60     return file;
61 }
62 
63 //
64 // BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined for the whole project
65 namespace boost {
66     inline void assertion_failed_msg(char const* expr, char const* msg, char const* function, char const* /*file*/, long /*line*/) {
67         std::cerr << "Expression '" << expr << "' is false in function '" << function << "': " << (msg ? msg : "<...>") << ".\n"
68             << "Backtrace:\n" << boost::stacktrace::stacktrace() << '\n';
69         std::abort();
70     }
71 
72     inline void assertion_failed(char const* expr, char const* function, char const* file, long line) {
73         ::boost::assertion_failed_msg(expr, 0 /*nullptr*/, function, file, line);
74     }
75 } // namespace boost      
boost stacktrace堆棧列印
boost stacktrace堆棧列印