void* FLinuxPlatformProcess::GetDllHandle( const TCHAR* Filename ) { check( Filename ); FString AbsolutePath = FPaths::ConvertRelativePathToFull(Filename); void *Handle = dlopen( TCHAR_TO_ANSI(*AbsolutePath), RTLD_LAZY | RTLD_LOCAL ); if (!Handle) { UE_LOG(LogLinux, Warning, TEXT("dlopen failed: %s"), ANSI_TO_TCHAR(dlerror()) ); } return Handle; }
FString FJavascriptWebSocket::LocalEndPoint() { #if !PLATFORM_HTML5 return FString(ANSI_TO_TCHAR(libwebsocket_canonical_hostname(Context))); #endif #if PLATFORM_HTML5 return FString(TEXT("TODO:LOCALENDPOINT")); #endif }
void FIOSPlatformMisc::GetEnvironmentVariable(const TCHAR* VariableName, TCHAR* Result, int32 ResultLength) { ANSICHAR *AnsiResult = getenv(TCHAR_TO_ANSI(VariableName)); if (AnsiResult) { wcsncpy(Result, ANSI_TO_TCHAR(AnsiResult), ResultLength); } else { *Result = 0; } }
bool UNdiMediaFinder::GetSources(TArray<FNdiMediaSourceId>& OutSources) const { if (!FNdi::IsInitialized() || (FindInstance == nullptr)) { return false; } uint32_t NumSources = 0; const NDIlib_source_t* Sources = FNdi::Lib->NDIlib_find_get_current_sources(FindInstance, &NumSources); for (uint32_t SourceIndex = 0; SourceIndex < NumSources; ++SourceIndex) { const NDIlib_source_t& Source = Sources[SourceIndex]; OutSources.Add(FNdiMediaSourceId( ANSI_TO_TCHAR(Source.p_ip_address), ANSI_TO_TCHAR(Source.p_ndi_name) )); } return true; }
/** * Create the bones needed to hold the transforms for the destructible chunks associated with an Apex Destructible Asset. * @param ImportData - SkeletalMesh import data into which we are extracting information * @param ApexDestructibleAsset - the Apex Destructible Asset */ static void CreateBones(FSkeletalMeshImportData &ImportData, const NxDestructibleAsset& ApexDestructibleAsset) { // Just need to create ApexDestructibleAsset.getChunkCount() bones, all with identity transform poses const uint32 ChunkCount = ApexDestructibleAsset.getChunkCount(); if( ChunkCount == 0 ) { UE_LOG(LogApexDestructibleAssetImport, Warning,TEXT("%s has no chunks"), ANSI_TO_TCHAR(ApexDestructibleAsset.getName()) ); return; } const uint32 BoneCount = ChunkCount + 1; // Adding one more bone for the root bone, required by the skeletal mesh // Format for bone names uint32 Q = ChunkCount-1; int32 MaxNumberWidth = 1; while ((Q /= 10) != 0) { ++MaxNumberWidth; } // Turn parts into bones for (uint32 BoneIndex=0; BoneIndex<BoneCount; ++BoneIndex) { ImportData.RefBonesBinary.Add( VBone() ); // Set bone VBone& Bone = ImportData.RefBonesBinary[BoneIndex]; if (BoneIndex == 0) { // Bone 0 is the required root bone Bone.Name = TEXT("Root"); Bone.NumChildren = ChunkCount; Bone.ParentIndex = INDEX_NONE; } else { // The rest are the parts Bone.Name = FString::Printf( TEXT("Part%0*d"), MaxNumberWidth, BoneIndex-1); Bone.NumChildren = 0; // Creates a simple "flat" hierarchy Bone.ParentIndex = 0; } // Set transform to identity VJointPos& JointMatrix = Bone.BonePos; JointMatrix.Orientation = FQuat(0.0f,0.0f,0.0f,1.0f); JointMatrix.Position = FVector(0.0f,0.0f,0.0f); JointMatrix.Length = 1.0f; JointMatrix.XSize = 100.0f; JointMatrix.YSize = 100.0f; JointMatrix.ZSize = 100.0f; } }
void FLinuxTime::PrintCalibrationLog() { // clock selection happens too early to be printed to log, print it now FString Buffer(ANSI_TO_TCHAR(CalibrationLog)); TArray<FString> Lines; Buffer.ParseIntoArrayLines(Lines); for(const FString& Line : Lines) { UE_LOG(LogLinux, Log, TEXT("%s"), *Line); } }
bool FSandboxPlatformFile::ShouldBeUsed(IPlatformFile* Inner, const TCHAR* CmdLine) const { FString SandboxDir; bool bResult = FParse::Value( CmdLine, TEXT("-Sandbox="), SandboxDir ); #if PLATFORM_DESKTOP && (UE_GAME || UE_SERVER) if (FPlatformProperties::RequiresCookedData() && SandboxDir.IsEmpty() && Inner == &FPlatformFileManager::Get().GetPlatformFile() && bEntireEngineWillUseThisSandbox) { FString SandboxName = FString(TEXT("Cooked-")) + ANSI_TO_TCHAR(FPlatformProperties::PlatformName()); SandboxDir = FPaths::Combine(*(FPaths::GameDir()), TEXT("Saved"), TEXT("Sandboxes"), *SandboxDir); bResult = FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*SandboxDir); } #endif return bResult; }
UOnlineHotfixManager::UOnlineHotfixManager() : Super(), TotalFiles(0), NumDownloaded(0), TotalBytes(0), NumBytes(0) { OnEnumerateFilesCompleteDelegate = FOnEnumerateFilesCompleteDelegate::CreateUObject(this, &UOnlineHotfixManager::OnEnumerateFilesComplete); OnReadFileProgressDelegate = FOnReadFileProgressDelegate::CreateUObject(this, &UOnlineHotfixManager::OnReadFileProgress); OnReadFileCompleteDelegate = FOnReadFileCompleteDelegate::CreateUObject(this, &UOnlineHotfixManager::OnReadFileComplete); // So we only try to apply files for this platform PlatformPrefix = ANSI_TO_TCHAR(FPlatformProperties::PlatformName()); PlatformPrefix += TEXT("_"); }
const TCHAR* FLinuxPlatformProcess::UserDir() { // The UserDir is where user visible files (such as game projects) live. // On Linux (just like on Mac) this corresponds to $HOME/Documents. // To accomodate localization requirement we use xdg-user-dir command, // and fall back to $HOME/Documents if setting not found. static TCHAR Result[MAX_PATH] = TEXT(""); if (!Result[0]) { char DocPath[MAX_PATH]; FILE* FilePtr = popen("xdg-user-dir DOCUMENTS", "r"); if(fgets(DocPath, MAX_PATH, FilePtr) == NULL) { char* Home = secure_getenv("HOME"); if (!Home) { UE_LOG(LogHAL, Warning, TEXT("Unable to read the $HOME environment variable")); } else { FCString::Strcpy(Result, ANSI_TO_TCHAR(Home)); FCString::Strcat(Result, TEXT("/Documents/")); } } else { size_t DocLen = strlen(DocPath) - 1; DocPath[DocLen] = '\0'; FCString::Strcpy(Result, ANSI_TO_TCHAR(DocPath)); FCString::Strcat(Result, TEXT("/")); } pclose(FilePtr); } return Result; }
bool FProcState::IsRunning() { if (bIsRunning) { check(!bHasBeenWaitedFor); // check for the sake of internal consistency // check if actually running int KillResult = kill(GetProcessId(), 0); // no actual signal is sent check(KillResult != -1 || errno != EINVAL); bIsRunning = (KillResult == 0 || (KillResult == -1 && errno == EPERM)); // additional check if it's a zombie if (bIsRunning) { for(;;) // infinite loop in case we get EINTR and have to repeat { siginfo_t SignalInfo; SignalInfo.si_pid = 0; // if remains 0, treat as child was not waitable (i.e. was running) if (waitid(P_PID, GetProcessId(), &SignalInfo, WEXITED | WNOHANG | WNOWAIT)) { if (errno != EINTR) { int ErrNo = errno; UE_LOG(LogHAL, Fatal, TEXT("FLinuxPlatformProcess::WaitForProc: waitid for pid %d failed (errno=%d, %s)"), static_cast< int32 >(GetProcessId()), ErrNo, ANSI_TO_TCHAR(strerror(ErrNo))); break; // exit the loop if for some reason Fatal log (above) returns } } else { bIsRunning = ( SignalInfo.si_pid != GetProcessId() ); break; } } } // If child is a zombie, wait() immediately to free up kernel resources. Higher level code // (e.g. shader compiling manager) can hold on to handle of no longer running process for longer, // which is a dubious, but valid behavior. We don't want to keep zombie around though. if (!bIsRunning) { UE_LOG(LogHAL, Log, TEXT("Child %d is no more running (zombie), Wait()ing immediately."), GetProcessId() ); Wait(); } } return bIsRunning; }
JNIEXPORT void JNICALL Java_com_ers_bluetones_BlueService_receiveData (JNIEnv * env, jclass clazz, jstring device, jobject data){ const char* devi = env->GetStringUTFChars(device, JNI_FALSE); jbyte *buffy = (jbyte*)(env->GetDirectBufferAddress(data)); switch(buffy[0]) { case 0: UCPPRelay::players.Add(FString(devi), buffy[1]); break; case 1: UE_LOG(LogTemp, Warning, TEXT("%s mov %d"), ANSI_TO_TCHAR(devi), buffy[1]) UCPPRelay::movement.Add(FString(devi), buffy[1]); break; } env->ReleaseStringUTFChars(device, devi); }
FLibvlcMedia* FVlcMediaSource::OpenUrl(const FString& Url) { Close(); Media = FVlc::MediaNewLocation(VlcInstance, TCHAR_TO_ANSI(*Url)); if (Media == nullptr) { UE_LOG(LogVlcMedia, Warning, TEXT("Failed to open media %s: %s"), *Url, ANSI_TO_TCHAR(FVlc::Errmsg())); } CurrentUrl = Url; return Media; }
FString FLinuxPlatformProcess::GetApplicationName( uint32 ProcessId ) { FString Output = TEXT(""); const int32 ReadLinkSize = 1024; char ReadLinkCmd[ReadLinkSize] = {0}; FCStringAnsi::Sprintf(ReadLinkCmd, "/proc/%d/exe", ProcessId); char ProcessPath[ PlatformProcessLimits::MaxBaseDirLength ] = {0}; int32 Ret = readlink(ReadLinkCmd, ProcessPath, ARRAY_COUNT(ProcessPath) - 1); if (Ret != -1) { Output = ANSI_TO_TCHAR(ProcessPath); } return Output; }
bool FVulkanDevice::QueryGPU(int32 DeviceIndex) { bool bDiscrete = false; VulkanRHI::vkGetPhysicalDeviceProperties(Gpu, &GpuProps); auto GetDeviceTypeString = [&]() { FString Info; switch (GpuProps.deviceType) { case VK_PHYSICAL_DEVICE_TYPE_OTHER: Info = TEXT("Other"); break; case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: Info = TEXT("Integrated GPU"); break; case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: Info = TEXT("Discrete GPU"); bDiscrete = true; break; case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: Info = TEXT("Virtual GPU"); break; case VK_PHYSICAL_DEVICE_TYPE_CPU: Info = TEXT("CPU"); break; default: Info = TEXT("Unknown"); break; } return Info; }; UE_LOG(LogVulkanRHI, Display, TEXT("Initializing Device %d"), DeviceIndex); UE_LOG(LogVulkanRHI, Display, TEXT("API 0x%x Driver 0x%x VendorId 0x%x"), GpuProps.apiVersion, GpuProps.driverVersion, GpuProps.vendorID); UE_LOG(LogVulkanRHI, Display, TEXT("Name %s Device 0x%x Type %s"), ANSI_TO_TCHAR(GpuProps.deviceName), GpuProps.deviceID, *GetDeviceTypeString()); UE_LOG(LogVulkanRHI, Display, TEXT("Max Descriptor Sets Bound %d Timestamps %d"), GpuProps.limits.maxBoundDescriptorSets, GpuProps.limits.timestampComputeAndGraphics); uint32 QueueCount = 0; VulkanRHI::vkGetPhysicalDeviceQueueFamilyProperties(Gpu, &QueueCount, nullptr); check(QueueCount >= 1); QueueFamilyProps.AddUninitialized(QueueCount); VulkanRHI::vkGetPhysicalDeviceQueueFamilyProperties(Gpu, &QueueCount, QueueFamilyProps.GetData()); return bDiscrete; }
void FMacroCallback::MacroDefined(const clang::Token &MacroNameTok, const clang::MacroDirective *MD) { auto MacroName = MacroNameTok.getIdentifierInfo()->getName(); if (IsMacroDefinedInCommandLine(MacroName) || IsBuiltInMacro(MD) || IsPredefinedMacro(MacroName)) { return; } auto MacroDefinitionFile = FString(SourceManager.getFilename(MacroNameTok.getLocation()).data()); MacroDefinitionFile.ReplaceInline(TEXT("\\"), TEXT("/")); if (MacroDefinitionFile.IsEmpty()) { OutputFileContents.Logf(TEXT("Found unexpected definition of macro %s."), ANSI_TO_TCHAR(MacroName.data())); } MacroDefinitionToFile.Add(MacroName.data(), MacroDefinitionFile); }
void FLinuxCrashContext::CaptureStackTrace() { // Only do work the first time this function is called - this is mainly a carry over from Windows where it can be called multiple times, left intact for extra safety. if (!bCapturedBacktrace) { const SIZE_T StackTraceSize = 65535; ANSICHAR* StackTrace = (ANSICHAR*) FMemory::Malloc( StackTraceSize ); StackTrace[0] = 0; // Walk the stack and dump it to the allocated memory (ignore first 2 callstack lines as those are in stack walking code) FPlatformStackWalk::StackWalkAndDump( StackTrace, StackTraceSize, 2, this); FCString::Strncat( GErrorHist, ANSI_TO_TCHAR(StackTrace), ARRAY_COUNT(GErrorHist) - 1 ); CreateExceptionInfoString(Signal, Info); FMemory::Free( StackTrace ); bCapturedBacktrace = true; } }
static void SignalHandler(int32 Signal, struct __siginfo* Info, void* Context) { static int32 bHasEntered = 0; if (FPlatformAtomics::InterlockedCompareExchange(&bHasEntered, 1, 0) == 0) { const SIZE_T StackTraceSize = 65535; ANSICHAR* StackTrace = (ANSICHAR*)FMemory::Malloc(StackTraceSize); StackTrace[0] = 0; // Walk the stack and dump it to the allocated memory. FPlatformStackWalk::StackWalkAndDump(StackTrace, StackTraceSize, 0, (ucontext_t*)Context); UE_LOG(LogEngine, Error, TEXT("%s"), ANSI_TO_TCHAR(StackTrace)); FMemory::Free(StackTrace); GError->HandleError(); FPlatformMisc::RequestExit(true); } }
/** * A simple crash handler that prints the callstack to the log */ int32 SimpleCrashHandler( LPEXCEPTION_POINTERS ExceptionInfo ) { const SIZE_T StackTraceSize = 65535; ANSICHAR* StackTrace = (ANSICHAR*)GMalloc->Malloc( StackTraceSize ); StackTrace[0] = 0; FPlatformStackWalk::StackWalkAndDump( StackTrace, StackTraceSize, 0, ExceptionInfo->ContextRecord ); FCString::Strncat( GErrorHist, TEXT( "\r\n\r\n" ), ARRAY_COUNT( GErrorHist ) ); FCString::Strncat( GErrorHist, ANSI_TO_TCHAR( StackTrace ), ARRAY_COUNT( GErrorHist ) ); GMalloc->Free( StackTrace ); GError->HandleError(); FPlatformMisc::RequestExit( true ); return EXCEPTION_EXECUTE_HANDLER; }
const TCHAR* FLinuxPlatformProcess::ComputerName() { static bool bHaveResult = false; static TCHAR CachedResult[ PlatformProcessLimits::MaxComputerName ]; if (!bHaveResult) { struct utsname name; const char * SysName = name.nodename; if(uname(&name)) { SysName = "Linux Computer"; } FCString::Strcpy(CachedResult, ARRAY_COUNT(CachedResult) - 1, ANSI_TO_TCHAR(SysName)); CachedResult[ARRAY_COUNT(CachedResult) - 1] = 0; bHaveResult = true; } return CachedResult; }
static void CompileShader( const FString& Filename, const FString& EntryPoint, const FString& ShaderModel, TRefCountPtr<ID3DBlob>& OutBlob ) { uint32 ShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if UE_BUILD_DEBUG ShaderFlags |= D3D10_SHADER_DEBUG; #else ShaderFlags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; #endif TRefCountPtr<ID3DBlob> ErrorBlob; HRESULT Hr = D3DX11CompileFromFile( *Filename, NULL, NULL, TCHAR_TO_ANSI(*EntryPoint), TCHAR_TO_ANSI(*ShaderModel), ShaderFlags, 0, NULL, OutBlob.GetInitReference(), ErrorBlob.GetInitReference(), NULL ); if( FAILED(Hr) ) { if( ErrorBlob.GetReference() ) { checkf(0, ANSI_TO_TCHAR(ErrorBlob->GetBufferPointer())); } } }
/** * Returns the current program log for a GLSL program */ static FString GetGLSLProgramLog( GLuint Program ) { GLint Len; FString ProgramLog; glGetProgramiv( Program, GL_INFO_LOG_LENGTH, &Len ); if( Len > 0 ) { GLchar* Log = new GLchar[Len]; GLsizei ActualLen; glGetProgramInfoLog( Program, Len, &ActualLen, Log ); ProgramLog = ANSI_TO_TCHAR( Log ); delete[] Log; } return ProgramLog; }
const TCHAR* FLinuxPlatformProcess::ApplicationSettingsDir() { // The ApplicationSettingsDir is where the engine stores settings and configuration // data. On linux this corresponds to $HOME/.config/Epic static TCHAR Result[MAX_PATH] = TEXT(""); if (!Result[0]) { char* Home = secure_getenv("HOME"); if (!Home) { UE_LOG(LogHAL, Warning, TEXT("Unable to read the $HOME environment variable")); } else { FCString::Strcpy(Result, ANSI_TO_TCHAR(Home)); FCString::Strcat(Result, TEXT("/.config/Epic/")); } } return Result; }
/** * Returns the current shader log for a GLSL shader */ static FString GetGLSLShaderLog( GLuint Shader ) { GLint Len; FString ShaderLog; glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &Len); if(Len > 0) { GLsizei ActualLen; GLchar *Log = new GLchar[Len]; glGetShaderInfoLog(Shader, Len, &ActualLen, Log); ShaderLog = ANSI_TO_TCHAR( Log ); delete[] Log; } return ShaderLog; }
void ALeapMotionHandActor::CreateBones(const TSubclassOf<class ALeapMotionBoneActor>& BoneBlueprint) { FActorSpawnParameters SpawnParams; SpawnParams.Owner = GetOwner(); SpawnParams.Instigator = GetInstigator(); float CombinedScale = GetCombinedScale(); FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { for (ELeapBone LeapBone = bShowArm ? ELeapBone::Forearm : ELeapBone::Palm; LeapBone <= ELeapBone::Finger4Tip; ((int8&)LeapBone)++) { FVector Position; FRotator Orientation; float Width; float Length; bool Success = Device->GetBonePostionAndOrientation(HandId, LeapBone, Position, Orientation); Success &= Device->GetBoneWidthAndLength(HandId, LeapBone, Width, Length); if (Success) { FQuat RefQuat = GetRootComponent()->GetComponentRotation().Quaternion(); Position = RefQuat * Position * CombinedScale + GetRootComponent()->GetComponentLocation(); Orientation = (RefQuat * Orientation.Quaternion()).Rotator(); ALeapMotionBoneActor* BoneActor = GWorld->SpawnActor<ALeapMotionBoneActor>(BoneBlueprint ? BoneBlueprint : ALeapMotionBoneActor::StaticClass(), Position, Orientation, SpawnParams); if (BoneActor) { BoneActors.Add(BoneActor); # if WITH_EDITOR BoneActor->SetActorLabel(*FString::Printf(TEXT("LeapBone:%s"), ANSI_TO_TCHAR(LEAP_GET_BONE_NAME(LeapBone)))); # endif BoneActor->AttachRootComponentToActor(this, NAME_None, EAttachLocation::KeepWorldPosition, true); BoneActor->Init(LeapBone, CombinedScale, Width, Length, bShowCollider, bShowMesh); } } } } }
void* FLinuxPlatformProcess::GetDllHandle( const TCHAR* Filename ) { check( Filename ); FString AbsolutePath = FPaths::ConvertRelativePathToFull(Filename); int DlOpenMode = RTLD_LAZY; if (AbsolutePath.EndsWith(TEXT("libsteam_api.so"))) { DlOpenMode |= RTLD_GLOBAL; //Global symbol resolution when loading shared objects - Needed for Steam to work when its library is loaded by a plugin } else { DlOpenMode |= RTLD_LOCAL; //Local symbol resolution when loading shared objects - Needed for Hot-Reload } void *Handle = dlopen( TCHAR_TO_ANSI(*AbsolutePath), DlOpenMode ); if (!Handle) { UE_LOG(LogLinux, Warning, TEXT("dlopen failed: %s"), ANSI_TO_TCHAR(dlerror()) ); } return Handle; }
const TCHAR* FLinuxPlatformProcess::ExecutableName(bool bRemoveExtension) { static bool bHaveResult = false; static TCHAR CachedResult[ PlatformProcessLimits::MaxBaseDirLength ]; if (!bHaveResult) { char SelfPath[ PlatformProcessLimits::MaxBaseDirLength ] = {0}; if (readlink( "/proc/self/exe", SelfPath, ARRAY_COUNT(SelfPath) - 1) == -1) { int ErrNo = errno; UE_LOG(LogHAL, Fatal, TEXT("readlink() failed with errno = %d (%s)"), ErrNo, StringCast< TCHAR >(strerror(ErrNo)).Get()); return CachedResult; } SelfPath[ARRAY_COUNT(SelfPath) - 1] = 0; FCString::Strcpy(CachedResult, ARRAY_COUNT(CachedResult) - 1, ANSI_TO_TCHAR(basename(SelfPath))); CachedResult[ARRAY_COUNT(CachedResult) - 1] = 0; bHaveResult = true; } return CachedResult; }
virtual void UpdateADBPath() override { FScopeLock PathUpdateLock(&ADBPathCheckLock); TCHAR AndroidDirectory[32768] = { 0 }; FPlatformMisc::GetEnvironmentVariable(TEXT("ANDROID_HOME"), AndroidDirectory, 32768); FString ADBPath; #if PLATFORM_MAC if (AndroidDirectory[0] == 0) { // didn't find ANDROID_HOME, so parse the .bash_profile file on MAC FArchive* FileReader = IFileManager::Get().CreateFileReader(*FString([@"~/.bash_profile" stringByExpandingTildeInPath])); if (FileReader) { const int64 FileSize = FileReader->TotalSize(); ANSICHAR* AnsiContents = (ANSICHAR*)FMemory::Malloc(FileSize); FileReader->Serialize(AnsiContents, FileSize); FileReader->Close(); delete FileReader; TArray<FString> Lines; FString(ANSI_TO_TCHAR(AnsiContents)).ParseIntoArrayLines(&Lines); FMemory::Free(AnsiContents); for (int32 Index = 0; Index < Lines.Num(); Index++) { if (AndroidDirectory[0] == 0 && Lines[Index].StartsWith(TEXT("export ANDROID_HOME="))) { FString Directory; Lines[Index].Split(TEXT("="), NULL, &Directory); Directory = Directory.Replace(TEXT("\""), TEXT("")); FCString::Strcpy(AndroidDirectory, *Directory); setenv("ANDROID_HOME", TCHAR_TO_ANSI(AndroidDirectory), 1); } } } }
int32 ReportCrash(ucontext_t *Context, int32 Signal, struct __siginfo* Info) { static bool GAlreadyCreatedMinidump = false; // Only create a minidump the first time this function is called. // (Can be called the first time from the RenderThread, then a second time from the MainThread.) if ( GAlreadyCreatedMinidump == false ) { GAlreadyCreatedMinidump = true; const SIZE_T StackTraceSize = 65535; ANSICHAR* StackTrace = (ANSICHAR*) FMemory::Malloc( StackTraceSize ); StackTrace[0] = 0; // Walk the stack and dump it to the allocated memory. FPlatformStackWalk::StackWalkAndDump( StackTrace, StackTraceSize, 0, Context ); #if WITH_EDITORONLY_DATA FCString::Strncat( GErrorHist, ANSI_TO_TCHAR(StackTrace), ARRAY_COUNT(GErrorHist) - 1 ); CreateExceptionInfoString(Signal, Info); #endif FMemory::Free( StackTrace ); } return 0; }
FString FDesktopPlatformBase::GetEngineSavedConfigDirectory(const FString& Identifier) { // Get the engine root directory FString RootDir; if (!GetEngineRootDirFromIdentifier(Identifier, RootDir)) { return FString(); } // Get the path to the game agnostic settings FString UserDir; if (IsStockEngineRelease(Identifier)) { UserDir = FPaths::Combine(FPlatformProcess::UserSettingsDir(), *FApp::GetEpicProductIdentifier(), *Identifier); } else { UserDir = FPaths::Combine(*RootDir, TEXT("Engine")); } // Get the game agnostic config dir return UserDir / TEXT("Saved/Config") / ANSI_TO_TCHAR(FPlatformProperties::PlatformName()); }
int32 ReportCrash(const FLinuxCrashContext & Context) { static bool GAlreadyCreatedMinidump = false; // Only create a minidump the first time this function is called. // (Can be called the first time from the RenderThread, then a second time from the MainThread.) if ( GAlreadyCreatedMinidump == false ) { GAlreadyCreatedMinidump = true; const SIZE_T StackTraceSize = 65535; ANSICHAR* StackTrace = (ANSICHAR*) FMemory::Malloc( StackTraceSize ); StackTrace[0] = 0; // Walk the stack and dump it to the allocated memory (ignore first 2 callstack lines as those are in stack walking code) FPlatformStackWalk::StackWalkAndDump( StackTrace, StackTraceSize, 2, const_cast< FLinuxCrashContext* >( &Context ) ); FCString::Strncat( GErrorHist, ANSI_TO_TCHAR(StackTrace), ARRAY_COUNT(GErrorHist) - 1 ); CreateExceptionInfoString(Context.Signal, Context.Info); FMemory::Free( StackTrace ); } return 0; }