Merge remote-tracking branch 'origin/master'

This commit is contained in:
Wojtek Figat
2025-04-22 16:17:53 +02:00
4 changed files with 104 additions and 17 deletions

View File

@@ -274,6 +274,24 @@ void Engine::RequestExit(int32 exitCode, FatalErrorType error)
RequestingExit(); RequestingExit();
} }
#if !BUILD_SHIPPING
void Engine::Crash(FatalErrorType error)
{
switch (error)
{
case FatalErrorType::None:
case FatalErrorType::Exception:
*((int32*)3) = 11;
break;
default:
Platform::Fatal(TEXT("Crash Test"), nullptr, error);
break;
}
}
#endif
void Engine::OnFixedUpdate() void Engine::OnFixedUpdate()
{ {
PROFILE_CPU_NAMED("Fixed Update"); PROFILE_CPU_NAMED("Fixed Update");

View File

@@ -125,6 +125,14 @@ public:
/// <param name="error">The fatal error type (or None on graceful exit).</param> /// <param name="error">The fatal error type (or None on graceful exit).</param>
API_FUNCTION() static void RequestExit(int32 exitCode = 0, FatalErrorType error = FatalErrorType::None); API_FUNCTION() static void RequestExit(int32 exitCode = 0, FatalErrorType error = FatalErrorType::None);
#if !BUILD_SHIPPING
/// <summary>
/// Crashes the engine. Utility used to test crash reporting or game stability monitoring systems.
/// </summary>
/// <param name="error">The fatal error type.</param>
API_FUNCTION(Attributes="DebugCommand") static void Crash(FatalErrorType error = FatalErrorType::Exception);
#endif
public: public:
/// <summary> /// <summary>
/// Fixed update callback used by the physics simulation (fixed stepping). /// Fixed update callback used by the physics simulation (fixed stepping).

View File

@@ -209,7 +209,7 @@ Ray Camera::ConvertMouseToRay(const Float2& mousePosition) const
Ray Camera::ConvertMouseToRay(const Float2& mousePosition, const Viewport& viewport) const Ray Camera::ConvertMouseToRay(const Float2& mousePosition, const Viewport& viewport) const
{ {
Vector3 position = GetPosition(); Vector3 position = GetPosition();
if (viewport.Width < ZeroTolerance || viewport.Height < ZeroTolerance) if (viewport.Width < ZeroTolerance || viewport.Height < ZeroTolerance || mousePosition.IsNaN())
return Ray(position, GetDirection()); return Ray(position, GetDirection());
// Use different logic in orthographic projection // Use different logic in orthographic projection

View File

@@ -58,6 +58,43 @@ int32 AutoreleasePoolInterval = 0;
float ApplePlatform::ScreenScale = 1.0f; float ApplePlatform::ScreenScale = 1.0f;
static void CrashHandler(int32 signal, siginfo_t* info, void* context)
{
// Skip if engine already crashed
if (Engine::FatalError != FatalErrorType::None)
return;
// Get exception info
String errorMsg(TEXT("Unhandled exception: "));
switch (signal)
{
#define CASE(x) case x: errorMsg += TEXT(#x); break
CASE(SIGABRT);
CASE(SIGILL);
CASE(SIGSEGV);
CASE(SIGQUIT);
CASE(SIGEMT);
CASE(SIGFPE);
CASE(SIGBUS);
CASE(SIGSYS);
#undef CASE
default:
errorMsg += StringUtils::ToString(signal);
}
// Log exception and return to the crash location when using debugger
if (Platform::IsDebuggerPresent())
{
LOG_STR(Error, errorMsg);
const String stackTrace = Platform::GetStackTrace(3, 60, nullptr);
LOG_STR(Error, stackTrace);
return;
}
// Crash engine
Platform::Fatal(errorMsg.Get(), nullptr, FatalErrorType::Exception);
}
String AppleUtils::ToString(CFStringRef str) String AppleUtils::ToString(CFStringRef str)
{ {
if (!str) if (!str)
@@ -90,41 +127,50 @@ NSString* AppleUtils::ToNSString(const char* string)
return ret ? ret : @""; return ret ? ret : @"";
} }
NSArray* AppleUtils::ParseArguments(NSString* argsString)
NSArray* AppleUtils::ParseArguments(NSString* argsString) { {
NSMutableArray *argsArray = [NSMutableArray array]; NSMutableArray* argsArray = [NSMutableArray array];
NSMutableString *currentArg = [NSMutableString string]; NSMutableString* currentArg = [NSMutableString string];
BOOL insideQuotes = NO; BOOL insideQuotes = NO;
for (NSInteger i = 0; i < argsString.length; ++i) { for (NSInteger i = 0; i < argsString.length; i++)
{
unichar c = [argsString characterAtIndex:i]; unichar c = [argsString characterAtIndex:i];
if (c == '\"')
if (c == '\"') { {
if (insideQuotes) { if (insideQuotes)
{
[argsArray addObject:[currentArg copy]]; [argsArray addObject:[currentArg copy]];
[currentArg setString:@""]; [currentArg setString:@""];
insideQuotes = NO; insideQuotes = NO;
} else { }
else
{
insideQuotes = YES; insideQuotes = YES;
} }
} else if (c == ' ' && !insideQuotes) { }
if (currentArg.length > 0) { else if (c == ' ' && !insideQuotes)
{
if (currentArg.length > 0)
{
[argsArray addObject:[currentArg copy]]; [argsArray addObject:[currentArg copy]];
[currentArg setString:@""]; [currentArg setString:@""];
} }
} else { }
else
{
[currentArg appendFormat:@"%C", c]; [currentArg appendFormat:@"%C", c];
} }
} }
if (currentArg.length > 0) { if (currentArg.length > 0)
{
[argsArray addObject:[currentArg copy]]; [argsArray addObject:[currentArg copy]];
} }
return [argsArray copy]; return [argsArray copy];
} }
typedef uint16_t offset_t; typedef uint16_t offset_t;
#define align_mem_up(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) #define align_mem_up(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
@@ -376,6 +422,21 @@ bool ApplePlatform::Init()
setrlimit(RLIMIT_NOFILE, &limit); setrlimit(RLIMIT_NOFILE, &limit);
} }
// Register crash handler
struct sigaction action;
Platform::MemoryClear(&action, sizeof(action));
action.sa_sigaction = CrashHandler;
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction(SIGABRT, &action, nullptr);
sigaction(SIGILL, &action, nullptr);
sigaction(SIGSEGV, &action, nullptr);
sigaction(SIGQUIT, &action, nullptr);
sigaction(SIGEMT, &action, nullptr);
sigaction(SIGFPE, &action, nullptr);
sigaction(SIGBUS, &action, nullptr);
sigaction(SIGSYS, &action, nullptr);
AutoreleasePool = [[NSAutoreleasePool alloc] init]; AutoreleasePool = [[NSAutoreleasePool alloc] init];
return false; return false;