addPointers - overlap with incoming pointers 异常分析

一.描述

       项目做老化测试,遇到system server重启,导致执行中间.

       报错信息:

Build fingerprint: 'Dish/Spence/T715DS:15/AP3A.240905.015.A2/1732765343:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2024-12-05 10:45:07.201198654+0800
Process uptime: 1944s
Cmdline: system_server
pid: 1406, tid: 1546, name: InputDispatcher  >>> system_server <<<
uid: 1000
tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: addPointers - overlap with incoming pointers 00000000000000000000000000000001 in {connection=1a0fef3 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher (server), windowHandle=1a0fef3 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher, dispatchMode=OUTSIDE, targetFlags=0x0, pointers=
        default (ROT_0) (IDENTITY)
}'
    x0  0000000000000000  x1  000000000000060a  x2  0000000000000006  x3  00000079c8899e90
    x4  fefefefefefefeff  x5  fefefefefefefeff  x6  fefefefefefefeff  x7  7f7f7f7f7f7f7f7f
    x8  00000000000000f0  x9  0000007e06e30418  x10 0000000000000001  x11 0000007e06e82070
    x12 00000079c8898bd0  x13 000000000000019f  x14 00000079c8898c80  x15 00000005f15e8a3b
    x16 0000007e06eebfe8  x17 0000007e06ed5ac0  x18 00000079c8334000  x19 000000000000057e
    x20 000000000000060a  x21 00000000ffffffff  x22 0000000000000000  x23 00000079c889aa80
    x24 000000000000016f  x25 b400007c9508c660  x26 706163207d293401  x27 000001c0594458c0
    x28 b400007cd50449d0  x29 00000079c8899f10
    lr  0000007e06e6a998  sp  00000079c8899e70  pc  0000007e06e6a9c4  pst 0000000000001000

14 total frames
backtrace:
      #00 pc 000000000005d9c4  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 6b5f6c2b322cc7e413534fa5f2520a62)
      #01 pc 000000000093075c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+344) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
      #02 pc 00000000000160fc  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_0::__invoke(char const*)+80) (BuildId: 42d41ca7c77853791d096606e7186547)
      #03 pc 0000000000015ed0  /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+512) (BuildId: 60e5261000aaaa4206a16ca816e8d913)
      #04 pc 000000000013ed84  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::addPointerWindowTargetLocked(android::sp<android::gui::WindowInfoHandle> const&, android::inputdispatcher::InputTarget::DispatchMode, android::ftl::Flags<android::inputdispatcher::InputTargetFlags>, std::__1::bitset<32ul>, std::__1::optional<long>, std::__1::vector<android::inputdispatcher::InputTarget, std::__1::allocator<android::inputdispatcher::InputTarget>>&) const+1572) (BuildId: 12b3baa199120fadecd8c896a37a9e9a)
      #05 pc 000000000014532c  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::findTouchedWindowTargetsLocked(long, android::inputdispatcher::MotionEntry const&, android::os::InputEventInjectionResult&)+10188) (BuildId: 12b3baa199120fadecd8c896a37a9e9a)
      #06 pc 000000000013c7c0  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchMotionLocked(long, std::__1::shared_ptr<android::inputdispatcher::MotionEntry const>, android::inputdispatcher::InputDispatcher::DropReason*, long&)+272) (BuildId: 12b3baa199120fadecd8c896a37a9e9a)
      #07 pc 0000000000139050  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchOnceInnerLocked(long&)+1392) (BuildId: 12b3baa199120fadecd8c896a37a9e9a)
      #08 pc 0000000000138a30  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::dispatchOnce()+80) (BuildId: 12b3baa199120fadecd8c896a37a9e9a)
      #09 pc 000000000000d9e8  /system/lib64/libinputflinger_base.so (android::(anonymous namespace)::InputThreadImpl::threadLoop()+24) (BuildId: cbf8e6b0d599e693f1f540a6ca741c2a)
      #10 pc 0000000000016c90  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+368) (BuildId: fa639e42761c9f4d00a390a8b06ed417)
      #11 pc 00000000000efccc  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: 7231ef3118ad57ffc5b76844d807a37a)
      #12 pc 0000000000070098  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+200) (BuildId: 6b5f6c2b322cc7e413534fa5f2520a62)
      #13 pc 0000000000061410  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 6b5f6c2b322cc7e413534fa5f2520a62)

 二. 分析

     1. 找到报错代码的地方

  在frameworks/native/services/inputflinger/dispatcher/InputTarget.cpp的addPointers函数中走到了如下代码

