You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by do...@apache.org on 2019/08/14 10:10:56 UTC

[incubator-weex] branch master updated: [Android] record ipc exception history and weexCoreThread stackTrace when white screen or js process died/reload (#2826)

This is an automated email from the ASF dual-hosted git repository.

dongyayun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new a994ce9  [Android] record ipc exception history and weexCoreThread stackTrace when white screen or js process died/reload (#2826)
a994ce9 is described below

commit a994ce97e72535032dccf9007471f7f890765356
Author: chen <lu...@users.noreply.github.com>
AuthorDate: Wed Aug 14 18:10:50 2019 +0800

    [Android] record ipc exception history and weexCoreThread stackTrace when white screen or js process died/reload (#2826)
---
 .../main/java/com/taobao/weex/WXSDKInstance.java   |  1 +
 .../com/taobao/weex/bridge/WXBridgeManager.java    | 39 ++++++++++++++++++----
 .../com/taobao/weex/performance/WXStateRecord.java | 21 +++++-------
 .../java/com/taobao/weex/utils/WXLogUtils.java     |  4 +++
 .../bridge/script/script_side_in_multi_process.cpp | 36 ++++++++++----------
 .../android/multiprocess/weex_js_connection.cpp    |  2 +-
 .../Source/third_party/IPC/IPCFutexPageQueue.cpp   |  1 +
 7 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
index a774e88..23d4089 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java
@@ -944,6 +944,7 @@ public class WXSDKInstance implements IWXActivityStateListener,View.OnLayoutChan
     Map<String,String> args = new HashMap<>(1);
     String vieTreeMsg = WhiteScreenUtils.takeViewTreeSnapShot(this);
     args.put("viewTree",null == vieTreeMsg?"null viewTreeMsg":vieTreeMsg);
+    args.put("weexCoreThreadStackTrace",WXBridgeManager.getInstance().getWeexCoreThreadStackTrace());
 
     for (Map.Entry<String,String> entry: WXStateRecord.getInstance().getStateInfo().entrySet()){
       args.put(entry.getKey(),entry.getValue());
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index d363651..145730c 100755
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -884,6 +884,10 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         url = instance.getBundleUrl();
         instance.setHasException(true);
       }
+      Map<String,String> extInfo = new HashMap<>(2);
+      extInfo.put("weexCoreThreadStackTrace:",WXBridgeManager.getInstance().getWeexCoreThreadStackTrace());
+      extInfo.put("wxStateInfo",WXStateRecord.getInstance().getStateInfo().toString());
+
       if(!isCrashFileEmpty) {
         try {
             if (WXEnvironment.getApplication() != null) {
@@ -894,15 +898,15 @@ public class WXBridgeManager implements Callback, BactchExecutor {
           WXLogUtils.e(WXLogUtils.getStackTrace(e));
         }
         WXStateRecord.getInstance().onJSCCrash();
-        callReportCrash(crashFile, instanceId, url);
+        callReportCrash(crashFile, instanceId, url,extInfo);
       } else {
         WXStateRecord.getInstance().onJSEngineReload();
-         commitJscCrashAlarmMonitor(IWXUserTrackAdapter.JS_BRIDGE, WXErrorCode.WX_ERR_RELOAD_PAGE, "reboot jsc Engine", instanceId, url);
+         commitJscCrashAlarmMonitor(IWXUserTrackAdapter.JS_BRIDGE, WXErrorCode.WX_ERR_RELOAD_PAGE, "reboot jsc Engine", instanceId, url,extInfo);
       }
 
       if (reInitCount > CRASHREINIT) {
         WXExceptionUtils.commitCriticalExceptionRT("jsEngine", WXErrorCode.WX_ERR_RELOAD_PAGE_EXCEED_LIMIT,
-            "callReportCrashReloadPage","reInitCount:"+reInitCount,null);
+            "callReportCrashReloadPage","reInitCount:"+reInitCount,extInfo);
         return IWXBridge.INSTANCE_RENDERING_ERROR;
       }
       reInitCount++;
@@ -974,7 +978,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
     return false;
   }
 
-  public void callReportCrash(String crashFile, final String instanceId, final String url) {
+  public void callReportCrash(String crashFile, final String instanceId, final String url,final Map<String,String> extInfo) {
     // statistic weex core process crash
     Date date = new Date();
     DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
@@ -1005,7 +1009,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
                   // }
                   result.append(s + "\n");
                 }
-                commitJscCrashAlarmMonitor(IWXUserTrackAdapter.JS_BRIDGE, WXErrorCode.WX_ERR_JSC_CRASH, result.toString(), instanceId, url);
+                commitJscCrashAlarmMonitor(IWXUserTrackAdapter.JS_BRIDGE, WXErrorCode.WX_ERR_JSC_CRASH, result.toString(), instanceId, url,extInfo);
                 br.close();
               } catch (Exception e) {
                 WXLogUtils.e(WXLogUtils.getStackTrace(e));
@@ -1473,7 +1477,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   }
 
   public void commitJscCrashAlarmMonitor(final String type, final WXErrorCode errorCode, String errMsg,
-                                         String instanceId, String url) {
+                                         String instanceId, String url,Map<String, String> extInfo) {
     if (TextUtils.isEmpty(type) || errorCode == null) {
       return;
     }
@@ -1483,6 +1487,9 @@ public class WXBridgeManager implements Callback, BactchExecutor {
     String exception = "weex core process crash and restart exception";
     Map<String, String> extParams = new HashMap<String, String>();
     extParams.put("jscCrashStack", errMsg);
+    if (null != extInfo){
+      extParams.putAll(extInfo);
+    }
     IWXJSExceptionAdapter adapter = WXSDKManager.getInstance().getIWXJSExceptionAdapter();
     if (adapter != null) {
       WXJSExceptionInfo jsException = new WXJSExceptionInfo(instanceId, url, errorCode, method, exception, extParams);
@@ -3614,4 +3621,24 @@ public class WXBridgeManager implements Callback, BactchExecutor {
     }
     mWeexCoreEnvOptions.clear();
   }
+
+  public  String getWeexCoreThreadStackTrace(){
+    if (null == mJSThread){
+      return "null == mJSThread";
+    }
+    StringBuilder stringBuilder = new StringBuilder();
+
+    try {
+      stringBuilder.append(String.format("Thread Name: '%s'\n", mJSThread.getName()));
+      stringBuilder.append(String.format(Locale.ENGLISH,"\"%s\" prio=%d tid=%d %s\n", mJSThread.getName(), mJSThread.getPriority(), mJSThread.getId(), mJSThread.getState()));
+
+      for (StackTraceElement e: mJSThread.getStackTrace()){
+        stringBuilder.append(String.format("\tat %s\n", e.toString()));
+      }
+    } catch (Exception var8) {
+      Log.e("weex", "getJSThreadStackTrace error:", var8);
+    }
+    return stringBuilder.toString();
+  }
+
 }
diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/WXStateRecord.java b/android/sdk/src/main/java/com/taobao/weex/performance/WXStateRecord.java
index 700d419..a95e957 100644
--- a/android/sdk/src/main/java/com/taobao/weex/performance/WXStateRecord.java
+++ b/android/sdk/src/main/java/com/taobao/weex/performance/WXStateRecord.java
@@ -44,6 +44,7 @@ public class WXStateRecord {
     private RecordList<Info> mJscCrashHistory;
     private RecordList<Info> mJscReloadHistory;
     private RecordList<Info> mJsThradWatchHistory;
+    private RecordList<Info> mIPCExceptionHistory;
 
     private static class SingleTonHolder {
         private static final WXStateRecord S_INSTANCE = new WXStateRecord();
@@ -60,6 +61,7 @@ public class WXStateRecord {
         mJscCrashHistory = new RecordList<>(10);
         mJscReloadHistory = new RecordList<>(10);
         mJsThradWatchHistory = new RecordList<>(20);
+        mIPCExceptionHistory = new RecordList<>(20);
     }
 
     /**
@@ -77,6 +79,11 @@ public class WXStateRecord {
         recordCommon(mActionHistory,new Info(WXUtils.getFixUnixTime(), instanceId, action));
     }
 
+    public void recordIPCException (String instanceId,String exception){
+        String shortException = exception.length() > 200 ?exception.substring(0,200) : exception;
+        recordCommon(mIPCExceptionHistory,new Info(WXUtils.getFixUnixTime(), instanceId, shortException));
+    }
+
     /**
      * check onJSFMInit time,and we know when jsfm is init sucess in reloadJsEngine case
      */
@@ -134,6 +141,7 @@ public class WXStateRecord {
         reportTimeLineInfo.addAll(mJscCrashHistory);
         reportTimeLineInfo.addAll(mJscReloadHistory);
         reportTimeLineInfo.addAll(mJsThradWatchHistory);
+        reportTimeLineInfo.addAll(mIPCExceptionHistory);
         Collections.sort(reportTimeLineInfo);
         stateInfo.put("stateInfoList",reportTimeLineInfo.toString());
 
@@ -147,17 +155,6 @@ public class WXStateRecord {
             super();
             this.maxSize = maxSize;
         }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            E e = this.poll();
-            while (null != e){
-                builder.append('[').append(e.toString()).append(']').append("->");
-                e = this.poll();
-            }
-            return builder.toString();
-        }
     }
 
     private static class Info implements Comparable<Info>{
@@ -174,7 +171,7 @@ public class WXStateRecord {
         @Override
         public String toString() {
             return new StringBuilder()
-                .append(instanceId).append(',').append(time).append(',').append(msg)
+                .append('[').append(instanceId).append(',').append(time).append(',').append(msg).append("]->")
                 .toString();
         }
 
diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
index 2560777..d8bc7a9 100644
--- a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java
@@ -26,6 +26,7 @@ import com.alibaba.fastjson.JSON;
 import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.WXSDKManager;
+import com.taobao.weex.performance.WXStateRecord;
 import com.taobao.weex.utils.tools.LogDetail;
 
 import java.io.IOException;
@@ -81,6 +82,9 @@ public class WXLogUtils {
     if(TextUtils.isEmpty(msg) || TextUtils.isEmpty(tag) || level == null || TextUtils.isEmpty(level.getName())){
       return;
     }
+    if (level == LogLevel.ERROR && !TextUtils.isEmpty(msg) && msg.contains("IPCException")){
+      WXStateRecord.getInstance().recordIPCException("ipc",msg);
+    }
 
     if(sLogWatcher !=null){
       sLogWatcher.onLog(level.getName(), tag, msg);
diff --git a/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp b/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
index 9958f21..36e853c 100644
--- a/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
+++ b/weex_core/Source/android/bridge/script/script_side_in_multi_process.cpp
@@ -59,7 +59,7 @@ int ScriptSideInMultiProcess::InitFramework(
       return false;
     }
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException InitFramework %s", e.msg());
     return false;
   }
   return true;
@@ -88,7 +88,7 @@ int ScriptSideInMultiProcess::InitAppFramework(
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("initAppFramework error %s", e.msg());
+    LOGE("IPCException initAppFramework error %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -115,7 +115,7 @@ int ScriptSideInMultiProcess::CreateAppContext(const char *instanceId,
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException CreateAppContext %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -156,7 +156,7 @@ std::unique_ptr<WeexJSResult> ScriptSideInMultiProcess::ExecJSOnAppWithResult(co
       return ret;
 
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJSOnAppWithResult %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -204,7 +204,7 @@ int ScriptSideInMultiProcess::CallJSOnAppContext(
     }
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException CallJSOnAppContext %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -228,7 +228,7 @@ int ScriptSideInMultiProcess::DestroyAppContext(const char *instanceId) {
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
     return true;
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException DestroyAppContext %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -255,7 +255,7 @@ int ScriptSideInMultiProcess::ExecJsService(const char *source) {
     }
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJsService error %s", e.msg());
     return false;
   }
 }
@@ -304,14 +304,14 @@ int ScriptSideInMultiProcess::ExecJS(const char *instanceId,
 
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
     if (result->getType() != IPCType::INT32) {
-      LOGE("execJS Unexpected result type");
+      LOGE("IPCException execJS Unexpected result type");
       return false;
     }
 
     return result->get<jint>();
 
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJS %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -380,7 +380,7 @@ std::unique_ptr<WeexJSResult> ScriptSideInMultiProcess::ExecJSWithResult(
 
       return ret;
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJSWithResult %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -396,7 +396,7 @@ void ScriptSideInMultiProcess::ExecJSWithCallback(
     std::unique_ptr<WeexJSResult> ret;
   try {
     if(sender_ == nullptr) {
-      LOGE("ExecJSWithResult sender is null");
+      LOGE("IPCException ExecJSWithResult sender is null");
       return;
     }
     std::unique_ptr<IPCSerializer> serializer(createIPCSerializer());
@@ -421,7 +421,7 @@ void ScriptSideInMultiProcess::ExecJSWithCallback(
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
 
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJSWithCallback %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -461,7 +461,7 @@ int ScriptSideInMultiProcess::CreateInstance(
     }
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("%s %s","Create Instance is failed and Error msg is", e.msg());
+    LOGE("IPCException %s %s","Create Instance is failed and Error msg is", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -498,7 +498,7 @@ std::unique_ptr<WeexJSResult> ScriptSideInMultiProcess::ExecJSOnInstance(const c
     string[ret->length] = '\0';
       return ret;
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException ExecJSOnInstance %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -526,7 +526,7 @@ int ScriptSideInMultiProcess::DestroyInstance(const char *instanceId) {
     }
     return result->get<jint>();
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException DestroyInstance %s", e.msg());
     // report crash here
     WeexCoreManager::Instance()
         ->getPlatformBridge()
@@ -548,7 +548,7 @@ int ScriptSideInMultiProcess::UpdateGlobalConfig(const char *config) {
     std::unique_ptr<IPCBuffer> buffer = serializer->finish();
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException UpdateGlobalConfig %s", e.msg());
   }
   return true;
 }
@@ -569,7 +569,7 @@ int ScriptSideInMultiProcess::UpdateInitFrameworkParams(const std::string &key,
     std::unique_ptr<IPCBuffer> buffer = serializer->finish();
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException UpdateInitFrameworkParams %s", e.msg());
   }
   return true;
 
@@ -588,7 +588,7 @@ void ScriptSideInMultiProcess::SetLogType(const int logLevel, const bool isPerf)
     std::unique_ptr<IPCBuffer> buffer = serializer->finish();
     std::unique_ptr<IPCResult> result = sender_->send(buffer.get());
   } catch (IPCException &e) {
-    LOGE("%s", e.msg());
+    LOGE("IPCException SetLogType %s", e.msg());
   }
   return;
 }
diff --git a/weex_core/Source/android/multiprocess/weex_js_connection.cpp b/weex_core/Source/android/multiprocess/weex_js_connection.cpp
index ffc3d45..11bd292 100644
--- a/weex_core/Source/android/multiprocess/weex_js_connection.cpp
+++ b/weex_core/Source/android/multiprocess/weex_js_connection.cpp
@@ -189,7 +189,7 @@ static void *newIPCServer(void *_td) {
       futexPageQueue->spinWaitPeer();
       listener->listen();
     } catch (IPCException &e) {
-        LOGE("server died");
+        LOGE("IPCException server died %s",e.msg());
         closeServerFd(td->ipcServerFd);
         base::android::DetachFromVM();
         pthread_exit(NULL);
diff --git a/weex_core/Source/third_party/IPC/IPCFutexPageQueue.cpp b/weex_core/Source/third_party/IPC/IPCFutexPageQueue.cpp
index fd9b72d..3699192 100644
--- a/weex_core/Source/third_party/IPC/IPCFutexPageQueue.cpp
+++ b/weex_core/Source/third_party/IPC/IPCFutexPageQueue.cpp
@@ -112,6 +112,7 @@ void IPCFutexPageQueue::lock(size_t id, bool checkFinish)
                 break;
             }
             struct timespec waitTime = { m_timeoutSec, 0 };
+            IPC_LOGE("IPCException IPCFutexPageQueue:: start futex wait");
             int futexReturn = __futex(pageStart + 1, FUTEX_WAIT, 0, &waitTime);
             if (futexReturn == -1) {
                 int myerrno = errno;