Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Commit

Permalink
minor: PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Ivanov committed Jun 8, 2020
1 parent d3c5515 commit 68b5bc3
Showing 1 changed file with 34 additions and 36 deletions.
70 changes: 34 additions & 36 deletions runtime/src/main/cpp/Exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,14 @@ NO_INLINE OBJ_GETTER0(Kotlin_getCurrentStackTrace) {
RETURN_OBJ(result.obj());
#else
const int maxSize = 32;
void *buffer[maxSize];
void* buffer[maxSize];

int size = backtrace(buffer, maxSize);
if (size < kSkipFrames)
return AllocArrayInstance(theNativePtrArrayTypeInfo, 0, OBJ_RESULT);

ObjHolder resultHolder;
ObjHeader *result = AllocArrayInstance(theNativePtrArrayTypeInfo, size - kSkipFrames, resultHolder.slot());
ObjHeader* result = AllocArrayInstance(theNativePtrArrayTypeInfo, size - kSkipFrames, resultHolder.slot());
for (int index = kSkipFrames; index < size; ++index) {
Kotlin_NativePtrArray_set(result, index - kSkipFrames, buffer[index]);
}
Expand All @@ -151,7 +151,7 @@ OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace) {
#else
uint32_t size = stackTrace->array()->count_;
ObjHolder resultHolder;
ObjHeader *strings = AllocArrayInstance(theArrayTypeInfo, size, resultHolder.slot());
ObjHeader* strings = AllocArrayInstance(theArrayTypeInfo, size, resultHolder.slot());
#if USE_GCC_UNWIND
for (int index = 0; index < size; ++index) {
KNativePtr address = Kotlin_NativePtrArray_get(stackTrace, index);
Expand All @@ -173,8 +173,8 @@ OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace) {

for (int index = 0; index < size; ++index) {
auto sourceInfo = Kotlin_getSourceInfo(*PrimitiveArrayAddressOfElementAt<KNativePtr>(stackTrace->array(), index));
const char *symbol = symbols[index];
const char *result;
const char* symbol = symbols[index];
const char* result;
char line[1024];
if (sourceInfo.fileName != nullptr) {
if (sourceInfo.lineNumber != -1) {
Expand Down Expand Up @@ -212,16 +212,14 @@ void ThrowException(KRef exception) {

OBJ_GETTER(Kotlin_setUnhandledExceptionHook, KRef hook) {
RETURN_RESULT_OF(SwapHeapRefLocked,
&currentUnhandledExceptionHook, currentUnhandledExceptionHook, hook,
&currentUnhandledExceptionHookLock,
&currentUnhandledExceptionHookCookie);
&currentUnhandledExceptionHook, currentUnhandledExceptionHook, hook, &currentUnhandledExceptionHookLock,
&currentUnhandledExceptionHookCookie);
}

void OnUnhandledException(KRef throwable) {
ObjHolder handlerHolder;
auto *handler = SwapHeapRefLocked(&currentUnhandledExceptionHook, currentUnhandledExceptionHook, nullptr,
&currentUnhandledExceptionHookLock, &currentUnhandledExceptionHookCookie,
handlerHolder.slot());
auto* handler = SwapHeapRefLocked(&currentUnhandledExceptionHook, currentUnhandledExceptionHook, nullptr,
&currentUnhandledExceptionHookLock, &currentUnhandledExceptionHookCookie, handlerHolder.slot());
if (handler == nullptr) {
ReportUnhandledException(throwable);
} else {
Expand All @@ -236,7 +234,7 @@ class {
* Timeout 5 sec for concurrent (second) terminate attempt to give a chance the first one to finish.
* If the terminate handler hangs for 5 sec it is probably fatally broken, so let's do abnormal _Exit in that case.
*/
unsigned int timeout = 5;
unsigned int timeoutSec = 5;
std::atomic_flag terminatingFlag = ATOMIC_FLAG_INIT;
public:
template <class Fun> RUNTIME_NORETURN void operator()(Fun block) {
Expand All @@ -245,7 +243,7 @@ class {
// block() is supposed to be NORETURN, otherwise go to normal abort()
konan::abort();
} else {
sleep(timeout);
sleep(timeoutSec);
// We come here when another terminate handler hangs for 5 sec, that looks fatally broken. Go to forced exit now.
}
_Exit(EXIT_FAILURE); // force exit
Expand All @@ -259,7 +257,7 @@ void reportUnhandledException(KRef throwable) {
#endif
}

}
} // namespace

RUNTIME_NORETURN void TerminateWithUnhandledException(KRef throwable) {
concurrentTerminateWrapper([=]() {
Expand All @@ -277,41 +275,41 @@ class TerminateHandler {

// In fact, it's safe to call my_handler directly from outside: it will do the job and then invoke original handler,
// even if it has not been initialized yet. So one may want to make it public and/or not the class member
RUNTIME_NORETURN static void kotlinHandler () {
RUNTIME_NORETURN static void kotlinHandler() {
concurrentTerminateWrapper([]() {
if (auto currentException = std::current_exception()) {
try {
std::rethrow_exception(currentException);
} catch (ExceptionObjHolder &e) {
reportUnhandledException(e.obj());
konan::abort();
} catch (...) {
// Not a Kotlin exception - pass throw to default handler
}
if (auto currentException = std::current_exception()) {
try {
std::rethrow_exception(currentException);
} catch (ExceptionObjHolder& e) {
reportUnhandledException(e.obj());
konan::abort();
} catch (...) {
// Not a Kotlin exception - call default handler
instance()->queuedHandler_();
}
// Come here in case of direct terminate() call or unknown exception - go to default terminate handler.
instance()->queuedHandler_();
}
// Come here in case of direct terminate() call or unknown exception - go to default terminate handler.
instance()->queuedHandler_();
});
}

/// Use machinery like Meyers singleton to provide thread safety
}

typedef __attribute__((noreturn)) void (*QH)();
using QH = __attribute__((noreturn)) void(*)();
QH queuedHandler_;

/// Use machinery like Meyers singleton to provide thread safety
TerminateHandler()
: queuedHandler_((QH)std::set_terminate(kotlinHandler)) {}

static TerminateHandler *instance() {
static TerminateHandler *singleton = new TerminateHandler();
static TerminateHandler* instance() {
static TerminateHandler* singleton [[clang::no_destroy]] = new TerminateHandler();
return singleton;
}

// Copy, move and assign would be safe, but not much useful, so let's delete all (rule of 5)
TerminateHandler(const TerminateHandler &) = delete;
TerminateHandler(TerminateHandler &&) = delete;
TerminateHandler &operator=(const TerminateHandler &) = delete;
TerminateHandler &operator=(TerminateHandler &&) = delete;
TerminateHandler(const TerminateHandler&) = delete;
TerminateHandler(TerminateHandler&&) = delete;
TerminateHandler& operator=(const TerminateHandler&) = delete;
TerminateHandler& operator=(TerminateHandler&&) = delete;
// Dtor might be in use to restore original handler. However, consequent install
// will not reconstruct handler anyway, so let's keep dtor deleted to avoid confusion.
~TerminateHandler() = delete;
Expand Down

0 comments on commit 68b5bc3

Please sign in to comment.