Skip to content

Instantly share code, notes, and snippets.

@adapptor-kurt
Created August 14, 2020 01:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adapptor-kurt/82384af67ee876d7d6d6239180127ff4 to your computer and use it in GitHub Desktop.
Save adapptor-kurt/82384af67ee876d7d6d6239180127ff4 to your computer and use it in GitHub Desktop.
Helps Flipper connect to physical iOS devices more reliably.
#!/usr/bin/env python3
# See https://github.com/facebook/flipper/issues/262
import os
import sys
import syslog
import shlex
import time
import subprocess
idb_command_args = ['idb'] + sys.argv[1:]
idb_command_str = ' '.join([shlex.quote(arg) for arg in idb_command_args])
def main():
udid = None
is_file_command = False
i = 1
while i < len(sys.argv):
if sys.argv[i] == '--udid':
# Save udid
i = i + 1
udid = sys.argv[i]
elif sys.argv[i][:2] == '--':
# Ignore other flag arg
i = i + 1
elif sys.argv[i] == 'file':
# This needs our help
is_file_command = True
i = i + 1
if is_file_command:
return run_with_workarounds(udid)
else:
return os.system(idb_command_str)
def run_with_timeout(timeout_secs, command_args):
p = subprocess.Popen(command_args)
try:
p.wait(timeout_secs)
return p.returncode
except subprocess.TimeoutExpired:
p.kill()
return 1
def run_with_workarounds(udid):
code = run_with_timeout(2, idb_command_args)
if code == 0:
return code
syslog.syslog(syslog.LOG_ALERT, "idb-workaround Failed attempt 1/4")
# Attempt 'connect' and try again.
# This usually solves the problem.
os.system('idb connect ' + shlex.quote(udid))
code = run_with_timeout(2, idb_command_args)
if code == 0:
return code
syslog.syslog(syslog.LOG_ALERT, "idb-workaround Failed attempt 2/4")
# Wait an arbitrary amount of time before trying again.
# This rarely solves the problem, but patience is a virtue.
time.sleep(3)
code = run_with_timeout(5, idb_command_args)
if code == 0:
return code
syslog.syslog(syslog.LOG_ALERT, "idb-workaround Failed attempt 3/4")
# Running `idb connect` will spawn many idb_companion instances, and after a certain number it will refuse to spawn
# any more. `idb disconnect` doesn't seem to help, so the only solution is to kill them all.
os.system('idb kill')
os.system('idb connect ' + shlex.quote(udid))
code = run_with_timeout(10, idb_command_args)
if code != 0:
syslog.syslog(syslog.LOG_ALERT, "idb-workaround Failed attempt 4/4")
return code
if __name__ == '__main__':
code = main()
# Exit with actual code, unless it's 256 or 512 because Python doesn't pass that on!
sys.exit(code if code != 256 and code != 512 else 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment