From 6b70edb9e110cd7307751a1effd39999d3a9399b Mon Sep 17 00:00:00 2001 From: Ivan Barba Date: Thu, 3 Sep 2026 20:58:51 +0000 Subject: [PATCH 1/4] [Android] Refine bad build check and testcase manager execution --- .../_internal/bot/testcase_manager.py | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/clusterfuzz/_internal/bot/testcase_manager.py b/src/clusterfuzz/_internal/bot/testcase_manager.py index e2e4a36f9a..88e84ae714 100644 --- a/src/clusterfuzz/_internal/bot/testcase_manager.py +++ b/src/clusterfuzz/_internal/bot/testcase_manager.py @@ -332,7 +332,12 @@ def run_testcase(thread_index, file_path, gestures, env_copy): app_directory = environment.get_value('APP_DIR') environment.set_value('PIDS', '[]') + logs.info( + f'Running testcase (thread {thread_index}): file_path={file_path}, ' + f'needs_http={needs_http}, gestures={gestures}') + # Get command line options. + command = get_command_line_for_application( file_path, user_profile_index=thread_index, needs_http=needs_http) @@ -1243,7 +1248,8 @@ def check_for_bad_build(job_type: str, os.environ['APP_ARGS'] = job_default_args try: - command = get_command_line_for_application(file_to_run='', needs_http=False) + command = get_command_line_for_application( + file_to_run='', needs_http=False, write_command_line_file=True) finally: if orig_app_args is not None: os.environ['APP_ARGS'] = orig_app_args @@ -1273,19 +1279,40 @@ def check_for_bad_build(job_type: str, process_handler.terminate_stale_application_instances() # Check if the build is bad. + logs.info( + f'Starting bad build check for {job_type} at r{crash_revision} with ' + f'command: {command} (timeout={fast_warmup_timeout})') return_code, crash_time, output = process_handler.run_process( command, timeout=fast_warmup_timeout, current_working_directory=app_directory) crash_result = CrashResult(return_code, crash_time, output) + logs.info( + f'Bad build check run_process completed: return_code={return_code}, ' + f'is_crash={crash_result.is_crash(ignore_state=True)}, ' + f'crash_type={crash_result.get_type()}') # 1. Need to account for startup crashes with no crash state. E.g. failed to # load shared library. So, ignore state for comparison. # 2. Ignore leaks as they don't block a build from reporting regular crashes # and also don't impact regression range calculations. - if (crash_result.is_crash(ignore_state=True) and - not crash_result.should_ignore() and - not crash_result.get_type() in ['Direct-leak', 'Indirect-leak']): + if environment.is_android(): + package_name = android.app.get_package_name() + if (package_name and + not android.adb.get_process_and_child_pids(package_name)): + is_bad_build = True + build_run_console_output = utils.get_crash_stacktrace_output( + command, output, output) + logs.info( + f'Bad build for {job_type} detected at r{crash_revision}: ' + f'application process for {package_name} is not running after ' + 'startup.', + raw_output=output, + output=build_run_console_output) + elif (crash_result.is_crash(ignore_state=True) and + not crash_result.should_ignore() and + not crash_result.get_type() in ['Direct-leak', 'Indirect-leak']): + is_bad_build = True build_run_console_output = utils.get_crash_stacktrace_output( command, From f27123a6fbb9bc2fb875b8f31eb6e6e70a9150c9 Mon Sep 17 00:00:00 2001 From: Ivan Barba Date: Fri, 4 Sep 2026 17:14:51 +0000 Subject: [PATCH 2/4] Removes duplicated code --- src/clusterfuzz/_internal/bot/testcase_manager.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/clusterfuzz/_internal/bot/testcase_manager.py b/src/clusterfuzz/_internal/bot/testcase_manager.py index 88e84ae714..0f9dbcdc77 100644 --- a/src/clusterfuzz/_internal/bot/testcase_manager.py +++ b/src/clusterfuzz/_internal/bot/testcase_manager.py @@ -1323,19 +1323,6 @@ def check_for_bad_build(job_type: str, f'return code = {return_code}, crash type = {crash_result.get_type()}', raw_output=output, output=build_run_console_output) - elif environment.is_android(): - package_name = android.app.get_package_name() - if (package_name and - not android.adb.get_process_and_child_pids(package_name)): - is_bad_build = True - build_run_console_output = utils.get_crash_stacktrace_output( - command, output, output) - logs.info( - f'Bad build for {job_type} detected at r{crash_revision}: ' - f'application process for {package_name} is not running after ' - 'startup.', - raw_output=output, - output=build_run_console_output) # Exit all running instances. process_handler.terminate_stale_application_instances() From 7aafdc6c0a8ce837c6d0180f0e6d41fc4796c217 Mon Sep 17 00:00:00 2001 From: Ivan Barba Date: Fri, 4 Sep 2026 17:53:27 +0000 Subject: [PATCH 3/4] [Android] Add comments for bad build check --- src/clusterfuzz/_internal/bot/testcase_manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/clusterfuzz/_internal/bot/testcase_manager.py b/src/clusterfuzz/_internal/bot/testcase_manager.py index 0f9dbcdc77..62a2a06c8b 100644 --- a/src/clusterfuzz/_internal/bot/testcase_manager.py +++ b/src/clusterfuzz/_internal/bot/testcase_manager.py @@ -1296,6 +1296,8 @@ def check_for_bad_build(job_type: str, # load shared library. So, ignore state for comparison. # 2. Ignore leaks as they don't block a build from reporting regular crashes # and also don't impact regression range calculations. + # 3. On Android, if the application process is not running after startup, + # the build is bad. if environment.is_android(): package_name = android.app.get_package_name() if (package_name and From 1162aa85deec3705723329da36e7f6aa54a1f03e Mon Sep 17 00:00:00 2001 From: Ivan Barba Date: Tue, 8 Sep 2026 17:36:22 +0000 Subject: [PATCH 4/4] [Android] Reorder comments --- src/clusterfuzz/_internal/bot/testcase_manager.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/clusterfuzz/_internal/bot/testcase_manager.py b/src/clusterfuzz/_internal/bot/testcase_manager.py index 62a2a06c8b..7bf5189367 100644 --- a/src/clusterfuzz/_internal/bot/testcase_manager.py +++ b/src/clusterfuzz/_internal/bot/testcase_manager.py @@ -1292,12 +1292,8 @@ def check_for_bad_build(job_type: str, f'is_crash={crash_result.is_crash(ignore_state=True)}, ' f'crash_type={crash_result.get_type()}') - # 1. Need to account for startup crashes with no crash state. E.g. failed to - # load shared library. So, ignore state for comparison. - # 2. Ignore leaks as they don't block a build from reporting regular crashes - # and also don't impact regression range calculations. - # 3. On Android, if the application process is not running after startup, - # the build is bad. + # On Android, if the application process is not running after startup, the + # build is bad. if environment.is_android(): package_name = android.app.get_package_name() if (package_name and @@ -1311,6 +1307,10 @@ def check_for_bad_build(job_type: str, 'startup.', raw_output=output, output=build_run_console_output) + # 1. Need to account for startup crashes with no crash state. E.g. failed to + # load shared library. So, ignore state for comparison. + # 2. Ignore leaks as they don't block a build from reporting regular crashes + # and also don't impact regression range calculations. elif (crash_result.is_crash(ignore_state=True) and not crash_result.should_ignore() and not crash_result.get_type() in ['Direct-leak', 'Indirect-leak']):