frameworks/native/services/inputflinger/dispatcher/InputTarget.cpp

Result<void> InputTarget::addPointers(std::bitset<MAX_POINTER_ID + 1> newPointerIds,
                                      const ui::Transform& transform) {
    // The pointerIds can be empty, but still a valid InputTarget. This can happen when there is no
    // valid pointer property from the input event.
    if (newPointerIds.none()) {
        setDefaultPointerTransform(transform);
        return {};
    }

    // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
    if ((getPointerIds() & newPointerIds).any()) {
        return Error() << __func__ << " - overlap with incoming pointers "
                       << bitsetToString(newPointerIds) << " in " << *this;
    }

    for (auto& [existingTransform, existingPointers] : mPointerTransforms) {
        if (transform == existingTransform) {
            existingPointers |= newPointerIds;
            return {};
        }
    }
    mPointerTransforms.emplace_back(transform, newPointerIds);
    return {};
}

导致InputDispatcher::addPointerWindowTargetLocked函数crash

androidv/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

void InputDispatcher::addPointerWindowTargetLocked(
        const sp<android::gui::WindowInfoHandle>& windowHandle,
        InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
        std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
        std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
...
     if (!result.ok()) {
         logDispatchStateLocked();
        LOG(FATAL) << result.error().message();
     }
}

2. 分析原因

此因为第一个monkey是以DOWN事件结尾。在下一次注入事件down的时候,触发了input主动abort。不存在这样的用户场景。

12-05 10:44:39.246814 15108 15108 I Monkey  : :Sending Touch (ACTION_DOWN): 0:(558.0,449.0)

12-05 10:44:39.249798 15108 15108 I Monkey  : Events injected: 4000

12-05 10:44:39.251625 15108 15108 I Monkey  : :Sending rotation degree=0, persist=false

12-05 10:44:39.263248 15108 15108 I Monkey  : :Dropped: keys=0 pointers=27 trackballs=0 flips=0 rotations=0

12-05 10:44:39.264473 15108 15108 I Monkey  : ## Network stats: elapsed time=488673ms (0ms mobile, 0ms wifi, 488673ms not connected)

12-05 10:44:39.264977 15108 15108 I Monkey  : // Monkey finished

12-05 10:44:39.247554  1406  6113 D InputManager: injectMotionEvent: 15108-{action=ACTION_DOWN, id[0]=0, x[0]=558.0, y[0]=449.0, pointerCount=1, eventTime=1925643, deviceId=0}

12-05 10:45:06.573880  1406  2890 D InputManager: injectMotionEvent: 18723-{action=ACTION_DOWN, id[0]=0, x[0]=600.0, y[0]=901.0, pointerCount=1, eventTime=1952952, deviceId=0}

