Merge branch 'FlaxEngine:master' into master
This commit is contained in:
@@ -280,17 +280,25 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
const Char* gradlew = TEXT("gradlew");
|
const Char* gradlew = TEXT("gradlew");
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_LINUX
|
#if PLATFORM_LINUX
|
||||||
Platform::RunProcess(String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath), data.OriginalOutputPath, Dictionary<String, String>(), true);
|
{
|
||||||
|
CreateProcessSettings procSettings;
|
||||||
|
procSettings.FileName = String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath);
|
||||||
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
|
procSettings.HiddenWindow = true;
|
||||||
|
Platform::CreateProcess(procSettings);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
const bool distributionPackage = buildSettings->ForDistribution;
|
const bool distributionPackage = buildSettings->ForDistribution;
|
||||||
CreateProcessSettings procSettings;
|
|
||||||
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
|
||||||
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
|
||||||
const int32 result = Platform::CreateProcess(procSettings);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
{
|
||||||
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
|
CreateProcessSettings procSettings;
|
||||||
return true;
|
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
||||||
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
|
const int32 result = Platform::CreateProcess(procSettings);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy result package
|
// Copy result package
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ void VisualStudioCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
|||||||
|
|
||||||
// Detect Flatpak installations
|
// Detect Flatpak installations
|
||||||
{
|
{
|
||||||
if (Platform::RunProcess(TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\""), String::Empty) == 0)
|
CreateProcessSettings procSettings;
|
||||||
|
procSettings.FileName = TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\"");
|
||||||
|
procSettings.HiddenWindow = true;
|
||||||
|
if (Platform::CreateProcess(procSettings) == 0)
|
||||||
{
|
{
|
||||||
const String runPath(TEXT("flatpak run com.visualstudio.code"));
|
const String runPath(TEXT("flatpak run com.visualstudio.code"));
|
||||||
output->Add(New<VisualStudioCodeEditor>(runPath, false));
|
output->Add(New<VisualStudioCodeEditor>(runPath, false));
|
||||||
|
|||||||
@@ -51,6 +51,33 @@
|
|||||||
#include <android/window.h>
|
#include <android/window.h>
|
||||||
#include <android/versioning.h>
|
#include <android/versioning.h>
|
||||||
|
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
|
||||||
|
#include <unwind.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
struct AndroidBacktraceState
|
||||||
|
{
|
||||||
|
void** Current;
|
||||||
|
void** End;
|
||||||
|
};
|
||||||
|
|
||||||
|
_Unwind_Reason_Code AndroidUnwindCallback(struct _Unwind_Context* context, void* arg)
|
||||||
|
{
|
||||||
|
AndroidBacktraceState* state = (AndroidBacktraceState*)arg;
|
||||||
|
uintptr_t pc = _Unwind_GetIP(context);
|
||||||
|
if (pc)
|
||||||
|
{
|
||||||
|
if (state->Current == state->End)
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
else
|
||||||
|
*state->Current++ = reinterpret_cast<void*>(pc);
|
||||||
|
}
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct AndroidKeyEventType
|
struct AndroidKeyEventType
|
||||||
{
|
{
|
||||||
uint32_t KeyCode;
|
uint32_t KeyCode;
|
||||||
@@ -1066,4 +1093,45 @@ void* AndroidPlatform::GetProcAddress(void* handle, const char* symbol)
|
|||||||
return dlsym(handle, symbol);
|
return dlsym(handle, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<AndroidPlatform::StackFrame> AndroidPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
|
||||||
|
{
|
||||||
|
Array<StackFrame> result;
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
// Reference: https://stackoverflow.com/questions/8115192/android-ndk-getting-the-backtrace
|
||||||
|
void* callstack[120];
|
||||||
|
skipCount = Math::Min<int32>(skipCount, ARRAY_COUNT(callstack));
|
||||||
|
int32 maxCount = Math::Min<int32>(ARRAY_COUNT(callstack), skipCount + maxDepth);
|
||||||
|
AndroidBacktraceState state;
|
||||||
|
state.Current = callstack;
|
||||||
|
state.End = callstack + maxCount;
|
||||||
|
_Unwind_Backtrace(AndroidUnwindCallback, &state);
|
||||||
|
int32 count = (int32)(state.Current - callstack);
|
||||||
|
int32 useCount = count - skipCount;
|
||||||
|
if (useCount > 0)
|
||||||
|
{
|
||||||
|
result.Resize(useCount);
|
||||||
|
for (int32 i = 0; i < useCount; i++)
|
||||||
|
{
|
||||||
|
StackFrame& frame = result[i];
|
||||||
|
frame.ProgramCounter = callstack[skipCount + i];
|
||||||
|
frame.ModuleName[0] = 0;
|
||||||
|
frame.FileName[0] = 0;
|
||||||
|
frame.LineNumber = 0;
|
||||||
|
Dl_info info;
|
||||||
|
const char* symbol = "";
|
||||||
|
if (dladdr(frame.ProgramCounter, &info) && info.dli_sname)
|
||||||
|
symbol = info.dli_sname;
|
||||||
|
int status = 0;
|
||||||
|
char* demangled = __cxxabiv1::__cxa_demangle(symbol, 0, 0, &status);
|
||||||
|
int32 nameLen = Math::Min<int32>(StringUtils::Length(demangled), ARRAY_COUNT(frame.FunctionName) - 1);
|
||||||
|
Platform::MemoryCopy(frame.FunctionName, demangled, nameLen);
|
||||||
|
frame.FunctionName[nameLen] = 0;
|
||||||
|
if (demangled)
|
||||||
|
free(demangled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ public:
|
|||||||
static void* LoadLibrary(const Char* filename);
|
static void* LoadLibrary(const Char* filename);
|
||||||
static void FreeLibrary(void* handle);
|
static void FreeLibrary(void* handle);
|
||||||
static void* GetProcAddress(void* handle, const char* symbol);
|
static void* GetProcAddress(void* handle, const char* symbol);
|
||||||
|
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,6 +50,10 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
#include <signal.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
CPUInfo UnixCpu;
|
CPUInfo UnixCpu;
|
||||||
int ClockSource;
|
int ClockSource;
|
||||||
@@ -1868,6 +1872,46 @@ void LinuxPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int3
|
|||||||
millisecond = time.tv_usec / 1000;
|
millisecond = time.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
|
||||||
|
bool LinuxPlatform::IsDebuggerPresent()
|
||||||
|
{
|
||||||
|
static int32 CachedState = -1;
|
||||||
|
if (CachedState == -1)
|
||||||
|
{
|
||||||
|
CachedState = 0;
|
||||||
|
|
||||||
|
// Reference: https://stackoverflow.com/questions/3596781/how-to-detect-if-the-current-process-is-being-run-by-gdb
|
||||||
|
char buf[4096];
|
||||||
|
const int status_fd = open("/proc/self/status", O_RDONLY);
|
||||||
|
if (status_fd == -1)
|
||||||
|
return false;
|
||||||
|
const ssize_t num_read = read(status_fd, buf, sizeof(buf) - 1);
|
||||||
|
close(status_fd);
|
||||||
|
if (num_read <= 0)
|
||||||
|
return false;
|
||||||
|
buf[num_read] = '\0';
|
||||||
|
constexpr char tracerPidString[] = "TracerPid:";
|
||||||
|
const auto tracer_pid_ptr = strstr(buf, tracerPidString);
|
||||||
|
if (!tracer_pid_ptr)
|
||||||
|
return false;
|
||||||
|
for (const char* characterPtr = tracer_pid_ptr + sizeof(tracerPidString) - 1; characterPtr <= buf + num_read; ++characterPtr)
|
||||||
|
{
|
||||||
|
if (StringUtils::IsWhitespace(*characterPtr))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (StringUtils::IsDigit(*characterPtr) && *characterPtr != '0')
|
||||||
|
CachedState = 1;
|
||||||
|
return CachedState == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CachedState == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
bool LinuxPlatform::Init()
|
bool LinuxPlatform::Init()
|
||||||
{
|
{
|
||||||
if (PlatformBase::Init())
|
if (PlatformBase::Init())
|
||||||
@@ -2992,4 +3036,36 @@ void* LinuxPlatform::GetProcAddress(void* handle, const char* symbol)
|
|||||||
return dlsym(handle, symbol);
|
return dlsym(handle, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<LinuxPlatform::StackFrame> LinuxPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
|
||||||
|
{
|
||||||
|
Array<StackFrame> result;
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
void* callstack[120];
|
||||||
|
skipCount = Math::Min<int32>(skipCount, ARRAY_COUNT(callstack));
|
||||||
|
int32 maxCount = Math::Min<int32>(ARRAY_COUNT(callstack), skipCount + maxDepth);
|
||||||
|
int32 count = backtrace(callstack, maxCount);
|
||||||
|
int32 useCount = count - skipCount;
|
||||||
|
if (useCount > 0)
|
||||||
|
{
|
||||||
|
char** names = backtrace_symbols(callstack + skipCount, useCount);
|
||||||
|
result.Resize(useCount);
|
||||||
|
for (int32 i = 0; i < useCount; i++)
|
||||||
|
{
|
||||||
|
char* name = names[i];
|
||||||
|
StackFrame& frame = result[i];
|
||||||
|
frame.ProgramCounter = callstack[skipCount + i];
|
||||||
|
frame.ModuleName[0] = 0;
|
||||||
|
frame.FileName[0] = 0;
|
||||||
|
frame.LineNumber = 0;
|
||||||
|
int32 nameLen = Math::Min<int32>(StringUtils::Length(name), ARRAY_COUNT(frame.FunctionName) - 1);
|
||||||
|
Platform::MemoryCopy(frame.FunctionName, name, nameLen);
|
||||||
|
frame.FunctionName[nameLen] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
free(names);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ public:
|
|||||||
}
|
}
|
||||||
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
static void GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond);
|
||||||
|
#if !BUILD_RELEASE
|
||||||
|
static bool IsDebuggerPresent();
|
||||||
|
#endif
|
||||||
static bool Init();
|
static bool Init();
|
||||||
static void BeforeRun();
|
static void BeforeRun();
|
||||||
static void Tick();
|
static void Tick();
|
||||||
@@ -143,6 +146,7 @@ public:
|
|||||||
static void* LoadLibrary(const Char* filename);
|
static void* LoadLibrary(const Char* filename);
|
||||||
static void FreeLibrary(void* handle);
|
static void FreeLibrary(void* handle);
|
||||||
static void* GetProcAddress(void* handle, const char* symbol);
|
static void* GetProcAddress(void* handle, const char* symbol);
|
||||||
|
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user