Kill orphaned instruments processes (#819)

Summary:
Fix https://github.com/facebook/flipper/issues/808
Kills any orphaned Instruments processes belonging to the user.

In some cases, we've seen interactions between Instruments and the iOS
simulator that cause hung instruments and DTServiceHub processes. If
enough instances pile up, the host machine eventually becomes
unresponsive. Until the underlying issue is resolved, manually kill any
orphaned instances (where the parent process has died and PPID is 1)
before launching another instruments run.

Taking the same approach as done by flutter here.

Reviewed By: passy

Differential Revision: D20030005

Pulled By: jknoxville

fbshipit-source-id: aa80be78c80f7797e88bf29b15f90d4aad0c66e4
This commit is contained in:
John Knox
2020-02-21 06:52:04 -08:00
committed by Facebook Github Bot
parent 4aec81b059
commit c2dfa6ca6b
2 changed files with 43 additions and 0 deletions

View File

@@ -10,6 +10,7 @@
import {DeviceType} from '../devices/BaseDevice';
import {exec} from 'promisify-child-process';
import {notNull} from '../utils/typeUtils';
import {killOrphanedInstrumentsProcesses} from '../utils/processCleanup';
const errorMessage = 'Physical iOS devices not yet supported';
@@ -24,6 +25,7 @@ function isAvailable(): boolean {
}
async function targets(): Promise<Array<DeviceTarget>> {
await killOrphanedInstrumentsProcesses();
const {stdout} = await exec('instruments -s devices');
if (!stdout) {
return [];

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {exec} from 'promisify-child-process';
import {notNull} from '../utils/typeUtils';
import {kill} from 'process';
// Kills any orphaned Instruments processes belonging to the user.
//
// In some cases, we've seen interactions between Instruments and the iOS
// simulator that cause hung instruments and DTServiceHub processes. If
// enough instances pile up, the host machine eventually becomes
// unresponsive. Until the underlying issue is resolved, manually kill any
// orphaned instances (where the parent process has died and PPID is 1)
// before launching another instruments run.
export async function killOrphanedInstrumentsProcesses() {
const result = await exec('ps -e -o user,ppid,pid,comm');
result.stdout
?.toString()
.split('\n')
.filter(notNull)
.map(a => /^(\S+)\s+1\s+(\d+)\s+(.+)$/.exec(a))
.filter(notNull)
.filter(m => m[1] === process.env.USER)
.filter(
m =>
m[3] &&
['/instruments', '/DTServiceHub'].some(name => m[3].endsWith(name)),
)
.forEach(m => {
const pid = m[2];
console.debug(`Killing orphaned Instruments process: ${pid}`);
kill(parseInt(pid, 10), 'SIGKILL');
});
}