// Fill out your copyright notice in the Description page of Project Settings. #include "CrashActor.h" DEFINE_LOG_CATEGORY(LogCrash); // Sets default values ACrashActor::ACrashActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned void ACrashActor::BeginPlay() { Super::BeginPlay(); } void TestCrash(int CrashFrame) { auto FN = [=]() { int* ptr = nullptr; *ptr = CrashFrame + 6; }; FN(); } ETestCrashType CrashNameToEnum(const FString& CrashName) { UEnum* CrashEnumPtr = nullptr; if (!CrashEnumPtr) { CrashEnumPtr = FindObject(ANY_PACKAGE, TEXT("ETestCrashType"), true); } if (!CrashEnumPtr) { return ETestCrashType::NullPointer; } return static_cast(CrashEnumPtr->GetValueByNameString(CrashName)); } void CrashTest(FString CrashName) { ETestCrashType Type = CrashNameToEnum(CrashName); switch (Type) { case ETestCrashType::NullPointer: { volatile char* ptr = nullptr; *ptr += 1; } break; case ETestCrashType::ArrayOutOfBounds: { TArray emptyArray; emptyArray[0] = 10; } break; case ETestCrashType::BadFunctionPtr: { void(*funcPointer)() = nullptr; funcPointer(); } break; case ETestCrashType::IllegalAccess: { int* addrPtr = reinterpret_cast(0x12345678); *addrPtr = 10; } break; case ETestCrashType::StackOverflow: { using CrashRecursiveFnType = void (*)(int counter); static CrashRecursiveFnType CrashFn; CrashFn = [](int counter) { volatile int data[1024]; // 每次递归分配额外栈空间加速溢出 UE_LOG(LogTemp, Warning, TEXT("Depth: %d"), counter); CrashFn(data[0] + 1); // 无限递归 }; CrashFn(1); } break; case ETestCrashType::CrashOOM: { // 持续分配内存直到崩溃 TArray MemoryBlocks; while (true) { // 每次分配 100MB(调整数值适配测试环境) void* Block = FMemory::Malloc(100 * 1024 * 1024); if (!Block) { // 分配失败时主动崩溃或记录日志 UE_LOG(LogTemp, Fatal, TEXT("OOM崩溃触发!")); break; } MemoryBlocks.Add(Block); } } break; case ETestCrashType::Assert: { char* assertPtr = nullptr; check(assertPtr != nullptr); } break; case ETestCrashType::Ensure: { char* ensurePtr = nullptr; ensure(ensurePtr != nullptr); } break; default: { UE_LOG(LogTemp, Warning, TEXT("Uknown app termination type!")); } break; } } // Called every frame void ACrashActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); CrashFrame = 100; if (Frame++ >= CrashFrame) { UE_LOG(LogTemp, Error, TEXT("ACrashActor:BeforeCrash")); CrashTest("CrashOOM"); //TestCrash(CrashFrame); } }