12-05 10:45:06.608980  1406  1546 F InputDispatcher: InputDispatcher.cpp:3119] addPointers - overlap with incoming pointers 00000000000000000000000000000001 in {connection=1a0fef3 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher (server), windowHandle=1a0fef3 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher, dispatchMode=OUTSIDE, targetFlags=0x0, pointers=

三.  解决方案

       出现问题的原因是跑monkey 最后一个事件是DOWN结尾,再次跑monkey 又以DOWN 开始,造成InputDispatcher 误判.  那么只要保证monkey 分发事件不是以DOWN结尾就行.

    查看monkey 代码. 出现此问题的原因是monkey 每次都会在队列中获取事件,而不管队列里面事件是否还有数据.当达到某个次数时,会自动停止,所以会造成有可能出现DOWN 结束的行为,而不是UP 事件结尾.

    查看monkey 里面的代码,在生产队列中的事件都是完整的事件,所以只要monkey 结束事件时,将所有的队列中的事件都执行完即可.

 对应patch:

1.  androidv/development/cmds/monkey/src/com/android/commands/monkey/Monkey.java

diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
old mode 100644
new mode 100755
index f821a0e..404b092
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -1116,10 +1116,16 @@
         boolean shouldReportDumpsysMemInfo = false;
         boolean shouldAbort = false;
         boolean systemCrashed = false;
-
+        //TINNO BEGIN
+        //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+        boolean isMonkeyEventQueueEmpty = true;
+        //TINNO END

         try {
             // TO DO : The count should apply to each of the script file.
-            while (!systemCrashed && cycleCounter < mCount) {
+            //TINNO BEGIN
+            //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+            while (!systemCrashed && cycleCounter < mCount || !isMonkeyEventQueueEmpty) {
+            //TINNO END

                 synchronized (this) {
                     if (mRequestProcRank) {
                         reportProcRank();
@@ -1182,7 +1188,10 @@
                     reportDumpsysMemInfo();
                 }
 
-                if (shouldAbort) {
+                //TINNO BEGIN
+                //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+                if (shouldAbort && isMonkeyEventQueueEmpty) {
+                //TINNO END

                     shouldAbort = false;
                     Logger.out.println("** Monkey aborted due to error.");
                     Logger.out.println("Events injected: " + eventCounter);
@@ -1207,6 +1216,10 @@
                 }
 
                 MonkeyEvent ev = mEventSource.getNextEvent();
+                //TINNO BEGIN
+                //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+                isMonkeyEventQueueEmpty = mEventSource.isMonkeyEventQueueEmpty();
+                //TINNO END

                 if (ev != null) {
                     int injectCode = ev.injectEvent(mWm, mAm, mVerbose);
                     if (injectCode == MonkeyEvent.INJECT_FAIL) {

(2) androidv/development/cmds/monkey/src/com/android/commands/monkey/MonkeyEventSource.java

diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEventSource.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventSource.java
old mode 100644
new mode 100755
index af8b4ec..12b0819
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEventSource.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventSource.java
@@ -39,4 +39,11 @@
      *         file can not open from script source etc
      */
     public boolean validate();
+
+    //TINNO BEGIN
+    //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+    default public boolean isMonkeyEventQueueEmpty(){
+        return true;
+    }
+    //TINNO END

 }

(3) androidv/development/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java

diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
index d75c823..0b0091b
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
@@ -498,4 +498,11 @@
         mQ.removeFirst();
         return e;
     }
+
+    //TINNO BEGIN
+    //DATE20241211,  Modify By XIBIN, UGAFTF-3568
+    public boolean isMonkeyEventQueueEmpty(){
+        return mQ.isEmpty();
+    }
+    //TINNO END

 }

代码jira 地址:

http://172.16.5.191:8080/c/mediatek/platform/development/+/74327

四. 验证

脚本:

adb shell monkey -p com.google.android.contacts -s 1000 --pct-touch 50 --pct-motion 40 --pct-pinchzoom 10 --throttle 500 -v -v -v 100

最后几行,运行结果.

:Sending Touch (ACTION_UP): 0:(138.90039,811.06055)
Sleeping for 500 milliseconds
:Sending Touch (ACTION_DOWN): 0:(143.0,246.0)
:Sending Touch (ACTION_POINTER_DOWN 1): 0:(146.76074,241.56055) 1:(234.0,610.0)
:Sending Touch (ACTION_MOVE): 0:(151.25781,236.30762) 1:(237.49121,619.68555)
:Sending Touch (ACTION_MOVE): 0:(151.66211,234.90234) 1:(243.43164,628.8701)
:Sending Touch (ACTION_MOVE): 0:(158.85547,230.58984) 1:(245.38965,635.76953)
:Sending Touch (ACTION_MOVE): 0:(160.69629,229.63281) 1:(253.32422,648.6748)
:Sending Touch (ACTION_MOVE): 0:(165.23633,224.39844) 1:(267.3711,654.36816)
:Sending Touch (ACTION_MOVE): 0:(174.40723,219.30762) 1:(270.98145,654.38086)
:Sending Touch (ACTION_MOVE): 0:(184.20312,217.2832) 1:(281.80566,660.751)
:Sending Touch (ACTION_MOVE): 0:(185.44434,212.06348) 1:(283.08398,661.1631)
:Sending Touch (ACTION_MOVE): 0:(194.88574,206.24512) 1:(285.3789,670.56836)
    //[calendar_time:2024-12-11 16:42:11.223  system_uptime:182084]
    // Sending event #100
:Sending Touch (ACTION_POINTER_UP 1): 0:(198.89746,205.03711) 1:(285.78418,681.24805)
:Sending Touch (ACTION_UP): 0:(203.13281,199.78027)
Sleeping for 500 milliseconds
Events injected: 102
:Sending rotation degree=0, persist=false
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
## Network stats: elapsed time=8775ms (0ms mobile, 0ms wifi, 8775ms not connected)
// Monkey finished
 

 老化脚本压测一周,测试pass. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值