android 常规log、dump、winscope常见抓取方法

1,025 阅读6分钟

ProtoLog开关

在代码中我们经常看见ProtoLog打印的log,如下:

ProtoLog.i(WM_DEBUG_ANIM, "Animation start delayed for %s", mAnimatable);

这种log正常情况不会显示,因此我们需要打开开关,其格式为: adb shell wm logging enable-text [代码中对应的TAG] 我们这段代码的TAG是WM_DEBUG_ANIM,因此通过命令adb shell wm logging enable-text WM_DEBUG_ANIM打开log开关

另一种情况

ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId);

wmshell的log比较特殊,其在SystemUI进程,如果我们直接运行adb shell wm logging enable-text WM_SHELL_TASK_ORG会报错,打印如下:

Loaded 749 log definitions from /system/etc/protolog.conf.json.gz
No IProtoLogGroup named WM_SHELL_TASK_ORG
Not handled, please use `adb shell dumpsys activity service SystemUIService WMShell` if you are looking for ProtoLog in WMShell

根据提示我们打开log adb shell dumpsys activity service SystemUIService WMShell protolog enable WM_SHELL_TASK_ORG

logcat抓取log

# 抓取普通的andorid log
adb shell logcat > log.txt
# 仅抓取events log
adb shell logcat -b events > log.txt
# 抓取所有类型log
adb shell logcat -b all > log.txt

# 根据关键字抓取log,-i可以忽略大小,-e可以添加多条关键字,如下:
adb shell logcat -b events | grep -ie "关键log1" -ie "关键log2"> log.txt

events.log中对应代码查找

events log对应代码的规律是: events log开头的字段,比如wm_xxx 则对应的代码可以通过 grep 抓取 writeWmxxx 找出是在哪里打印的该events log

例如: 应用走到onresume生命周期的log wm_on_resume_called: [223605563,com.tencent.mm.ui.LauncherUI,RESUME_ACTIVITY,10]

EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason);

通知cancel的log notification_canceled: [0|com.tencent.mm|40|null|10218,8,19980,19980,7720,-1,-1,NULL]

EventLogTags.writeNotificationCanceled(canceledKey, reason,
                r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now),
                rank, count, listenerName);

使用winscope

手机要处于root状态才能使用

  • 使用手机自带的winscope 在手机设置里面,找到开发者选项->快捷设置开发者图块->打开 “ Winscope跟踪 ” 打开后复现问题,最后再关闭这个开关,就表示抓取完成 导出文件adb pull /data/misc/wmtrace 把导出文件在源码路径的android-13.0.0_r6/prebuilts/misc/common/winscope/winscope.html打开即可

  • 使用脚本抓取winscope(推荐) 附链接:

    winscope-t

    winscope-u

    winscope-v

    winscope-t和winscope-u均可离线使用,但是V的版本却不行,需要进行以下操作 1.需要用npm安装http-server npm install -g http-server 2.安装完成后运行http-server,进入下面任意一个ip即可在这里插入图片描述

    下载后,连接手机,直接运行脚本中的./run.sh,或者python3 winscope_proxy.py 在这里插入图片描述 START TRACE: 可以持续dump window和SurfaceFlinger信息,一般适用于闪黑场景,复现之前按下,复现后停止即可。 DMUP STATE: 相当于就是抓取一次 dumpsys windowdumpsys SurfaceFlinger

常见dump命令

adb shell dumpsys SurfaceFlinger > ./dump/SurfaceFlinger.txt
adb shell dumpsys window -a > ./dump/window.txt
adb shell dumpsys activity activities > ./dump/activities.txt
adb shell dumpsys activity top > ./dump/top_activity.txt
adb shell dumpsys activity containers > ./dump/containers.txt
adb shell dumpsys input > ./dump/input.txt

查找dump命令的方法

