static std::string _FormatDiagnostic(const TfEnum &code, const TfCallContext &context, const std::string &msg, const TfDiagnosticInfo &info) { string output; string codeName = TfDiagnosticMgr::GetCodeName(code); if (context.IsHidden() || !strcmp(context.GetFunction(), "") || !strcmp(context.GetFile(), "")) { output = TfStringPrintf("%s%s: %s [%s]\n", codeName.c_str(), ArchIsMainThread() ? "" : " (secondary thread)", msg.c_str(), ArchGetProgramNameForErrors()); } else { output = TfStringPrintf("%s%s: in %s at line %zu of %s -- %s\n", codeName.c_str(), ArchIsMainThread() ? "" : " (secondary thread)", context.GetFunction(), context.GetLine(), context.GetFile(), msg.c_str()); } if (const TfPyExceptionState* exc = boost::any_cast<TfPyExceptionState>(&info)) { output += TfStringPrintf("%s\n", exc->GetExceptionString().c_str()); } return output; }
void TfDiagnosticMgr::PostFatal(TfCallContext const &context, TfEnum statusCode, std::string const &msg) const { _ReentrancyGuard guard(&_reentrantGuard.local()); if (guard.ScopeWasReentered()) { return; } if (TfDebug::IsEnabled(TF_ATTACH_DEBUGGER_ON_ERROR) || TfDebug::IsEnabled(TF_ATTACH_DEBUGGER_ON_FATAL_ERROR)) ArchDebuggerTrap(); bool dispatchedToDelegate = false; { tbb::spin_rw_mutex::scoped_lock lock(_delegatesMutex, /*writer=*/false); for (auto const& delegate : _delegates) { if (delegate) { delegate->IssueFatalError(context, msg); } } dispatchedToDelegate = !_delegates.empty(); } if (!dispatchedToDelegate) { if (statusCode == TF_DIAGNOSTIC_CODING_ERROR_TYPE) { fprintf(stderr, "Fatal coding error: %s [%s], in %s(), %s:%zu\n", msg.c_str(), ArchGetProgramNameForErrors(), context.GetFunction(), context.GetFile(), context.GetLine()); } else if (statusCode == TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE) { fprintf(stderr, "Fatal error: %s [%s].\n", msg.c_str(), ArchGetProgramNameForErrors()); exit(1); } else { // Report and log information about the fatal error TfLogCrash("FATAL ERROR", msg, std::string() /*additionalInfo*/, context, true /*logToDB*/); } // Abort, but avoid the signal handler, since we've already logged the // session info in TfLogStackTrace. Tf_UnhandledAbort(); } }
void TfDiagnosticMgr::PostFatal(TfCallContext const &context, TfEnum statusCode, std::string const &msg) const { if (TfDebug::IsEnabled(TF_ATTACH_DEBUGGER_ON_ERROR) || TfDebug::IsEnabled(TF_ATTACH_DEBUGGER_ON_FATAL_ERROR)) ArchDebuggerTrap(); bool isMainThread = ArchIsMainThread(); // Send out the IssuedFatalError notice if we're in the main thread. if (isMainThread) { TfDiagnosticBase data(statusCode, "", context, msg, TfDiagnosticInfo(), false /*quiet*/); TfDiagnosticNotice::IssuedFatalError fe(msg, context); fe.SetData(data); fe.Send(TfCreateWeakPtr(this)); } if (isMainThread && _delegate) { _delegate->IssueFatalError(context, msg); } else { if (statusCode == TF_DIAGNOSTIC_CODING_ERROR_TYPE) { fprintf(stderr, "Fatal coding error: %s [%s], in %s(), %s:%zu\n", msg.c_str(), ArchGetProgramNameForErrors(), context.GetFunction(), context.GetFile(), context.GetLine()); } else if (statusCode == TF_DIAGNOSTIC_RUNTIME_ERROR_TYPE) { fprintf(stderr, "Fatal error: %s [%s].\n", msg.c_str(), ArchGetProgramNameForErrors()); exit(1); } else { // Report and log information about the fatal error TfLogCrash("FATAL ERROR", msg, std::string() /*additionalInfo*/, context, true /*logToDB*/); } // Abort, but avoid the signal handler, since we've already logged the // session info in TfLogStackTrace. Tf_UnhandledAbort(); } }