Tuesday, November 1, 2011

FAIL_FAST

In Windows 7 an new weapon in the fight against bugs was released in the form of RaiseFailFastException

In a world where Windows Error Reporting (WER) collects each crash and reports it with a minidump. FAIL_FAST is essential to finding and fixing bugs quickly. Instead of laboring for a repro, just open the minidump and it points to the line of code that failed and usually has enough state to determine the cause.

FAIL_FAST should be used to report bugs in code. Transient or environmental failures like no-memory or access-denied are not suited for reporting via FAIL_FAST, rather things like 'I do not understand this enum value' or 'I did not expect this error value'

#define FAIL_FAST_FILTER() \
  __except(FailFastFilter(GetExceptionInformation())) \
  { \
  } do {} while(0,0)

inline
LONG WINAPI FailFastFilter(
  __in  struct _EXCEPTION_POINTERS* exceptionInfo)
{
  RaiseFailFastException(
    exceptionInfo - > ExceptionRecord,
    exceptionInfo - > ContextRecord,
    0);
  return EXCEPTION_CONTINUE_SEARCH;
}

template<typename Function>
auto FailFastOnThrow(
  Function && function) -> decltype(
      std::forward<Function>(function)())
{
  //
  // __ try must be isolated in its own
  // function in order for the compiler
  // to reason about C++ unwind in the
  // calling and called functions.
  //
  __try {
    return std::forward <Function >(function)();
  }
  FAIL_FAST_FILTER();
}

#define FAIL_FAST_ON_THROW(Function) \
  FailFastOnThrow((Function))

#define FAIL_FAST(Code) \
  FAIL_FAST_ON_THROW(
    [&]{ \
      RaiseException( \
        (Code), \
        EXCEPTION_NONCONTINUABLE, \
        0, \
        nullptr \
      ); \
    } \
  )

No comments:

Post a Comment