代码路径:frameworks/base/core/java/android/content/Context.java 这个代码里面有很多serviceName

    @StringDef(suffix = { "_SERVICE" }, value = {
            POWER_SERVICE,
            //@hide: POWER_STATS_SERVICE,
            WINDOW_SERVICE,
            LAYOUT_INFLATER_SERVICE,
            ACCOUNT_SERVICE,
            ACTIVITY_SERVICE,
            ALARM_SERVICE,
            NOTIFICATION_SERVICE,
            ACCESSIBILITY_SERVICE,
            CAPTIONING_SERVICE,
            KEYGUARD_SERVICE,
            LOCATION_SERVICE,
            HEALTHCONNECT_SERVICE,
            //@hide: COUNTRY_DETECTOR,
            SEARCH_SERVICE,
            SENSOR_SERVICE,
            SENSOR_PRIVACY_SERVICE,
            STORAGE_SERVICE,
            STORAGE_STATS_SERVICE,
            WALLPAPER_SERVICE,
            VIBRATOR_MANAGER_SERVICE,
            VIBRATOR_SERVICE,
            //@hide: STATUS_BAR_SERVICE,
            CONNECTIVITY_SERVICE,
            PAC_PROXY_SERVICE,
            VCN_MANAGEMENT_SERVICE,
            //@hide: IP_MEMORY_STORE_SERVICE,
            IPSEC_SERVICE,
            VPN_MANAGEMENT_SERVICE,
            TEST_NETWORK_SERVICE,
            //@hide: UPDATE_LOCK_SERVICE,
            //@hide: NETWORKMANAGEMENT_SERVICE,
            NETWORK_STATS_SERVICE,
            //@hide: NETWORK_POLICY_SERVICE,
            WIFI_SERVICE,
            WIFI_AWARE_SERVICE,
            WIFI_P2P_SERVICE,
            WIFI_SCANNING_SERVICE,
            //@hide: LOWPAN_SERVICE,
            //@hide: WIFI_RTT_SERVICE,
            //@hide: ETHERNET_SERVICE,
            WIFI_RTT_RANGING_SERVICE,
            NSD_SERVICE,
            AUDIO_SERVICE,
            AUDIO_DEVICE_VOLUME_SERVICE,
            AUTH_SERVICE,
            FINGERPRINT_SERVICE,
            //@hide: FACE_SERVICE,
            BIOMETRIC_SERVICE,
            MEDIA_ROUTER_SERVICE,
            TELEPHONY_SERVICE,
            TELEPHONY_SUBSCRIPTION_SERVICE,
            CARRIER_CONFIG_SERVICE,
            EUICC_SERVICE,
            //@hide: MMS_SERVICE,
            TELECOM_SERVICE,
            CLIPBOARD_SERVICE,
            INPUT_METHOD_SERVICE,
            TEXT_SERVICES_MANAGER_SERVICE,
            TEXT_CLASSIFICATION_SERVICE,
            APPWIDGET_SERVICE,
            //@hide: VOICE_INTERACTION_MANAGER_SERVICE,
            //@hide: BACKUP_SERVICE,
            REBOOT_READINESS_SERVICE,
            ROLLBACK_SERVICE,
            DROPBOX_SERVICE,
            //@hide: DEVICE_IDLE_CONTROLLER,
            //@hide: POWER_WHITELIST_MANAGER,
            DEVICE_POLICY_SERVICE,
            UI_MODE_SERVICE,
            DOWNLOAD_SERVICE,
            NFC_SERVICE,
            BLUETOOTH_SERVICE,
            //@hide: SIP_SERVICE,
            USB_SERVICE,
            LAUNCHER_APPS_SERVICE,
            //@hide: SERIAL_SERVICE,
            //@hide: HDMI_CONTROL_SERVICE,
            INPUT_SERVICE,
            DISPLAY_SERVICE,
            //@hide COLOR_DISPLAY_SERVICE,
            USER_SERVICE,
            RESTRICTIONS_SERVICE,
            APP_OPS_SERVICE,
            ROLE_SERVICE,
            //@hide ROLE_CONTROLLER_SERVICE,
            CAMERA_SERVICE,
            //@hide: PLATFORM_COMPAT_SERVICE,
            //@hide: PLATFORM_COMPAT_NATIVE_SERVICE,
            PRINT_SERVICE,
            CONSUMER_IR_SERVICE,
            //@hide: TRUST_SERVICE,
            TV_INTERACTIVE_APP_SERVICE,
            TV_INPUT_SERVICE,
            //@hide: TV_TUNER_RESOURCE_MGR_SERVICE,
            //@hide: NETWORK_SCORE_SERVICE,
            USAGE_STATS_SERVICE,
            MEDIA_SESSION_SERVICE,
            MEDIA_COMMUNICATION_SERVICE,
            BATTERY_SERVICE,
            JOB_SCHEDULER_SERVICE,
            //@hide: PERSISTENT_DATA_BLOCK_SERVICE,
            //@hide: OEM_LOCK_SERVICE,
            MEDIA_PROJECTION_SERVICE,
            MIDI_SERVICE,
            RADIO_SERVICE,
            HARDWARE_PROPERTIES_SERVICE,
            //@hide: SOUND_TRIGGER_SERVICE,
            SHORTCUT_SERVICE,
            //@hide: CONTEXTHUB_SERVICE,
            SYSTEM_HEALTH_SERVICE,
            //@hide: INCIDENT_SERVICE,
            //@hide: INCIDENT_COMPANION_SERVICE,
            //@hide: STATS_COMPANION_SERVICE,
            COMPANION_DEVICE_SERVICE,
            VIRTUAL_DEVICE_SERVICE,
            CROSS_PROFILE_APPS_SERVICE,
            //@hide: SYSTEM_UPDATE_SERVICE,
            //@hide: TIME_DETECTOR_SERVICE,
            //@hide: TIME_ZONE_DETECTOR_SERVICE,
            PERMISSION_SERVICE,
            LIGHTS_SERVICE,
            LOCALE_SERVICE,
            //@hide: PEOPLE_SERVICE,
            //@hide: DEVICE_STATE_SERVICE,
            //@hide: SPEECH_RECOGNITION_SERVICE,
            UWB_SERVICE,
            MEDIA_METRICS_SERVICE,
            //@hide: ATTESTATION_VERIFICATION_SERVICE,
            //@hide: SAFETY_CENTER_SERVICE,
            DISPLAY_HASH_SERVICE,
            CREDENTIAL_SERVICE,
            DEVICE_LOCK_SERVICE,
            VIRTUALIZATION_SERVICE,
            GRAMMATICAL_INFLECTION_SERVICE,

    })

