Files
UnrealEngineUWP/Engine/Source/Runtime/Linux/LinuxCommonStartup/Private/LinuxCommonStartup.cpp
Andrew Grant f98f5761cc Copying //UE4/Orion-Staging to //UE4/Main (Origin: //Orion/Dev-General @ 2879808)
==========================
MAJOR FEATURES + CHANGES
==========================

#lockdown Nick.Penwarden

Change 2879705 on 2016/02/24 by Nick.Darnell

	Editor - Tweaking some comments.

	#tests n/a
	#rb n/a

Change 2879674 on 2016/02/24 by Nick.Darnell

	Editor - The editor now supports many new methods of opening new asset editors.  You can choose where tabs open with a great deal more options in Editor Preferences > Appearance > Asset Editor Open Location.  This will reset the 'always open asset editors in new windows' option, it completely replaces and enchances that option.

	#tests Ran the editor, tried each option and they all seem to do what I want.
	#rb matt.kuhlenschmidt

Change 2879661 on 2016/02/24 by Jamie.Dale

	More general fixes for dialogue waves

	- The localization key now uses a hash of the speaker and target voice GUIDs to help keep them short.
	- The localization key can now be user customized, and contains a placeholder format specifier for the context hash.
	- The "Variations" meta-data is now called "Context".

	#rb James.Hopkin
	#tests Built for Windows, Linux, and PS4. Tested a loc gather and export had the correct info in it. Tested the new UI worked as expected.

Change 2879436 on 2016/02/24 by Nicholas.Davies

	A few bug fixes for blocking PS4 > PC chat
	#jira OR-15467 Disable Paragon chat on PS4 for users outside of the game
	#RB Antony.Carter
	#codereview Sam.Zamani
	#TESTS PS4 whispers to and from none Paragon PC users is blocked.

Change 2878929 on 2016/02/23 by Jason.Bestimt

	#ORION_DEV - Merge Main to reconcile 0.20 branch creation

	#RB:none
	#Tests:none

Change 2878600 on 2016/02/23 by Dmitry.Rekman

	Linux: added code to identify CPU for FPSCharts (OR-14949).

	#rb none
	#tests Ran dedicated server on local VM and a few physical boxes.

Change 2878443 on 2016/02/23 by Marcus.Wassmer

	Fix game not ticking when PS button is pressed.
	#rb andrew.grant
	#test golden path ps4

Change 2878361 on 2016/02/23 by Josh.Markiewicz

	#UE4 - fixed bad comment
	#rb none
	#tests none

Change 2878205 on 2016/02/23 by Jason.Bestimt

	#ORION_DEV - Merge main (0.19) at CL# 2878162

	#Tests:none
	#RB:none

Change 2878095 on 2016/02/23 by Josh.Markiewicz

	#UE4 - added warnings to json mcp read/write failures
	- removed HostAddressOverride parameter (use -uselocalips and -multihome together instead)
	#rb none
	#tests matchmaking golden path

Change 2878002 on 2016/02/23 by Josh.Markiewicz

	#UE4 - made two party framework functions virtual
	#rb none
	#tests none

Change 2877998 on 2016/02/23 by Josh.Markiewicz

	#Ue4 - Party interface can optionally enable/disable creating a chat room alongside the party (defaults to enabled)
	#rb rob.cannaday
	#tests social/team parties golden path
	#codereview rob.cannaday

Change 2877822 on 2016/02/23 by Olaf.Piesche

	speculative fix for OR-15710

	#rb david.hill
	#tests PC game

Change 2877804 on 2016/02/23 by Uriel.Doyon

	Fixed ULevel::AddReferencedObjects clearing all references to static texture streaming data
	#codereview robert.manuszewski
	#rb marcus.wassmer
	#tests played several games on PC, also doing rejoin
	#jira OR-15658

Change 2877692 on 2016/02/23 by Jamie.Dale

	Added commandlet to replace sound wave players in sound cues with dialogue wave players where appropriate

	#rb Saul.Abreu
	#tests Built for Windows, Linux, and PS4. Tested the commandlet.

Change 2877691 on 2016/02/23 by Jamie.Dale

	Added commandlet to extract out the information from our character sheets and put it into the correct dialogue waves

	#rb Saul.Abreu
	#tests Built for Windows, Linux, and PS4. Tested the commandlet.

Change 2877690 on 2016/02/23 by Jamie.Dale

	General dialogue wave fixes

