Backed out changeset f8ef3d7a6294 (bug 1827651) for causing NSWorkspace related assertions CLOSED TREE

This commit is contained in:
Noemi Erli 2023-09-20 19:13:08 +03:00
Родитель d113647ced
Коммит aaff5e1a23
2 изменённых файлов: 65 добавлений и 37 удалений

Просмотреть файл

@ -86,31 +86,72 @@ bool IsBinaryArmExecutable(const char* executablePath) {
return isArmExecutable;
}
// Returns true if the executable provided in |executablePath| should be
// launched with a preference for arm64. After updating from an x64 version
// running under Rosetta, if the update is to a universal binary with arm64
// support we want to switch to arm64 execution mode. Returns true if those
// conditions are met and the arch(1) utility at |archPath| is executable.
// It should be safe to always launch with arch and fallback to x64, but we
// limit its use to the only scenario it is necessary to minimize risk.
bool ShouldPreferArmLaunch(const char* archPath, const char* executablePath) {
// If not running under Rosetta, we are not on arm64 hardware.
if (!IsProcessRosettaTranslated()) {
return false;
}
// Ensure the arch(1) utility is present and executable.
NSFileManager* fileMgr = [NSFileManager defaultManager];
NSString* archPathString = [NSString stringWithUTF8String:archPath];
if (![fileMgr isExecutableFileAtPath:archPathString]) {
return false;
}
// Ensure the binary can be run natively on arm64.
return IsBinaryArmExecutable(executablePath);
}
#endif // __x86_64__
void LaunchChild(int argc, const char** argv) {
MacAutoreleasePool pool;
@try {
NSString* launchPath = [NSString stringWithUTF8String:argv[0]];
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argc - 1];
bool preferArmLaunch = false;
#if defined(__x86_64__)
// When running under Rosetta, child processes inherit the architecture
// preference of their parent and therefore universal binaries launched
// by an emulated x64 process will launch in x64 mode. If we are running
// under Rosetta, launch the child process with a preference for arm64 so
// that we will switch to arm64 execution if we have just updated from
// x64 to a universal build. This includes if we were already a universal
// build and the user is intentionally running under Rosetta.
preferArmLaunch = ShouldPreferArmLaunch(ARCH_PATH, argv[0]);
#endif // __x86_64__
NSString* launchPath;
NSMutableArray* arguments;
if (preferArmLaunch) {
launchPath = [NSString stringWithUTF8String:ARCH_PATH];
// Size the arguments array to include all the arguments
// in |argv| plus two arguments to pass to the arch(1) utility.
arguments = [NSMutableArray arrayWithCapacity:argc + 2];
[arguments addObject:[NSString stringWithUTF8String:"-arm64"]];
[arguments addObject:[NSString stringWithUTF8String:"-x86_64"]];
// Add the first argument from |argv|. The rest are added below.
[arguments addObject:[NSString stringWithUTF8String:argv[0]]];
} else {
launchPath = [NSString stringWithUTF8String:argv[0]];
arguments = [NSMutableArray arrayWithCapacity:argc - 1];
}
for (int i = 1; i < argc; i++) {
[arguments addObject:[NSString stringWithUTF8String:argv[i]]];
}
NSWorkspaceOpenConfiguration* config =
[NSWorkspaceOpenConfiguration configuration];
[config setArguments:arguments];
[config setCreatesNewApplicationInstance:YES];
[[NSWorkspace sharedWorkspace]
openApplicationAtURL:[NSURL URLWithString:launchPath]
configuration:config
completionHandler:^(NSRunningApplication* child, NSError* error) {
if (error) {
NSLog(@"Failed to run: %@", error);
}
}];
[NSTask launchedTaskWithLaunchPath:launchPath arguments:arguments];
} @catch (NSException* e) {
NSLog(@"%@: %@", e.name, e.reason);
}

Просмотреть файл

@ -26,28 +26,15 @@ void LaunchChildMac(int aArgc, char** aArgv, pid_t* aPid) {
for (int i = 1; i < aArgc; i++) {
[arguments addObject:[NSString stringWithUTF8String:aArgv[i]]];
}
__block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSWorkspaceOpenConfiguration* config =
[NSWorkspaceOpenConfiguration configuration];
[config setArguments:arguments];
[config setCreatesNewApplicationInstance:YES];
[[NSWorkspace sharedWorkspace]
openApplicationAtURL:[NSURL URLWithString:launchPath]
configuration:config
completionHandler:^(NSRunningApplication* child, NSError* error) {
if (error) {
NSLog(@"Failed to run: %@", error);
}
if (aPid) {
*aPid = [child processIdentifier];
}
dispatch_semaphore_signal(semaphore);
}];
// We use a semaphore to wait for the application to launch.
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSTask* child = [NSTask launchedTaskWithLaunchPath:launchPath
arguments:arguments];
if (aPid) {
*aPid = [child processIdentifier];
// We used to use waitpid to wait for the process to terminate. This is
// incompatible with NSTask and we wait for the process to exit here
// instead.
[child waitUntilExit];
}
} @catch (NSException* e) {
NSLog(@"%@: %@", e.name, e.reason);
}