1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#ifndef SUPPORT_ASSERT_CHECKPOINT_H
#define SUPPORT_ASSERT_CHECKPOINT_H
#include <csignal>
#include <cstdlib>
#include <iostream>
struct Checkpoint
{
const char* file;
const char* func;
int line;
const char* msg;
Checkpoint()
: file(nullptr)
, func(nullptr)
, line(-1)
, msg(nullptr)
{}
Checkpoint(const char* xfile, const char* xfunc, int xline, const char* xmsg)
: file(xfile)
, func(xfunc)
, line(xline)
, msg(xmsg)
{}
template <class Stream>
void print(Stream& s) const
{
if (!file)
{
s << "NO CHECKPOINT\n";
return;
}
s << file << ":" << line << " " << func << ": Checkpoint";
if (msg)
{
s << " '" << msg << "'";
}
s << std::endl;
}
};
inline Checkpoint& globalCheckpoint()
{
static Checkpoint C;
return C;
}
inline void clearCheckpoint()
{
globalCheckpoint() = Checkpoint();
}
#if defined(__GNUC__)
# define CHECKPOINT_FUNCTION_NAME __PRETTY_FUNCTION__
#else
# define CHECKPOINT_FUNCTION_NAME __func__
#endif
#define CHECKPOINT(msg) globalCheckpoint() = Checkpoint(__FILE__, CHECKPOINT_FUNCTION_NAME, __LINE__, msg);
inline void checkpointSignalHandler(int signal)
{
if (signal == SIGABRT)
{
globalCheckpoint().print(std::cerr);
}
else
{
std::cerr << "Unexpected signal " << signal << " received\n";
}
std::_Exit(EXIT_FAILURE);
}
inline bool initCheckpointHandler()
{
typedef void (*HandlerT)(int);
static bool isInit = false;
if (isInit)
{
return true;
}
HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler);
if (prev_h == SIG_ERR)
{
std::cerr << "Setup failed.\n";
std::_Exit(EXIT_FAILURE);
}
isInit = true;
return false;
}
static bool initDummy = initCheckpointHandler();
#endif
|