Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Detect if a process runs under Rosetta 2 on Apple Silicon M1 or native. Works for macOS and iOS.
@objc(PSTArchitecture) class Architecture: NSObject {
/// Check if process runs under Rosetta 2.
///
/// Use to disable tests that use WebKit when running on Apple Silicon
/// FB8920323: Crash in WebKit memory allocator on Apple Silicon when iOS below 14
/// Crash is in JavaScriptCore: bmalloc::HeapConstants::HeapConstants(std::__1::lock_guard<bmalloc::Mutex> const&)
@objc class var isRosettaEmulated: Bool {
// Issue is specific to Simulator, not real devices
#if targetEnvironment(simulator)
return processIsTranslated() == EMULATED_EXECUTION
#else
return false
#endif
}
}
let NATIVE_EXECUTION = Int32(0)
let EMULATED_EXECUTION = Int32(1)
let UNKNOWN_EXECUTION = -Int32(1)
/// Test if the process runs natively or under Rosetta
/// https://developer.apple.com/forums/thread/652667?answerId=618217022&page=1#622923022
private func processIsTranslated() -> Int32 {
let key = "sysctl.proc_translated"
var ret = Int32(0)
var size: Int = 0
sysctlbyname(key, nil, &size, nil, 0)
let result = sysctlbyname(key, &ret, &size, nil, 0)
if result == -1 {
if errno == ENOENT {
return 0
}
return -1
}
return ret
}
@steipete

This comment has been minimized.

Copy link
Owner Author

@steipete steipete commented Nov 29, 2020

This works around the WebKit/JavaScriptCore memory allocator issue mentioned in https://steipete.com/posts/apple-silicon-m1-a-developer-perspective/

Usage: (Our iOS PDF SDK offers a Reader Mode "liquid mode" to reformat PDF documents for small screens. Formatted text is extracted and displayed via WKWebView. This initializes WebKit and doesn't currently work on Apple Silicon when running on iOS < 14.)

final class ReaderViewTests: EarlGreyTestCase {

    func testReflowedDocumentContainsHTML() {
        guard !Architecture.isRosettaEmulated else { return }

		// Test Code
	}
}

A typical crash log looks like this:

Exception Type:        EXC_BREAKPOINT (SIGTRAP)
Exception Codes:       0x0000000000000002, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   <translation info unavailable>	0x0000000106cd964c ???
1   <translation info unavailable>	0x0000000106cd6330 ???
2   com.apple.JavaScriptCore      	0x0000000118d06a8d bmalloc::StaticPerProcess<bmalloc::HeapConstants>::getSlowCase() + 77
3   com.apple.JavaScriptCore      	0x0000000118d02dc8 bmalloc::Heap::Heap(bmalloc::HeapKind, std::__1::lock_guard<bmalloc::Mutex>&) + 56
4   com.apple.JavaScriptCore      	0x0000000118cff865 bmalloc::PerProcess<bmalloc::PerHeapKind<bmalloc::Heap> >::getSlowCase() + 181
5   com.apple.JavaScriptCore      	0x0000000118d000c5 bmalloc::PerHeapKindBase<bmalloc::Cache>::PerHeapKindBase<>() + 37
6   com.apple.JavaScriptCore      	0x0000000118cffae6 bmalloc::PerThread<bmalloc::PerHeapKind<bmalloc::Cache> >::getSlowCase() + 102
7   com.apple.JavaScriptCore      	0x0000000118cffba1 bmalloc::Cache::allocateSlowCaseNullCache(bmalloc::HeapKind, unsigned long) + 129
8   com.apple.JavaScriptCore      	0x0000000118cacf82 void std::__1::__call_once_proxy<std::__1::tuple<WTF::activeThreads()::$_3&&> >(void*) + 82
9   libc++.1.dylib                	0x000000010bed2c8a std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) + 139
10  com.apple.JavaScriptCore      	0x0000000118cacf1c WTF::SignalHandlers::initialize() + 60
11  com.apple.JavaScriptCore      	0x0000000118cc4652 void std::__1::__call_once_proxy<std::__1::tuple<WTF::initializeThreading()::$_0&&> >(void*) + 34
12  libc++.1.dylib                	0x000000010bed2c8a std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) + 139
13  com.apple.JavaScriptCore      	0x0000000118cc268c WTF::initializeThreading() + 60
14  com.apple.JavaScriptCore      	0x0000000119548dbc void std::__1::__call_once_proxy<std::__1::tuple<JSC::initializeThreading()::$_0&&> >(void*) + 12
15  libc++.1.dylib                	0x000000010bed2c8a std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) + 139
16  com.apple.JavaScriptCore      	0x00000001195445fc JSC::initializeThreading() + 60
17  com.apple.WebKit              	0x000000013e245cfc WebKit::runInitializationCode(void*) + 19
18  libc++.1.dylib                	0x000000010bed2c8a std::__1::__call_once(unsigned long volatile&, void*, void (*)(void*)) + 139
19  com.apple.WebKit              	0x000000013e24284a WebKit::InitializeWebKit2() + 58
@mladenny

This comment has been minimized.

Copy link

@mladenny mladenny commented Nov 29, 2020

You have a typo on row 19: UNKONWNUNKNOWN 😃

@steipete

This comment has been minimized.

Copy link
Owner Author

@steipete steipete commented Nov 29, 2020

@mladenny Thanks, fixed!

@faisalmemon

This comment has been minimized.

Copy link

@faisalmemon faisalmemon commented Nov 30, 2020

@steipete I'd be most grateful if you could post the full crash dump, perhaps onto pastebin.com, because I am researching Rosetta 2 crashes with WebKit (and Safari) at the moment for my book (iOS Crash Dump Analysis).

@steipete

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment