[runtime] Terminate on IncorrectDereferenceException from ObjC weak property (#4126)

Issue: ObjC runtime gets a os_unfair_lock when accessing weak property.
If exception is thrown from _tryRetainImp this lock left unlocked,
so it will hang on `__ulock_wait` on the next access.
Interim workaround: terminate instead of exception propagating.

However TerminateWithUnhandledException causes stacktrace dump to fail
in debug mode because of CSSymbolOwnerGetSymbolWithAddress failed on
the same recursive os_unfair_lock attempt.
This commit is contained in:
Vladimir Ivanov
2020-04-22 11:10:06 +03:00
committed by GitHub
parent 777e6e856c
commit a39b496938
6 changed files with 29 additions and 4 deletions
+1
View File
@@ -601,6 +601,7 @@ class ObjHolder {
ObjHeader* obj_;
};
//! TODO Follow the Rule of Zero to prevent dangling on unintented copy ctor
class ExceptionObjHolder {
public:
explicit ExceptionObjHolder(const ObjHeader* obj) {
+1
View File
@@ -19,6 +19,7 @@
#include "Types.h"
#include "Exceptions.h"
#include "Memory.h"
constexpr size_t alignUp(size_t size, size_t alignment) {
return (size + alignment - 1) & ~(alignment - 1);
+1 -1
View File
@@ -46,7 +46,7 @@ extern "C" RUNTIME_NORETURN void Kotlin_ObjCExport_trapOnUndeclaredException(KRe
static char kotlinExceptionOriginChar;
static bool isExceptionOfType(KRef exception, const TypeInfo** types) {
for (int i = 0; types[i] != nullptr; ++i) {
if (types) for (int i = 0; types[i] != nullptr; ++i) {
// TODO: use fast instance check when possible.
if (IsInstance(exception, types[i])) return true;
}
+19 -1
View File
@@ -16,6 +16,9 @@
#if KONAN_OBJC_INTEROP
#import <Foundation/NSException.h>
#import <objc/objc-exception.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
@@ -95,7 +98,22 @@ BOOL _tryRetainImp(id self, SEL _cmd) {
// this is a regression for instances of Kotlin subclasses of Obj-C classes:
// loading a reference to such an object from Obj-C weak reference now fails on "wrong" thread
// unless the object is frozen.
return getBackRef(self)->tryAddRef();
try {
return getBackRef(self)->tryAddRef();
} catch (ExceptionObjHolder& e) {
// TODO: check for IncorrectDereferenceException and possible weak property access
@try {
// try and catch with objc_terminate: this is a workaround to terminate immediately
// with libc default_terminate_handler() to be called instead of custom `TerminateWithUnhandledException`.
// See `KonanTerminateHandler`.
// TerminateWithUnhandledException shall not be used here because in debug mode it uses
// CoreSymbolication framework (CSSymbolOwnerGetSymbolWithAddress) which fails at recursive retain lock.
[NSException raise:NSGenericException
format:@"Possible illegal attempt to access weak property from non-owning thread"];
} @catch (...) {
objc_terminate();
}
}
}
void releaseImp(id self, SEL _cmd) {
+6 -1
View File
@@ -14,6 +14,9 @@
* limitations under the License.
*/
#ifndef RUNTIME_SOURCEINFO_H
#define RUNTIME_SOURCEINFO_H
struct SourceInfo {
const char* fileName;
int lineNumber;
@@ -28,4 +31,6 @@ struct SourceInfo Kotlin_getSourceInfo(void* addr);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#endif // RUNTIME_SOURCEINFO_H
+1 -1
View File
@@ -16,6 +16,6 @@
#include "SourceInfo.h"
extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) {
struct SourceInfo Kotlin_getSourceInfo(void* addr) {
return (SourceInfo) { .fileName = nullptr, .lineNumber = -1, .column = -1 };
}