我们只需要根据这些常量找到对应的名称即可,比如输入法:

    /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link android.view.inputmethod.InputMethodManager} for accessing input
     * methods.
     *
     * @see #getSystemService(String)
     */
    public static final String INPUT_METHOD_SERVICE = "input_method";

我们可以看到,其实就是通过getSystemService方法中调用的字符常量,我们要dump输入法服务相关的命令就是adb shell dumpsys input_method

如果我们想知道这个dump的方法具体在哪,会有哪些打印,则只需通过对应Mananger找到对应的ManagerService即可。 比如,我们这里以输入法为例,那么其对应的就是InputMethodManagerService,在这个里面就有对应的dump方法: 代码路径:frameworks/base/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java

void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
            final SimpleDateFormat dataFormat =
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);

            for (int i = 0; i < mEntries.length; ++i) {
                final Entry entry = mEntries[(i + mNextIndex) % mEntries.length];
                if (entry == null) {
                    continue;
                }
                pw.print(prefix);
                pw.println("SoftInputShowHideHistory #" + entry.mSequenceNumber + ":");

                pw.print(prefix);
                pw.println(" time=" + dataFormat.format(new Date(entry.mWallTime))
                        + " (timestamp=" + entry.mTimestamp + ")");

                pw.print(prefix);
                pw.print(" reason=" + InputMethodDebug.softInputDisplayReasonToString(
                        entry.mReason));
                pw.println(" inFullscreenMode=" + entry.mInFullscreenMode);

                pw.print(prefix);
                pw.println(" requestClient=" + entry.mClientState);

                pw.print(prefix);
                pw.println(" focusedWindowName=" + entry.mFocusedWindowName);

                pw.print(prefix);
                pw.println(" requestWindowName=" + entry.mRequestWindowName);

                pw.print(prefix);
                pw.println(" imeControlTargetName=" + entry.mImeControlTargetName);

                pw.print(prefix);
                pw.println(" imeTargetNameFromWm=" + entry.mImeTargetNameFromWm);

                pw.print(prefix);
                pw.print(" editorInfo: ");
                pw.print(" inputType=" + entry.mEditorInfo.inputType);
                pw.print(" privateImeOptions=" + entry.mEditorInfo.privateImeOptions);
                pw.println(" fieldId (viewId)=" + entry.mEditorInfo.fieldId);

                pw.print(prefix);
                pw.println(" focusedWindowSoftInputMode=" + InputMethodDebug.softInputModeToString(
                        entry.mFocusedWindowSoftInputMode));
            }
        }
    }

有些命令是带参数的,比如:adb shell dumpsys activity top
可以加上-h来查看所有的命令,如:adb shell dumpsys activity -h
打印结果如下:

Activity manager dump options:
  [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...
  WHAT may be one of:
    a[ctivities]: activity stack state
    r[recents]: recent activities state
    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state
    broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics
    i[ntents] [PACKAGE_NAME]: pending intent state
    p[rocesses] [PACKAGE_NAME]: process state
    o[om]: out of memory management
    perm[issions]: URI permission grant state
    prov[iders] [COMP_SPEC ...]: content provider state
    provider [COMP_SPEC]: provider client-side state
    s[ervices] [COMP_SPEC ...]: service state
    allowed-associations: current package association restrictions
    as[sociations]: tracked app associations
    exit-info [PACKAGE_NAME]: historical process exit information
    lmk: stats on low memory killer
    lru: raw LRU process list
    binder-proxies: stats on binder objects and IPCs
    settings: currently applied config settings
    service [COMP_SPEC]: service client-side state
    package [PACKAGE_NAME]: all state related to given package
    all: dump all activities
    top: dump the top activity
    users: user state
  WHAT may also be a COMP_SPEC to dump activities.
  COMP_SPEC may be a component name (com.foo/.myApp),
    a partial substring in a component name, a
    hex object identifier.
  -a: include all available server state.
  -c: include client state.
  -p: limit output to given package.
  -d: limit output to given display.
  --checkin: output checkin format, resetting data.
  --C: output checkin format, not resetting data.
  --proto: output dump in protocol buffer format.
  --dump-dumpable: dump just the DUMPABLE-related state of an activity. Use the --list-dumpables option to list the supported DUMPABLEs
  --list-dumpables: show the available dumpables in an activity