Crash Reporting

Does anyone have a method they like for cross platform crash reporting? I’ve got an app deployed in the wild and I’d love to automate crash feedback.

C

Been using ampm along with in-app log statements (file logging + timestamps enabled) for this purpose myself, although there are some services that will let you send off a crash dump and (presumably) debug it with your local toolset.

One key for me has been some cpp trickery to make asserts log to file, so if something like a vector or map blows up, I can still get a stack trace.

We have been using PM2. it has some nice memory statistics, but you need to be careful with process priority configuration. An app was running slower when lunched from pm2, and we had to dig around a bit to find the right config.

@rich.e, can you elaborate a bit on the c++ trickery? that sounds super useful!

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