Skip to content

[Android] Refine bad build check and testcase manager execution - #5456

Merged
IvanBM18 merged 4 commits into
feature/android-exit-code-process-handlerfrom
feature/android-bad-build-check
Sep 11, 2026
Merged

IvanBM18 merged 4 commits into
feature/android-exit-code-process-handlerfrom
feature/android-bad-build-check

Conversation

@IvanBM18

@IvanBM18 IvanBM18 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Bug: b/553141628

Overview

Since Android API level 30 (and apps targeting Android 11+), apps have scoped storage access. Previously, bad build checks for Android did not verify whether the application process actually survived startup because am start returns 0 even if the process dies immediately.

This PR enhances check_for_bad_build() in testcase_manager.py by ensuring command line files are written prior to execution and flipping a conditional so in the bad build check the android specific validation proceeds other validations.

The later was required because thanks to this PR we added the possibility to check for false positives, but this added a problem in which valid builds were incorrectly flagged as crashes, so by flipping the conditional we fix this.

Changes

  • src/clusterfuzz/_internal/bot/testcase_manager.py: Updated check_for_bad_build() to pass write_command_line_file=True and verify target application process presence on Android post-launch.

Tests performed

Basically the same as the parent PR

reason=2 (SIGNALED) subreason=0 (UNKNOWN) status=9

When this happen now CF correctly determines that the app crashed due to runtime issues not related to memory errors.

PR stack

  • master
    • #PR 2.1a feature/android-exit-code-constants
    • #PR 2.1b feature/android-exit-code-core
    • #PR 2.2 feature/android-exit-code-process-handler
    • #PR 2.3 feature/android-bad-build-check 👈

Note:

Adding additional debug logs in this other PR:

@IvanBM18
IvanBM18 requested a review from a team as a code owner September 3, 2026 20:47
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 6c51bd7 to 455c3f5 Compare September 3, 2026 20:59
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 455c3f5 to c41d97d Compare September 3, 2026 21:13
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from c41d97d to 91f145b Compare September 3, 2026 21:20
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 91f145b to 8630786 Compare September 3, 2026 21:26
@IvanBM18 IvanBM18 self-assigned this Sep 3, 2026
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 8630786 to 7ea0de9 Compare September 3, 2026 21:50
Comment thread src/clusterfuzz/_internal/bot/testcase_manager.py
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 29bb199 to a9b0c46 Compare September 4, 2026 17:53
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from a9b0c46 to 0e01fdf Compare September 4, 2026 22:30

@dylanjew dylanjew left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. sorry, forgot to send my comments earlier

Comment thread src/clusterfuzz/_internal/bot/testcase_manager.py
Comment thread src/clusterfuzz/_internal/bot/testcase_manager.py Outdated
@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 07d8d6a to 8ad9f8e Compare September 8, 2026 17:39

@decoNR decoNR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. Left a quick question, please answer it before merging.

Were you able to test it in dev to guarantee that this does not affect other platforms? I think this seems important since one of the changes is not specific to Android.

Comment thread src/clusterfuzz/_internal/bot/testcase_manager.py
@IvanBM18

Copy link
Copy Markdown
Collaborator Author

Overall LGTM. Left a quick question, please answer it before merging.

Were you able to test it in dev to guarantee that this does not affect other platforms? I think this seems important since one of the changes is not specific to Android.

Sure no worries, that specific argument in the

get_command_line_for_application()

Is only used on android, see:

@decoNR

decoNR commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Overall LGTM. Left a quick question, please answer it before merging.
Were you able to test it in dev to guarantee that this does not affect other platforms? I think this seems important since one of the changes is not specific to Android.

Sure no worries, that specific argument in the

get_command_line_for_application()

Is only used on android, see:

Perfect, thanks.

@IvanBM18
IvanBM18 force-pushed the feature/android-bad-build-check branch from 8ad9f8e to 1162aa8 Compare September 11, 2026 20:33
@IvanBM18
IvanBM18 merged commit 294bb99 into master Sep 11, 2026
13 checks passed
@IvanBM18
IvanBM18 deleted the feature/android-bad-build-check branch September 11, 2026 20:34
@AashutoshMurthy

Copy link
Copy Markdown
Contributor

Control-flow issue: elif is unreachable on Android

Because if environment.is_android(): is now placed first in the if/elif chain, Python unconditionally enters the first branch on any Android platform, which means the elif (crash_result.is_crash(...)): branch is never evaluated.

This causes two regressions on Android:

  1. Non-APK Android jobs (package_name is None):
    The inner check if (package_name and ...) evaluates to False. Since the elif is skipped, is_bad_build is never set to True—even if the native binary or script crashed on launch with a SIGSEGV or ASan violation.
  2. Symbolized stack traces are bypassed for APKs:
    Even when package_name is set and an app crashes on launch, bypassing the elif skips crash_result.get_stacktrace(symbolized=True). The bot only checks if the PID is dead and logs raw, un-symbolized console output instead of the symbolized crash stack.

Suggested Fix

Evaluate the standard crash_result.is_crash() check first (so symbolized stacks are captured for any crash), and use the Android PID check as a fallback when no crash stack was caught:

  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']):
    is_bad_build = True
    build_run_console_output = utils.get_crash_stacktrace_output(
        command,
        crash_result.get_stacktrace(symbolized=True),
        crash_result.get_stacktrace(symbolized=False))
    logs.info(...)
  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
      ...

@IvanBM18

Copy link
Copy Markdown
Collaborator Author

Hi @AashutoshMurthy

Thanks for your comments, assumed all android fuzzing used apks... so i'll modify the code accordingly to this and your other PR comments.

Although, we can't fully revert the conditional because as this line says the crash analysis will mark a working chrome build as if it was crashing, this issue although old, is still happening.

An alternative to this is to is modify the bad build check, so that we only taking it into account if theres an apk present:

  # On Android, if we have an APK package and the application process is not
  # running after startup, the build is bad.
  if (environment.is_android() and
      (package_name := android.app.get_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)
  # 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

This way both apk and non apk android fuzzing should check for crashes accordingly at the bad build check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants