You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Change when ImageNtHeader is called to PreInitPostStartupScreen. This is after some hidden DbgHelp initialization is done so future calls to SymFromAddr succeed. There is not a clear answer for when ImageNtHeader can be called but where it was before was too early. This is potentially an issue with large PDBs This issue only was seen to reproduce in monolithic exes [REVIEW] [at]Bob.Tellez [at]Devin.Doucette [at]Robert.Millar [at]Gary.Yuan [at]Joe.Kirchoff #preflight 636c0f617c2b505190240d9b [CL 23071975 by eric knapik in ue5-main branch]
206 lines
5.2 KiB
C++
206 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Misc/CommandLine.h"
|
|
#include "Misc/App.h"
|
|
#include "Misc/OutputDeviceError.h"
|
|
#include "LaunchEngineLoop.h"
|
|
#include "PhysicsPublic.h"
|
|
#include "HAL/ExceptionHandling.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "ProfilingDebugging/LoadTimeTracker.h"
|
|
#include "Stats/StatsMisc.h"
|
|
#include "Misc/CoreDelegates.h"
|
|
#include "Misc/EngineVersion.h"
|
|
#include "Misc/ScopedSlowTask.h"
|
|
#include "Misc/TrackedActivity.h"
|
|
#if WITH_EDITOR
|
|
#include "UnrealEdGlobals.h"
|
|
#endif
|
|
#if PLATFORM_WINDOWS
|
|
#include "Windows/WindowsHWrapper.h"
|
|
#endif
|
|
|
|
|
|
IMPLEMENT_MODULE(FDefaultModuleImpl, Launch);
|
|
|
|
#if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_UNIX || PLATFORM_USE_GENERIC_LAUNCH_IMPLEMENTATION
|
|
|
|
FEngineLoop GEngineLoop;
|
|
|
|
extern "C" int test_main(int argc, char ** argp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* PreInits the engine loop
|
|
*/
|
|
int32 EnginePreInit( const TCHAR* CmdLine )
|
|
{
|
|
int32 ErrorLevel = GEngineLoop.PreInit( CmdLine );
|
|
|
|
return( ErrorLevel );
|
|
}
|
|
|
|
/**
|
|
* Inits the engine loop
|
|
*/
|
|
int32 EngineInit()
|
|
{
|
|
int32 ErrorLevel = GEngineLoop.Init();
|
|
|
|
return( ErrorLevel );
|
|
}
|
|
|
|
/**
|
|
* Ticks the engine loop
|
|
*/
|
|
LAUNCH_API void EngineTick( void )
|
|
{
|
|
GEngineLoop.Tick();
|
|
}
|
|
|
|
/**
|
|
* Shuts down the engine
|
|
*/
|
|
LAUNCH_API void EngineExit( void )
|
|
{
|
|
// Make sure this is set
|
|
RequestEngineExit(TEXT("EngineExit() was called"));
|
|
|
|
GEngineLoop.Exit();
|
|
}
|
|
|
|
/**
|
|
* Performs any required cleanup in the case of a fatal error.
|
|
*/
|
|
void LaunchStaticShutdownAfterError()
|
|
{
|
|
// Make sure physics is correctly torn down.
|
|
TermGamePhys();
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
extern UNREALED_API FSecondsCounterData BlueprintCompileAndLoadTimerData;
|
|
#endif
|
|
|
|
/**
|
|
* Static guarded main function. Rolled into own function so we can have error handling for debug/ release builds depending
|
|
* on whether a debugger is attached or not.
|
|
*/
|
|
int32 GuardedMain( const TCHAR* CmdLine )
|
|
{
|
|
FTrackedActivity::GetEngineActivity().Update(TEXT("Starting"), FTrackedActivity::ELight::Yellow);
|
|
|
|
FTaskTagScope Scope(ETaskTag::EGameThread);
|
|
|
|
#if !(UE_BUILD_SHIPPING)
|
|
|
|
// If "-waitforattach" or "-WaitForDebugger" was specified, halt startup and wait for a debugger to attach before continuing
|
|
if (FParse::Param(CmdLine, TEXT("waitforattach")) || FParse::Param(CmdLine, TEXT("WaitForDebugger")))
|
|
{
|
|
while (!FPlatformMisc::IsDebuggerPresent())
|
|
{
|
|
FPlatformProcess::Sleep(0.1f);
|
|
}
|
|
UE_DEBUG_BREAK();
|
|
}
|
|
|
|
#endif
|
|
|
|
BootTimingPoint("DefaultMain");
|
|
|
|
// Super early init code. DO NOT MOVE THIS ANYWHERE ELSE!
|
|
FCoreDelegates::GetPreMainInitDelegate().Broadcast();
|
|
|
|
// make sure GEngineLoop::Exit() is always called.
|
|
struct EngineLoopCleanupGuard
|
|
{
|
|
~EngineLoopCleanupGuard()
|
|
{
|
|
// Don't shut down the engine on scope exit when we are running embedded
|
|
// because the outer application will take care of that.
|
|
if (!GUELibraryOverrideSettings.bIsEmbedded)
|
|
{
|
|
EngineExit();
|
|
}
|
|
}
|
|
} CleanupGuard;
|
|
|
|
// Set up minidump filename. We cannot do this directly inside main as we use an FString that requires
|
|
// destruction and main uses SEH.
|
|
// These names will be updated as soon as the Filemanager is set up so we can write to the log file.
|
|
// That will also use the user folder for installed builds so we don't write into program files or whatever.
|
|
#if PLATFORM_WINDOWS
|
|
FCString::Strcpy(MiniDumpFilenameW, *FString::Printf(TEXT("unreal-v%i-%s.dmp"), FEngineVersion::Current().GetChangelist(), *FDateTime::Now().ToString()));
|
|
#endif
|
|
|
|
FTrackedActivity::GetEngineActivity().Update(TEXT("Initializing"));
|
|
int32 ErrorLevel = EnginePreInit( CmdLine );
|
|
|
|
// exit if PreInit failed.
|
|
if ( ErrorLevel != 0 || IsEngineExitRequested() )
|
|
{
|
|
return ErrorLevel;
|
|
}
|
|
|
|
{
|
|
FScopedSlowTask SlowTask(100, NSLOCTEXT("EngineInit", "EngineInit_Loading", "Loading..."));
|
|
|
|
// EnginePreInit leaves 20% unused in its slow task.
|
|
// Here we consume 80% immediately so that the percentage value on the splash screen doesn't change from one slow task to the next.
|
|
// (Note, we can't include the call to EnginePreInit in this ScopedSlowTask, because the engine isn't fully initialized at that point)
|
|
SlowTask.EnterProgressFrame(80);
|
|
|
|
SlowTask.EnterProgressFrame(20);
|
|
|
|
#if WITH_EDITOR
|
|
if (GIsEditor)
|
|
{
|
|
ErrorLevel = EditorInit(GEngineLoop);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
ErrorLevel = EngineInit();
|
|
}
|
|
}
|
|
|
|
double EngineInitializationTime = FPlatformTime::Seconds() - GStartTime;
|
|
UE_LOG(LogLoad, Log, TEXT("(Engine Initialization) Total time: %.2f seconds"), EngineInitializationTime);
|
|
|
|
#if WITH_EDITOR
|
|
UE_LOG(LogLoad, Log, TEXT("(Engine Initialization) Total Blueprint compile time: %.2f seconds"), BlueprintCompileAndLoadTimerData.GetTime());
|
|
#endif
|
|
|
|
ACCUM_LOADTIME(TEXT("EngineInitialization"), EngineInitializationTime);
|
|
|
|
BootTimingPoint("Tick loop starting");
|
|
DumpBootTiming();
|
|
|
|
FTrackedActivity::GetEngineActivity().Update(TEXT("Ticking loop"), FTrackedActivity::ELight::Green);
|
|
|
|
// Don't tick if we're running an embedded engine - we rely on the outer
|
|
// application ticking us instead.
|
|
if (!GUELibraryOverrideSettings.bIsEmbedded)
|
|
{
|
|
while( !IsEngineExitRequested() )
|
|
{
|
|
EngineTick();
|
|
}
|
|
}
|
|
|
|
TRACE_BOOKMARK(TEXT("Tick loop end"));
|
|
|
|
#if WITH_EDITOR
|
|
if( GIsEditor )
|
|
{
|
|
EditorExit();
|
|
}
|
|
#endif
|
|
return ErrorLevel;
|
|
}
|
|
|
|
#endif
|