IT开发者百科  > 所属分类  >  Telephony   
[0] 评论[0] 编辑

【Crash】com.android.phone GsmServiceStateTracker Crash

目录

问题描述编辑本段

ARP系统用户缺陷控制中心上报大量GsmServiceStateTracker Crash信息

Description
【网络环境】用户缺陷控制中心
【异常类型】crash
【模 块】com.android.phone
【堆 栈】at com.android.internal.telephony.gsm.GsmServiceStateTracker$timerTask.run(GsmServiceStateTracker.java:4659)
【分析结论】com.android.phone

Process: com.android.phone
Flags: 0x38883e45
Package: com.android.providers.telephony v23 (6.0-1489054638)
Package: com.android.phone.recorder v1 (1.0)
Package: com.mediatek.engineermode v1 (1.0)
Package: com.android.stk v23 (6.0-1489054638)
Package: com.huawei.android.dsdscardmanager v3050 (3.0.5.14)
Package: com.android.phone v23 (6.0-1489054638)
Build: XXXXXX/NCE-AL00/HWNCE-L6750:6.0/XXXXXXNCE-AL00/C00B138:user/release-keys

java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
 at java.lang.Thread.nativeCreate(Native Method)
 at java.lang.Thread.start(Thread.java:1078)
 at com.android.internal.telephony.gsm.GsmServiceStateTracker$timerTask.run(GsmServiceStateTracker.java:4659)
 at java.util.Timer$TimerImpl.run(Timer.java:284)


 

代码分析编辑本段

我们内部作了初步分析,每次log都定位在new Thread(new Runnable()这一行 ,不像是jvm溢出,是不是此处频繁新建线程,占用过多系统资源导致OOM?
此处的代码是MTK添加的,getAllCellInfoByRate()的功能是做什么用的?EMUI在GsmServiceStateTracker.java中并未修改太多代码。

public class timerTask extends TimerTask {
public void run() {
log("CellInfo Timeout invoke getAllCellInfoByRate()");
if ((mCellInfoRate != Integer.MAX_VALUE) && (mCellInfoRate != 0)
&& (mCellInfoTimer != null)) {
log("timerTask schedule timer with period = " + mCellInfoRate + " ms");
mCellInfoTimer.schedule(new timerTask(), mCellInfoRate);
}

new Thread(new Runnable() {
public void run() {
log("timerTask invoke getAllCellInfoByRate() in another thread");
getAllCellInfoByRate();
}
}).start();

}
};


复现操作编辑本段

 昨天晚上我们做了复现,手机在某些场景下会调用getAllCellInfoByRate-->setCellInfoListRate,频繁更新小区信息,创建new Thread(new Runnable() {},导致OutOfMemoryError "pthread_create"
目前仅发现在工模RadioInfo.java中调用setCellInfoListRate,如果在工模RadioInfo界面设置刷新小区为1000毫秒一次,数分钟后就会复现问题。此问题在之前的版本中也是一直存在的,可能概率小未关注到,这一块代码是MTK添加的。
请确认是否在手机正常使用的场景下也会出现此问题,MTK添加setCellInfoListRate的作用是什么,仅用于工模吗?此处代码是否有patch优化?

04-13 20:41:12.738 2542 5039 D GsmSST : [GsmSST0] CellInfo Timeout invoke getAllCellInfoByRate()
04-13 20:41:12.739 2542 5039 D GsmSST : [GsmSST0] timerTask schedule timer with period = 1000 ms
04-13 20:41:12.745 2542 5039 I System.out: Group name=java.lang.ThreadGroup[name=main,maxPriority=10], Thread Total count=481, This thread name=Thread-1438
04-13 20:41:12.745 2542 5039 W System.err: java.lang.Throwable: stack dump
04-13 20:41:12.746 2542 5039 W System.err: at java.lang.Thread.dumpStack(Thread.java:505)
04-13 20:41:12.746 2542 5039 W System.err: at java.lang.Thread.create(Thread.java:435)
04-13 20:41:12.746 2542 5039 W System.err: at java.lang.Thread.<init>(Thread.java:222)
04-13 20:41:12.746 2542 5039 W System.err: at com.android.internal.telephony.gsm.GsmServiceStateTracker$timerTask.run(GsmServiceStateTracker.java:4659)
04-13 20:41:12.746 2542 5039 W System.err: at java.util.Timer$TimerImpl.run(Timer.java:284)
04-13 20:41:12.747 2542 5039 W libc : pthread_create failed: clone failed: Out of memory
04-13 20:41:12.747 2542 5039 W art : Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Out of memory"


MTK回复编辑本段

該題主因就在於SST定期new Thread並呼叫getAllCellInfoByRate()
而getAllCellInfoByRate()會透過result.lockObj.wait();等待EVENT_GET_CELL_INFO_LIST_BY_RATE
但是SST收到EVENT_GET_CELL_INFO_LIST_BY_RATE並不會result.lockObj.notify();
導致Thread不會結束沒有釋放佔用的資源
最終出現OOM問題

 

修改方案编辑本段

    protected void updateCellInfoRate() {
        log("updateCellInfoRate(),mCellInfoRate= " + mCellInfoRate);
        // protect MTK platform from unreasonable rate, period must > 20s
        if (mCellInfoRate < 20000) mCellInfoRate = 20000;

        if ((mCellInfoRate != Integer.MAX_VALUE) && (mCellInfoRate != 0)) {
            if (mCellInfoTimer != null) {
                log("cancel previous timer if any");
                mCellInfoTimer.cancel();
                mCellInfoTimer = null;
            }

            mCellInfoTimer = new Timer(true);

            log("schedule timer with period = " + mCellInfoRate + " ms");
            mCellInfoTimer.schedule(new timerTask(), mCellInfoRate);
        } else if ((mCellInfoRate == 0) || (mCellInfoRate == Integer.MAX_VALUE)) {
            if (mCellInfoTimer != null) {
                log("cancel cell info timer if any");
                mCellInfoTimer.cancel();
                mCellInfoTimer = null;
            }
        }
    }

 

风险确认编辑本段

1.目前从可见的代码上看工模RadioInfo.java界面有调用setCellInfoListRate-->getAllCellInfoByRate接口,但并未看到其它代码能走到此流程,正常用户是在什么场景下走到此流程的。


【MTK】如贵公司之前note所述:“工模RadioInfo界面设置刷新小区为1000毫秒一次”, 会有这样的调用:

/packages/apps/Settings/src/com/android/settings/RadioInfo.java: phone.setCellInfoListRate(rates[index]); -->
/frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneBase.java : getServiceStateTracker().setCellInfoRate(rateInMillis); --->
/frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java : updateCellInfoRate(); -->
/frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java : mCellInfoTimer.schedule(new timerTask(), mCellInfoRate);
这里会按照mCellInfoRate的间隔去不断创建timerTask()去执行getAllCellInfoByRate()。

2.此Patch修改了好几个问题,是否有风险评审验证,我们要应用到量产项目上。

附件列表


0

Java-Android手机千人开发交流QQ群:38088312,PHP开发千人高级交流QQ群:50194090,欢迎加入学习!本站为
非赢利站点,挖掘网络资源,分享个人兴趣,如有侵犯您的版权,请联系我们,我们会第一时间删除内容或添加转载出处,敬请谅解!

如果您认为本词条还有待完善,请 编辑

上一篇 XX项目海外定制无法注网问题分析    下一篇 IMS接入边界技术的发展

同义词

暂无同义词