github.com/searKing/golang/go@v1.2.74/os/signal/cgo/base_signal_handler.hpp (about) 1 // Copyright (c) 2019 The searKing authors. All Rights Reserved. 2 // 3 // Use of this source code is governed by a MIT-style license 4 // that can be found in the LICENSE file in the root of the source 5 // tree. An additional intellectual property rights grant can be found 6 // in the file PATENTS. All contributing project authors may 7 // be found in the AUTHORS file in the root of the source tree. 8 9 // +build cgo 10 11 #ifndef GO_OS_SIGNAL_CGO_BASE_SIGNAL_HANDLER_HPP_ 12 #define GO_OS_SIGNAL_CGO_BASE_SIGNAL_HANDLER_HPP_ 13 #include <boost/core/noncopyable.hpp> 14 #include <boost/stacktrace.hpp> 15 #include <cstdio> 16 #include <cstring> 17 #include <fstream> 18 #include <map> 19 #include <memory> 20 #include <sstream> 21 #include <string> 22 #include <tuple> 23 24 #include "write_int.hpp" 25 26 namespace searking { 27 template <class T> 28 class BaseSignalHandler : private boost::noncopyable, 29 public std::enable_shared_from_this<T> { 30 protected: 31 BaseSignalHandler() : signal_dump_to_fd_(-1) {} 32 33 public: 34 void SetSignalDumpToFd(int fd) { signal_dump_to_fd_ = fd; } 35 36 void SetSignalDumpToFd(FILE *fd) { SetSignalDumpToFd(fileno(fd)); } 37 38 void SetStacktraceDumpToFile(const std::string &name) { 39 stacktrace_dump_to_file_ = name; 40 } 41 42 void WriteSignalStacktrace(int signum) { 43 if (signal_dump_to_fd_ >= 0) { 44 write(signal_dump_to_fd_, "Signal received(", strlen("Signal received(")); 45 WriteInt(signal_dump_to_fd_, signum); 46 write(signal_dump_to_fd_, ").\n", strlen(").\n")); 47 // binary format,not human readable.mute this. 48 // write(signal_dump_to_fd_, "stacktrace dumped in binary format:\n", 49 // strlen("stacktrace dumped in binary format:\n")); 50 // boost::stacktrace::safe_dump_to(signal_dump_to_fd_); 51 // write(signal_dump_to_fd_, "\n", strlen("\n")); 52 } 53 54 if (!stacktrace_dump_to_file_.empty()) { 55 if (signal_dump_to_fd_ >= 0) { 56 write(signal_dump_to_fd_, "Stacktrace dumped to file: ", 57 strlen("Stacktrace dumped to file: ")); 58 write(signal_dump_to_fd_, stacktrace_dump_to_file_.c_str(), 59 stacktrace_dump_to_file_.length()); 60 write(signal_dump_to_fd_, ".\n", strlen(".\n")); 61 } 62 boost::stacktrace::safe_dump_to(stacktrace_dump_to_file_.c_str()); 63 } 64 } 65 66 ssize_t DumpPreviousStacktrace() { 67 if (signal_dump_to_fd_ < 0) { 68 return 0; 69 } 70 71 std::ostringstream msg; 72 msg << "Previous run crashed:" << std::endl; 73 msg << PreviousStacktrace(); 74 75 auto m = msg.str(); 76 return write(signal_dump_to_fd_, m.c_str(), m.length()); 77 } 78 std::string PreviousStacktrace() { 79 if (stacktrace_dump_to_file_.empty()) { 80 return ""; 81 } 82 83 std::ifstream ifs(stacktrace_dump_to_file_); 84 if (!ifs.good()) { 85 return ""; 86 } 87 88 std::shared_ptr<int> deferFileCLose(nullptr, [&ifs](int *) { 89 // cleaning up 90 ifs.close(); 91 }); 92 93 // there is a backtrace 94 boost::stacktrace::stacktrace st = 95 boost::stacktrace::stacktrace::from_dump(ifs); 96 std::ostringstream msg; 97 98 msg << st << std::endl; 99 return msg.str(); 100 } 101 102 void SetSigInvokeChain(const int from, const int to, const int wait, 103 const int sleepInSeconds) { 104 sig_invoke_signal_chains_[from] = 105 std::make_tuple(from, to, wait, sleepInSeconds); 106 } 107 108 void SetSigInvokeChain(const int from, const int pipeWriter, 109 const int pipeReader) { 110 sig_invoke_pipe_chains_[from] = 111 std::make_tuple(from, pipeWriter, pipeReader); 112 } 113 114 protected: 115 int signal_dump_to_fd_; 116 std::string stacktrace_dump_to_file_; 117 // <from, <from, to, wait, sleepInSeconds>> 118 std::map<int, std::tuple<int, int, int, int>> sig_invoke_signal_chains_; 119 120 // <from, <from, pipeWriter, pipeReader>> 121 std::map<int, std::tuple<int, int, int>> sig_invoke_pipe_chains_; 122 }; 123 } // namespace searking 124 #endif // GO_OS_SIGNAL_CGO_BASE_SIGNAL_HANDLER_HPP_