From 0579a814f12de4b169658ad98b0d3b14e74aaac2 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Wed, 5 Jul 2023 11:07:17 +0100 Subject: [PATCH] android: Add a retry logic for background command PID detection PID detection can sometimes fail for unknown reason. Maybe there is a latency between the process being started and "ps" being able to see it that can sometimes be high enough that we look for the process before it's exposed. In order to remedy that, add a retry logic to avoid plain failures. --- devlib/utils/android.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/devlib/utils/android.py b/devlib/utils/android.py index f680023..1f6fd11 100755 --- a/devlib/utils/android.py +++ b/devlib/utils/android.py @@ -657,6 +657,7 @@ def adb_background_shell(conn, command, busybox = conn.busybox _check_env() + orig_command = command stdout, stderr, command = redirect_streams(stdout, stderr, command) if as_root: command = f'{busybox} printf "%s" {quote(command)} | su' @@ -693,10 +694,25 @@ def adb_background_shell(conn, command, # avoids having to rely on PID ordering (which could be misleading if PIDs # got recycled). find_pid = f'''pids=$({busybox} ps -A -o pid,args | {grep_cmd} | {busybox} grep -v {quote(grep_cmd)} | {busybox} awk '{{print $1}}') && {busybox} printf "%s" "$pids" && {busybox} kill -CONT $pids''' - pids = conn.execute(find_pid, as_root=as_root) - # We choose the highest PID as the "control" PID. It actually does not - # really matter which one we pick, as they are all equivalent sh -c layers. - pid = max(map(int, pids.split())) + + excep = None + for _ in range(5): + try: + pids = conn.execute(find_pid, as_root=as_root) + # We choose the highest PID as the "control" PID. It actually does not + # really matter which one we pick, as they are all equivalent sh -c layers. + pid = max(map(int, pids.split())) + except TargetStableError: + raise + except Exception as e: + excep = e + time.sleep(10e-3) + continue + else: + break + else: + raise TargetTransientError(f'Could not detect PID of background command: {orig_command}') from excep + return (p, pid) def adb_kill_server(timeout=30, adb_server=None):