Crash Reporting

PM2 looks really nice! I think that with a little wrapper that could do the heartbeat / google analytics things that AMPM does will be something I look into in the future.

About the C++ asserts to log trick: it’s basically a combination of a few pieces:

  1. Override the CinderMswUserDefines.h file as described here and add the lines:
//! This allows us to define our own assertion handlers (in psCommon.cpp)
#define CI_ENABLE_ASSERTS
#define CI_ENABLE_ASSERT_HANDLER
  1. Add some custom assert functions that only log at the FATAL level but don’t abort:
// Our own handlers for assertions which print fatal messages instead.
// CI_LOG_F() will cause the breakpoint to be hit when in non-production mode.
namespace cinder {
//! Called when CI_ASSERT() fails
void assertionFailed( char const *expr, char const *function, char const *file, long line )
{
	CI_LOG_F( "*** [nw] Assertion Failed *** | expression: ( " << expr << " ), location: " << file << "[" << line << "], " << function );
}

//! Called when CI_ASSERT_MSG() fails
void assertionFailedMessage( char const *expr, char const *msg, char const *function, char const *file, long line )
{
	CI_LOG_F( "*** [nw] Assertion Failed *** | expression: ( " << expr << " ), location: " << file << "[" << line << "], " << function << "\n\tmessage: " );
}

} // namespace cinder
  1. Enable file logging and also the LoggerBreakpoint with at least a level of FATAL:
log::makeOrGetLogger<log::LoggerFileRotating>( "logs", "YourApp.%Y.%m.%d_%H.%M.%S.log" );
log::makeOrGetLogger<log::LoggerBreakpoint>()->setTriggerLevel( log::Level::LEVEL_FATAL );

On Posix this is a tad easier, you can skip the CinderMswDefines.h step and just build everything on the command line with those same additional #defines.

After this, if you get an assertion failure in either Debug or Release, you’ll first get a message logged to file, and then a break into the debugger. When you are running outside of a debugger, you’ll just get the message logged to file after which the routine will carry on as if there was no assertion failure.

This covers you for lots of things like a std::vector out of bounds and asserting, which would other wise end in the app log saying “we aborted”, or maybe nothing at all. The other thing I’ve been trying to catch and (safely) log are things like SIGFPE or SIGABRT, but haven’t yet figured that out…

cheers,
Rich