diff --git a/src/clusterfuzz/_internal/platforms/android/constants.py b/src/clusterfuzz/_internal/platforms/android/constants.py index 86739d43fa..3beb91cf57 100644 --- a/src/clusterfuzz/_internal/platforms/android/constants.py +++ b/src/clusterfuzz/_internal/platforms/android/constants.py @@ -13,6 +13,7 @@ # limitations under the License. """Common constants.""" +from enum import IntEnum import re DEVICE_DOWNLOAD_DIR = '/sdcard/Download' @@ -83,3 +84,42 @@ # Restrict pixel6 from picking up generic Android jobs to avoid # Binary Mismatch: Hence, 'ANDROID:PIXEL6' is added to the list. DEVICES_WITH_NO_FALLBACK_QUEUE_LIST = ['ANDROID:PIXEL6'] + + +class ExitReason(IntEnum): + """Android process exit reasons from ApplicationExitInfo. Taken from + https://developer.android.com/reference/android/app/ApplicationExitInfo + """ + + UNKNOWN = 0 + EXIT_SELF = 1 + SIGNALED = 2 + LOW_MEMORY = 3 + CRASH = 4 + CRASH_NATIVE = 5 + ANR = 6 + INITIALIZATION_FAILURE = 7 + PERMISSION_CHANGE = 8 + EXCESSIVE_RESOURCE_USAGE = 9 + USER_REQUESTED = 10 + USER_STOPPED = 11 + DEPENDENCY_DIED = 12 + OTHER_KILLS_BY_SYSTEM = 13 + FREEZER = 14 + PACKAGE_STATE_CHANGE = 15 + PACKAGE_UPDATED = 16 + REASON_MEMORY_LIMITER = 17 + REASON_ANOMALY = 18 + + +class ExitStatus(IntEnum): + """Process exit signal statuses corresponding to POSIX signals. + + See: https://developer.android.com/reference/android/os/Process + """ + + SIGQUIT = 3 + SIGILL = 4 + SIGABRT = 6 + SIGKILL = 9 + SIGSEGV = 11 diff --git a/src/clusterfuzz/_internal/platforms/android/util.py b/src/clusterfuzz/_internal/platforms/android/util.py index 3cab131b78..6b9c7f5404 100644 --- a/src/clusterfuzz/_internal/platforms/android/util.py +++ b/src/clusterfuzz/_internal/platforms/android/util.py @@ -13,6 +13,7 @@ # limitations under the License. """Utility functions for Android device.""" +from dataclasses import dataclass import os from clusterfuzz._internal.metrics import logs @@ -20,6 +21,21 @@ from clusterfuzz._internal.system import environment +@dataclass(frozen=True) +class ProcessExitInfo: + """DTO representing process exit metadata from dumpsys activity exit-info. + + For a full list of android exit info reasons and subreasons, see: + https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/proto_logging/stats/enums/app_shared/app_enums.proto;l=270?q=content:subreason + """ + + reason: android.constants.ExitReason | int + reason_name: str # e.g., 'APP_CRASH(NATIVE)', 'SIGNALED' + subreason: int + subreason_name: str # e.g., 'UNKNOWN', 'ISOLATED_NOT_NEEDED' + status: android.constants.ExitStatus | int + + def get_device_path(local_path): """Returns device path for the given local path.""" root_directory = environment.get_root_directory()