[CL 2881965 by Andrew Grant in Main branch]
2016-02-25 15:13:33 -05:00

263 lines
7.2 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "LinuxCommonStartup.h"
#include "ExceptionHandling.h"
#include "LinuxPlatformCrashContext.h"
#include "ModuleManager.h"
#include "EngineVersion.h"
#include <locale.h>
#include <sys/resource.h>
static FString GSavedCommandLine;
extern int32 GuardedMain( const TCHAR* CmdLine );
extern void LaunchStaticShutdownAfterError();
#if WITH_ENGINE
// see comment in LaunchLinux.cpp for details why it is done this way
extern void LaunchLinux_FEngineLoop_AppExit();
#endif // WITH_ENGINE
/**
* Game-specific crash reporter
*/
void CommonLinuxCrashHandler(const FGenericCrashContext& GenericContext)
{
// at this point we should already be using malloc crash handler (see PlatformCrashHandler)
const FLinuxCrashContext& Context = static_cast< const FLinuxCrashContext& >( GenericContext );
printf("CommonLinuxCrashHandler: Signal=%d\n", Context.Signal);
// better than having mutable fields?
const_cast< FLinuxCrashContext& >(Context).CaptureStackTrace();
if (GLog)
{
GLog->Flush();
}
if (GWarn)
{
GWarn->Flush();
}
if (GError)
{
GError->Flush();
GError->HandleError();
}
return Context.GenerateCrashInfoAndLaunchReporter();
}
/**
* Sets (soft) limit on a specific resource
*
* @param Resource - one of RLIMIT_* values
* @param DesiredLimit - desired value
* @param bIncreaseOnly - avoid changing the limit if current value is sufficient
*/
bool SetResourceLimit(int Resource, rlim_t DesiredLimit, bool bIncreaseOnly)
{
rlimit Limit;
if (getrlimit(Resource, &Limit) != 0)
{
fprintf(stderr, "getrlimit() failed with error %d (%s)\n", errno, strerror(errno));
return false;
}
if (bIncreaseOnly && (Limit.rlim_cur == RLIM_INFINITY || Limit.rlim_cur >= DesiredLimit))
{
if (!UE_BUILD_SHIPPING)
{
printf("- Existing per-process limit (soft=%lu, hard=%lu) is enough for us (need only %lu)\n", Limit.rlim_cur, Limit.rlim_max, DesiredLimit);
}
return true;
}
Limit.rlim_cur = DesiredLimit;
if (setrlimit(Resource, &Limit) != 0)
{
fprintf(stderr, "setrlimit() failed with error %d (%s)\n", errno, strerror(errno));
if (errno == EINVAL)
{
if (DesiredLimit == RLIM_INFINITY)
{
fprintf(stderr, "- Max per-process value allowed is %lu (we wanted infinity).\n", Limit.rlim_max);
}
else
{
fprintf(stderr, "- Max per-process value allowed is %lu (we wanted %lu).\n", Limit.rlim_max, DesiredLimit);
}
}
return false;
}
return true;
}
/**
* Expects GSavedCommandLine to be set up. Increases limit on
* - number of open files to be no less than desired (if specified on command line, otherwise left alone)
* - size of core file, so core gets dumped and we can debug crashed builds (unless overridden with -nocore)
*
*/
static bool IncreasePerProcessLimits()
{
// honor the parameter if given, but don't change limits if not
int32 FileHandlesToReserve = -1;
if (FParse::Value(*GSavedCommandLine, TEXT("numopenfiles="), FileHandlesToReserve) && FileHandlesToReserve > 0)
{
if (!UE_BUILD_SHIPPING)
{
printf("Increasing per-process limit of open file handles to %d\n", FileHandlesToReserve);
}
if (!SetResourceLimit(RLIMIT_NOFILE, FileHandlesToReserve, true))
{
fprintf(stderr, "Could not adjust number of file handles, consider changing \"nofile\" in /etc/security/limits.conf and relogin.\nerror(%d): %s\n", errno, strerror(errno));
return false;
}
}
// core dump policy:
// - Shipping and Test disable by default (unless -core is passed)
// - The rest set it to infinity unless -nocore is passed
// (in all scenarios user wish as expressed with -core or -nocore takes priority)
bool bDisableCore = (UE_BUILD_SHIPPING != 0 || UE_BUILD_TEST != 0);
if (FParse::Param(*GSavedCommandLine, TEXT("nocore")))
{
bDisableCore = true;
}
if (FParse::Param(*GSavedCommandLine, TEXT("core")))
{
bDisableCore = false;
}
if (bDisableCore)
{
printf("Disabling core dumps.\n");
if (!SetResourceLimit(RLIMIT_CORE, 0, false))
{
fprintf(stderr, "Could not set core file size to 0, error(%d): %s\n", errno, strerror(errno));
return false;
}
}
else
{
printf("Increasing per-process limit of core file size to infinity.\n");
if (!SetResourceLimit(RLIMIT_CORE, RLIM_INFINITY, true))
{
fprintf(stderr, "Could not adjust core file size, consider changing \"core\" in /etc/security/limits.conf and relogin.\nerror(%d): %s\n", errno, strerror(errno));
fprintf(stderr, "Alternatively, pass -nocore if you are unable or unwilling to do that.\n");
return false;
}
}
return true;
}
int CommonLinuxMain(int argc, char *argv[], int (*RealMain)(const TCHAR * CommandLine))
{
FPlatformMisc::SetGracefulTerminationHandler();
if (UE_BUILD_SHIPPING)
{
// only printed in shipping
printf("%s %d %d %d %d\n", StringCast<ANSICHAR>(*FEngineVersion::Current().ToString()).Get(), GEngineMinNetVersion, GEngineNegotiationVersion, GPackageFileUE4Version, GPackageFileLicenseeUE4Version);
}
int ErrorLevel = 0;
if (setenv("LC_NUMERIC", "en_US", 1) != 0)
{
int ErrNo = errno;
fprintf(stderr, "Unable to setenv(LC_NUMERIC): errno=%d (%s)", ErrNo, strerror(ErrNo));
}
setlocale(LC_CTYPE, "");
for (int32 Option = 1; Option < argc; Option++)
{
GSavedCommandLine += TEXT(" ");
// we need to quote stuff that has spaces in it because something somewhere is removing quotation marks before they arrive here
FString Temp = UTF8_TO_TCHAR(argv[Option]);
if (Temp.Contains(TEXT(" ")))
{
if(Temp.StartsWith(TEXT("-")))
{
Temp = Temp.Replace(TEXT("="), TEXT("=\""));
}
else
{
Temp = TEXT("\"") + Temp;
}
Temp += TEXT("\"");
}
GSavedCommandLine += Temp; // note: technically it depends on locale
}
if (!UE_BUILD_SHIPPING)
{
GAlwaysReportCrash = true; // set by default and reverse the behavior
if ( FParse::Param( *GSavedCommandLine,TEXT("nocrashreports") ) || FParse::Param( *GSavedCommandLine,TEXT("no-crashreports") ) )
{
GAlwaysReportCrash = false;
}
}
if (!IncreasePerProcessLimits())
{
fprintf(stderr, "Could not set desired per-process limits, consider changing system limits.\n");
ErrorLevel = 1;
}
else
{
#if UE_BUILD_DEBUG
if( true && !GAlwaysReportCrash )
#else
if( FPlatformMisc::IsDebuggerPresent() && !GAlwaysReportCrash )
#endif
{
// Don't use exception handling when a debugger is attached to exactly trap the crash. This does NOT check
// whether we are the first instance or not!
ErrorLevel = RealMain( *GSavedCommandLine );
}
else
{
FPlatformMisc::SetCrashHandler(CommonLinuxCrashHandler);
GIsGuarded = 1;
// Run the guarded code.
ErrorLevel = RealMain( *GSavedCommandLine );
GIsGuarded = 0;
}
}
// Final shut down.
#if WITH_ENGINE
LaunchLinux_FEngineLoop_AppExit();
#endif // WITH_ENGINE
// check if a specific return code has been set
uint8 OverriddenErrorLevel = 0;
if (FPlatformMisc::HasOverriddenReturnCode(&OverriddenErrorLevel))
{
ErrorLevel = OverriddenErrorLevel;
}
if (ErrorLevel)
{
printf("Exiting abnormally (error code: %d)\n", ErrorLevel);
}
return ErrorLevel;
}
class FLinuxCommonStartupModule : public IModuleInterface
{
/** IModuleInterface implementation */
virtual void StartupModule() override {};
virtual void ShutdownModule() override {};
};
IMPLEMENT_MODULE(FLinuxCommonStartupModule, LinuxCommonStartup);