Compare commits

...

1 Commits

Author SHA1 Message Date
Benjamin Doherty
f3da96d424 Throw an NSException on Apple platforms when panicking 2024-03-27 16:04:49 -07:00
5 changed files with 107 additions and 5 deletions

View File

@@ -87,6 +87,7 @@ if (LINUX OR ANDROID)
list(APPEND SRCS src/linux/Path.cpp)
endif()
if (APPLE)
list(APPEND SRCS src/darwin/Exception.mm)
list(APPEND SRCS src/darwin/Path.mm)
list(APPEND SRCS src/darwin/Systrace.cpp)
endif()
@@ -122,6 +123,10 @@ if (LINUX)
target_link_libraries(${TARGET} PRIVATE dl)
endif()
if (APPLE AND NOT IOS)
target_link_libraries(${TARGET} PRIVATE "-framework Cocoa")
endif()
# ==================================================================================================
# Installation
# ==================================================================================================

View File

@@ -258,6 +258,18 @@ public:
*/
virtual const char* what() const noexcept = 0;
/**
* Get the reason for the panic.
* @return a C string containing the reason for the panic.
*/
virtual const char* getReason() const noexcept = 0;
/**
* Get the type of the panic. When compiled without RTTI, this returns a generic type name.
* @return a C string containing the type of the panic.
*/
virtual const char* getType() const noexcept = 0;
/**
* Get the function name where the panic was detected
* @return a C string containing the function name where the panic was detected
@@ -305,6 +317,8 @@ public:
const char* what() const noexcept override;
// Panic interface
const char* getReason() const noexcept override;
const char* getType() const noexcept override;
const char* getFunction() const noexcept override;
const char* getFile() const noexcept override;
int getLine() const noexcept override;
@@ -369,7 +383,8 @@ private:
char const* const m_function = nullptr;
char const* const m_file = nullptr;
const int m_line = -1;
mutable std::string m_msg;
std::string m_msg;
std::string m_type;
};
namespace details {

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_UTILS_DARWIN_EXCEPTION_H
#define TNT_UTILS_DARWIN_EXCEPTION_H
#include <utils/Panic.h>
#include <utils/compiler.h>
namespace utils::details {
void throwDarwinException(const Panic& exception) UTILS_NORETURN;
}
#endif // TNT_UTILS_DARWIN_EXCEPTION_H

View File

@@ -16,6 +16,10 @@
#include <utils/Panic.h>
#if defined(__APPLE__)
#include <utils/darwin/Exception.h>
#endif
#include <atomic>
#include <cstdarg>
#include <cstdlib>
@@ -88,6 +92,16 @@ const char* TPanic<T>::what() const noexcept {
return m_msg.c_str();
}
template<typename T>
const char* TPanic<T>::getReason() const noexcept {
return m_reason.c_str();
}
template<typename T>
const char* TPanic<T>::getType() const noexcept {
return m_type.c_str();
}
template<typename T>
const char* TPanic<T>::getFunction() const noexcept {
return m_function;
@@ -116,13 +130,12 @@ void TPanic<T>::log() const noexcept {
template<typename T>
void TPanic<T>::buildMessage() {
std::string type;
#if UTILS_HAS_RTTI
type = CallStack::demangleTypeName(typeid(T).name()).c_str();
m_type = CallStack::demangleTypeName(typeid(T).name()).c_str();
#else
type = "Panic";
m_type = "Panic";
#endif
m_msg = panicString(type, m_function, m_line, m_file, m_reason.c_str());
m_msg = panicString(m_type, m_function, m_line, m_file, m_reason.c_str());
}
UTILS_ALWAYS_INLINE
@@ -139,6 +152,11 @@ void TPanic<T>::panic(char const* function, char const* file, int line, const ch
va_end(args);
T e(function, formatFile(file), line, reason);
e.log();
#if defined(__APPLE__)
details::throwDarwinException(e);
#endif
#ifdef __EXCEPTIONS
throw e;
#endif

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <utils/Panic.h>
#include <Foundation/Foundation.h>
namespace utils::details {
void throwDarwinException(const Panic& exception) {
// Turn this exception into an NSException and raise it.
// This is allowed even if we're built without Objective-C exceptions (-fno-objc-exceptions).
[[NSException exceptionWithName:@(exception.getType())
reason:@(exception.getReason())
userInfo:@{
@"file" : @(exception.getFile()),
@"line" : @(exception.getLine()),
@"function" : @(exception.getFunction())
}] raise];
}
}