Skip to content

Instantly share code, notes, and snippets.

@steipete
Last active December 8, 2022 15:47
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steipete/e15b1fabffc7da7d49c92e3fbd06971a to your computer and use it in GitHub Desktop.
Save steipete/e15b1fabffc7da7d49c92e3fbd06971a to your computer and use it in GitHub Desktop.
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
}
@Deco354
Copy link

Deco354 commented Jan 24, 2022

If you're implementing this yourself, don't omit the @objc and NSObject inheritance or you'll get a -1 result from processIsTranslated() every time.

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