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;