From 767ced356356ee0c934b537b95fb26bc7bbd7452 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 13 May 2020 12:30:25 -0700 Subject: [PATCH] Improved fatal errors - they run through crash handler now --- BeefySysLib/platform/win/Platform.cpp | 12 ++----- IDEHelper/Compiler/BfExprEvaluator.cpp | 4 +-- IDEHelper/Compiler/BfModule.cpp | 41 ++++++++++++++++++------ IDEHelper/Compiler/BfModule.h | 3 ++ IDEHelper/Compiler/BfModuleTypeUtils.cpp | 18 +++++------ 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 2d6df814..f5bbafee 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -414,15 +414,9 @@ void Beefy::BFFatalError(const StringImpl& message, const StringImpl& file, int if (gBFApp != NULL) gBFApp->mSysDialogCnt++; #endif - -#ifdef _DEBUG - OutputDebugStrF("FATAL ERROR: %s\n", message.c_str()); - _wassert(UTF8Decode(message).c_str(), UTF8Decode(file).c_str(), line); -#else - String error = StrFormat("%s in %s:%d", message.c_str(), file.c_str(), line); - ::MessageBoxA(NULL, error.c_str(), "FATAL ERROR", MB_ICONERROR | MB_OK); - exit(1); -#endif + + String failMsg = StrFormat("%s in %s:%d", message.c_str(), file.c_str(), line); + BfpSystem_FatalError(failMsg.c_str(), "FATAL ERROR"); #ifndef BF_NO_BFAPP if (gBFApp != NULL) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 174bc6f8..892a181a 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -1161,7 +1161,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod); if (methodInstance == NULL) { - BF_FATAL("Failed to get raw method in BfMethodMatcher::CheckMethod"); + BFMODULE_FATAL(mModule, "Failed to get raw method in BfMethodMatcher::CheckMethod"); return false; } @@ -5814,7 +5814,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou } else { - BF_FATAL("Bad"); + BFMODULE_FATAL(mModule, "Bad"); } } methodMatcher.mArguments.Insert(0, resolvedArg); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index b968e93d..8797e426 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2845,12 +2845,31 @@ void BfModule::CheckRangeError(BfType* type, BfAstNode* refNode) Fail(StrFormat("Result out of range for type '%s'", TypeToString(type).c_str()), refNode); } +void BfModule::FatalError(const StringImpl& error, const char* file, int line) +{ + String fullError = error; + + if (file != NULL) + fullError += StrFormat(" at %s:%d", file, line); + + fullError += StrFormat("\nModule: %s", mModuleName.c_str()); + + if (mCurTypeInstance != NULL) + fullError += StrFormat("\nType: %s", TypeToString(mCurTypeInstance).c_str()); + if (mCurMethodInstance != NULL) + fullError += StrFormat("\nMethod: %s", MethodToString(mCurMethodInstance).c_str()); + + if ((mCurFilePosition.mFileInstance != NULL) && (mCurFilePosition.mFileInstance->mParser != NULL)) + fullError += StrFormat("\nSource Location: %s:%d", mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), mCurFilePosition.mCurLine + 1); + + BfpSystem_FatalError(fullError.c_str(), "FATAL MODULE ERROR"); +} + void BfModule::NotImpl(BfAstNode* astNode) { Fail("INTERNAL ERROR: Not implemented", astNode); } - bool BfModule::CheckAccessMemberProtection(BfProtection protection, BfType* memberType) { bool allowPrivate = (memberType == mCurTypeInstance) || (IsInnerType(mCurTypeInstance, memberType)); @@ -5431,16 +5450,16 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } else if (constant->mTypeCode == BfTypeCode_Object) { - BF_FATAL("Unhandled"); + BFMODULE_FATAL(this, "Unhandled"); } else { - BF_FATAL("Unhandled"); + BFMODULE_FATAL(this, "Unhandled"); } } else if (!handled) { - BF_FATAL("Unhandled"); + BFMODULE_FATAL(this, "Unhandled"); } argIdx++; @@ -10660,7 +10679,7 @@ BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, return val; } - BF_FATAL("Splat not found"); + BFMODULE_FATAL(this, "Splat not found"); return BfIRValue(); } @@ -11278,7 +11297,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM return GetLocalMethodInstance(localMethod, methodGenericArguments); } - BF_FATAL("Cannot find local method"); + BFMODULE_FATAL(this, "Cannot find local method"); return BfModuleMethodInstance(); } @@ -11887,7 +11906,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM if (methodDef->mGenericParams.size() != sanitizedMethodGenericArguments.size()) { Fail("Internal error"); - BF_FATAL("Generic method argument counts mismatch"); + BFMODULE_FATAL(this, "Generic method argument counts mismatch"); return NULL; } @@ -15832,7 +15851,7 @@ void BfModule::EmitGCMarkMembers() } else if (checkType->IsMethodRef()) { - BF_FATAL("Not handled"); + BFMODULE_FATAL(this, "Not handled"); } else if (checkType->WantsGCMarking()) { @@ -17499,7 +17518,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup) auto thisValue = GetThis(); if (thisValue.IsSplat()) { - BF_FATAL("Should not happen"); + BFMODULE_FATAL(this, "Should not happen"); } if (mCurTypeInstance->IsObject()) thisValue = LoadValue(thisValue); @@ -19126,6 +19145,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto methodDef = mCurMethodInstance->mMethodDef; BF_ASSERT(methodDef->mName != "__ASSERTNAME"); + if (methodDef->mName == "__FATALERRORNAME") + BFMODULE_FATAL(this, "__FATALERRORNAME"); if (typeInstance->IsClosure()) { @@ -21253,7 +21274,7 @@ bool BfModule::Finish() } else if ((!mCompiler->mOptions.mGenerateObj) && (!mCompiler->mOptions.mGenerateBitcode) && (!mCompiler->mOptions.mWriteIR)) { - BF_FATAL("Neither obj nor IR specified"); + BFMODULE_FATAL(this, "Neither obj nor IR specified"); } moduleFileName.mModuleWritten = writeModule; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index cd100a9a..36a05e30 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1307,6 +1307,8 @@ public: } }; +#define BFMODULE_FATAL(module, msg) (module)->FatalError((msg), __FILE__, __LINE__) + class BfModule : public BfStructuralVisitor { public: @@ -1405,6 +1407,7 @@ public: bool mHadHotObjectWrites; public: + void FatalError(const StringImpl& error, const char* file = NULL, int line = -1); void NotImpl(BfAstNode* astNode); void AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None); bool CheckProtection(BfProtection protection, bool allowProtected, bool allowPrivate); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 2092e541..113fe5d6 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1179,7 +1179,7 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType break; default: //NotImpl(resolvedTypeRef->mTypeRef); - BF_FATAL("Invalid type"); + BFMODULE_FATAL(this, "Invalid type"); return false; } ////////////////////////////////////////////////////////////////////////// @@ -4628,7 +4628,7 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode) primType = (BfPrimitiveType*)ResolveTypeDef(mSystem->mTypeUIntUnknown); break; case BfTypeCode_StringId: - BF_FATAL("Invalid use of StringId"); + BFMODULE_FATAL(this, "Invalid use of StringId"); break; default: break; } @@ -4881,7 +4881,7 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef) resolvedTypeRef = GetPrimitiveStructType(primType->mTypeDef->mTypeCode); if (resolvedTypeRef == NULL) { - BF_FATAL("Unable to find primitive type"); + BFMODULE_FATAL(this, "Unable to find primitive type"); return NULL; } } @@ -5881,7 +5881,7 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId { if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)) { - BF_FATAL("Invalid GetGenericParamInstance with extension"); + BFMODULE_FATAL(this, "Invalid GetGenericParamInstance with extension"); } } } @@ -6415,7 +6415,7 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI if (directStrTypeDef != NULL) findNameStr = directStrTypeDef->mTypeName; else - BF_FATAL("Error?"); + BFMODULE_FATAL(this, "Error?"); } if (findNameStr.mLength == 6) @@ -7300,7 +7300,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return resolvedType; } else - BF_FATAL("Unhandled"); + BFMODULE_FATAL(this, "Unhandled"); } if (auto refTypeRef = BfNodeDynCastExact(typeRef)) @@ -7950,7 +7950,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } else { - BF_FATAL("Not implemented!"); + BFMODULE_FATAL(this, "Not implemented!"); NotImpl(typeRef); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } @@ -10673,7 +10673,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF { auto constExprValueType = (BfConstExprValueType*)resolvedType; str += "const "; - + DoTypeToString(str, constExprValueType->mType, typeNameFlags, genericMethodNameOverrides); str += " "; @@ -10681,7 +10681,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF return; } - BF_FATAL("Not implemented"); + BFMODULE_FATAL(this, "Not implemented"); str += "???"; return; }