/** .============.* // M A K E / \* // C++ DEV / \* // E A S Y / \/ \* ++ ----------. \/\ .* \\ \ \ /\ /* \\ \ \ /* \\ \ \ /* -============'** Copyright (c) 2018 Hevake and contributors, all rights reserved.** This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox)* Use of this source code is governed by MIT license that can be found* in the LICENSE file in the root of the source tree. All contributing* project authors may be found in the CONTRIBUTORS.md file in the root* of the source tree.*/#include <signal.h>#include <cstring>#include <iostream>#include <sstream>#include <functional>#include <map>#include <tbox/base/log.h>#include <tbox/base/scope_exit.hpp>#include <tbox/base/backtrace.h>#define TBOX_USE_SIGACTIONint main(int argc, char **argv);namespace tbox {namespace main {extern void AbnormalExit();namespace {#ifdef TBOX_USE_SIGACTIONusing SignalHandler = struct sigaction;#elseusing SignalHandler = void (*) (int);#endifstd::map<int, SignalHandler> _old_handler_map;bool _is_recursion_call = false;#ifdef TBOX_USE_SIGACTIONvoid InvokeOldHandler(int signo, siginfo_t *siginfo, void *context)#elsevoid InvokeOldHandler(int signo)#endif{auto iter = _old_handler_map.find(signo);if (iter == _old_handler_map.end())return;const auto &old_handler = iter->second;#ifdef TBOX_USE_SIGACTIONif (old_handler.sa_flags & SA_SIGINFO) {if (old_handler.sa_sigaction)old_handler.sa_sigaction(signo, siginfo, context);} else {if (SIG_ERR != old_handler.sa_handler &&SIG_IGN != old_handler.sa_handler &&SIG_DFL != old_handler.sa_handler)old_handler.sa_handler(signo);}#elseif (SIG_ERR != old_handler &&SIG_IGN != old_handler &&SIG_DFL != old_handler)old_handler(signo);#endif}//! 处理程序运行异常信号#ifdef TBOX_USE_SIGACTIONvoid OnErrorSignal(int signo, siginfo_t *siginfo, void *context)#elsevoid OnErrorSignal(int signo)#endif{#ifdef TBOX_USE_SIGACTIONInvokeOldHandler(signo, siginfo, context);#elseInvokeOldHandler(signo);#endifif (!_is_recursion_call) {_is_recursion_call = true;LogFatal("Receive signal %d", signo);const std::string &stack_str = DumpBacktrace();LogFatal("main: <%p>\n-----call stack-----\n%s", ::main, stack_str.c_str());_is_recursion_call = false;} else {LogFatal("Recursion signal %d", signo);}AbnormalExit();}bool InstallSignal(int signo){SignalHandler old_handler;bool is_succ = false;#ifdef TBOX_USE_SIGACTIONstruct sigaction new_handler;memset(&new_handler, 0, sizeof(new_handler));sigemptyset(&new_handler.sa_mask);new_handler.sa_sigaction = OnErrorSignal;new_handler.sa_flags = SA_SIGINFO;ssize_t ret = ::sigaction(signo, &new_handler, &old_handler);is_succ = (ret != -1);#elseold_handler = ::signal(signo, OnErrorSignal);is_succ = (SIG_ERR != old_handler);#endif_old_handler_map[signo] = old_handler;return is_succ;}}void InstallErrorSignals(){//! 要禁止信号触发sigset_t new_sigmask, old_sigmask;sigfillset(&new_sigmask);sigprocmask(SIG_BLOCK, &new_sigmask, &old_sigmask);SetScopeExitAction([&] { sigprocmask(SIG_SETMASK, &old_sigmask, 0); });//! 注册信号处理函数InstallSignal(SIGSEGV);InstallSignal(SIGILL);InstallSignal(SIGABRT);InstallSignal(SIGBUS);InstallSignal(SIGFPE);InstallSignal(SIGSYS);}void UninstallErrorSignals(){//! 要禁止信号触发sigset_t new_sigmask, old_sigmask;sigfillset(&new_sigmask);sigprocmask(SIG_BLOCK, &new_sigmask, &old_sigmask);SetScopeExitAction([&] { sigprocmask(SIG_SETMASK, &old_sigmask, 0); });for (auto &item : _old_handler_map) {int signo = item.first;auto &old_handler = item.second;#ifdef TBOX_USE_SIGACTION::sigaction(signo, &old_handler, nullptr);#elseif (old_handler != SIG_ERR)::signal(signo, old_handler);#endif}_old_handler_map.clear();}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型