C++サーバー(Linux)が落ちるバグで悩まされたので、セグメンテーションフォールトを補足してログを吐く機能を作ってみた。
- CrashReporter.hpp
#pragma once
class ICrashReporter
{
public:
virtual void CrashReport() = 0;
};
class CCrashReporter
{
public:
static void Setup();
static void AddReporter(ICrashReporter*);
static void Start();
};
- CrashReporter.cpp
#include "crashreporter.hpp"
#include <signal.h>
#include <unistd.h>
#include <vector>
#include <thread>
#include <csignal>
volatile std::sig_atomic_t _crashed = 0;
std::vector<ICrashReporter*> _reporters;
static void segv_handler(int sig)
{
_crashed = 1;
}
static void check_crash()
{
if (_crashed)
{
printf("***** CRASH REPORT *****\n");
for (ICrashReporter* reporter : _reporters)
{
reporter->CrashReport();
}
printf("************************\n");
signal(SIGSEGV, SIG_DFL);
kill(getpid(), SIGSEGV);
}
}
void CCrashReporter::Setup()
{
signal(SIGSEGV, segv_handler);
}
void CCrashReporter::AddReporter(ICrashReporter* reporter)
{
_reporters.push_back(reporter);
}
void CCrashReporter::Start()
{
std::thread th([]()
{
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
check_crash();
}
});
th.detach();
}
- 使い方
class Hoge : public ICrashReporter
{
public:
virtual void CrashReport() override {
printf("吐きたいログ\n");
}
};
int main()
{
CCrashReporter::Setup();
auto hoge = new CHoge();
CCrashReporter::AddReporter(hoge);
CCrashReporter::Start();
//hogeを使った処理...
return 0;
}