【归一化】stage模型注册异常监听归一&&sourcemap独立so

Signed-off-by: chenyuyan <chenyuyan3@huawei.com>
Change-Id: I11b2f08db27e5b71ec173e21af358a87a01d4ecd
This commit is contained in:
chenyuyan 2023-03-30 09:49:29 +08:00
parent 47337409eb
commit f17b76c7bb
17 changed files with 269 additions and 54 deletions

View File

@ -177,6 +177,15 @@
},
"name": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime:runtime"
},
{
"header": {
"header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/",
"header_files": [
"source_map.h"
]
},
"name": "//foundation/ability/ability_runtime/interfaces/inner_api/runtime:source_map"
},
{
"header": {
"header_base": "//foundation/ability/ability_runtime/interfaces/inner_api/napi_base_context/include",

View File

@ -139,6 +139,7 @@ ohos_shared_library("appkit_native") {
"ability_runtime:abilitykit_native",
"ability_runtime:app_manager",
"ability_runtime:runtime",
"ability_runtime:source_map",
"bundle_framework:appexecfwk_base",
"c_utils:utils",
"common_event_service:cesfwk_innerkits",

View File

@ -1079,51 +1079,16 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
auto& jsEngine = (static_cast<AbilityRuntime::JsRuntime&>(*runtime)).GetNativeEngine();
auto bundleName = appInfo.bundleName;
auto versionCode = appInfo.versionCode;
JsEnv::UncaughtInfo uncaughtInfo;
uncaughtInfo.hapPath = hapPath;
wptr<MainThread> weak = this;
auto uncaughtTask = [weak, bundleName, versionCode, hapPath](NativeValue* v) {
HILOG_INFO("Js uncaught exception callback come.");
uncaughtInfo.uncaughtTask = [weak, bundleName, versionCode]
(std::string summary, const JsEnv::ErrorObject errorObj) {
auto appThread = weak.promote();
if (appThread == nullptr) {
HILOG_ERROR("appThread is nullptr, HandleLaunchApplication failed.");
return;
}
NativeObject* obj = AbilityRuntime::ConvertNativeValueTo<NativeObject>(v);
std::string errorMsg = GetNativeStrFromJsTaggedObj(obj, "message");
std::string errorName = GetNativeStrFromJsTaggedObj(obj, "name");
std::string errorStack = GetNativeStrFromJsTaggedObj(obj, "stack");
std::string summary = "Error message:" + errorMsg + "\n";
const AppExecFwk::ErrorObject errorObj = {
.name = errorName,
.message = errorMsg,
.stack = errorStack
};
if (obj != nullptr && obj->HasProperty("code")) {
std::string errorCode = GetNativeStrFromJsTaggedObj(obj, "code");
summary += "Error code:" + errorCode + "\n";
}
if (appThread->application_ == nullptr) {
HILOG_ERROR("appThread is nullptr, HandleLaunchApplication failde.");
return;
}
auto& bindSourceMaps = (static_cast<AbilityRuntime::JsRuntime&>(*
(appThread->application_->GetRuntime()))).GetSourceMap();
// bindRuntime.bindSourceMaps lazy loading
if (errorStack.empty()) {
HILOG_ERROR("errorStack is empty");
return;
}
HILOG_INFO("JS Stack:\n%{public}s", errorStack.c_str());
auto errorPos = ModSourceMap::GetErrorPos(errorStack);
std::string error;
if (obj != nullptr) {
NativeValue* value = obj->GetProperty("errorfunc");
NativeFunction* fuc = AbilityRuntime::ConvertNativeValueTo<NativeFunction>(value);
if (fuc != nullptr) {
error = fuc->GetSourceCodeInfo(errorPos);
}
}
summary += error + "Stacktrace:\n" + OHOS::AbilityRuntime::ModSourceMap::TranslateBySourceMap(errorStack,
bindSourceMaps, hapPath);
time_t timet;
time(&timet);
HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::AAFWK, "JS_ERROR",
@ -1132,7 +1097,7 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
EVENT_KEY_VERSION, std::to_string(versionCode),
EVENT_KEY_TYPE, JSCRASH_TYPE,
EVENT_KEY_HAPPEN_TIME, timet,
EVENT_KEY_REASON, errorName,
EVENT_KEY_REASON, errorObj.name,
EVENT_KEY_JSVM, JSVM_TYPE,
EVENT_KEY_SUMMARY, summary);
if (ApplicationDataManager::GetInstance().NotifyUnhandledException(summary) &&
@ -1141,10 +1106,10 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
}
// if app's callback has been registered, let app decide whether exit or not.
HILOG_ERROR("\n%{public}s is about to exit due to RuntimeError\nError type:%{public}s\n%{public}s",
bundleName.c_str(), errorName.c_str(), summary.c_str());
bundleName.c_str(), errorObj.name.c_str(), summary.c_str());
appThread->ScheduleProcessSecurityExit();
};
jsEngine.RegisterUncaughtExceptionHandler(uncaughtTask);
}
runtime->RegisterUncaughtExceptionHandler(uncaughtInfo);
application_->SetRuntime(std::move(runtime));
std::weak_ptr<OHOSApplication> wpApplication = application_;

View File

@ -600,7 +600,9 @@ void JsRuntime::SetAppLibPath(const std::map<std::string, std::vector<std::strin
void JsRuntime::InitSourceMap(const Options& options)
{
bindSourceMaps_ = std::make_unique<ModSourceMap>(options.bundleCodeDir, options.isStageModel);
if (jsEnv_ != nullptr) {
jsEnv_->InitSourceMap(options.bundleCodeDir, options.isStageModel);
}
}
void JsRuntime::Deinitialize()
@ -939,5 +941,11 @@ void JsRuntime::UpdateModuleNameAndAssetPath(const std::string& moduleName)
panda::JSNApi::SetAssetPath(vm, path);
panda::JSNApi::SetModuleName(vm, moduleName_);
}
void JsRuntime::RegisterUncaughtExceptionHandler(UncaughtInfo uncaughtInfo)
{
CHECK_POINTER(jsEnv_);
jsEnv_->RegisterUncaughtExceptionHandler(uncaughtInfo);
}
} // namespace AbilityRuntime
} // namespace OHOS

View File

@ -87,6 +87,7 @@ ohos_shared_library("runtime") {
"ability_base:string_utils",
"ability_base:want",
"ability_runtime:js_environment",
"ability_runtime:source_map",
"access_token:libaccesstoken_sdk",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
@ -118,3 +119,28 @@ ohos_shared_library("runtime") {
subsystem_name = "ability"
part_name = "ability_runtime"
}
config("source_map_config") {
include_dirs = [ "${ability_runtime_services_path}/common/include" ]
}
config("source_map_public_config") {
include_dirs = [ "include" ]
}
ohos_shared_library("source_map") {
sources = [ "${ability_runtime_native_path}/runtime/source_map.cpp" ]
configs = [ ":source_map_config" ]
public_configs = [ ":source_map_public_config" ]
external_deps = [
"ability_base:extractortool",
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
]
subsystem_name = "ability"
part_name = "ability_runtime"
}

View File

@ -90,6 +90,7 @@ public:
bool LoadRepairPatch(const std::string& hqfFile, const std::string& hapPath) override;
bool UnLoadRepairPatch(const std::string& hqfFile) override;
bool NotifyHotReloadPage() override;
void RegisterUncaughtExceptionHandler(UncaughtInfo uncaughtInfo);
NativeEngine* GetNativeEnginePointer() const;
panda::ecmascript::EcmaVM* GetEcmaVm() const;

View File

@ -28,7 +28,6 @@
#include "application_impl.h"
#include "resource_manager.h"
#include "foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/runtime.h"
#include "foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/source_map.h"
#include "ipc_singleton.h"
#include "native_engine/native_engine.h"
#include "watchdog.h"

View File

@ -15,7 +15,9 @@ import("//build/ohos.gni")
import("../../js_environment.gni")
config("js_environment_config") {
include_dirs = [ "${inner_api_path}" ]
include_dirs = [
"${inner_api_path}"
]
}
config("public_js_environment_config") {
@ -26,7 +28,11 @@ config("public_js_environment_config") {
}
ohos_shared_library("js_environment") {
sources = [ "src/js_environment.cpp" ]
sources = [
"src/js_environment.cpp",
"src/uncaught_exception_callback.cpp",
"${utils_path}/src/js_env_logger.cpp"
]
configs = [
":js_environment_config",
@ -35,9 +41,12 @@ ohos_shared_library("js_environment") {
public_configs = [ ":public_js_environment_config" ]
deps = [ "${arkui_path}/napi:ace_napi_ark" ]
deps = [
"${arkui_path}/napi:ace_napi_ark",
]
external_deps = [
"ability_runtime:source_map",
"ets_runtime:libark_jsruntime",
"napi:ace_napi",
]

View File

@ -18,6 +18,7 @@
#include "js_env_logger.h"
#include "js_environment_impl.h"
#include "native_engine/impl/ark/ark_native_engine.h"
#include "uncaught_exception_callback.h"
namespace OHOS {
namespace JsEnv {
@ -104,5 +105,20 @@ void JsEnvironment::RemoveTask(const std::string& name)
impl_->RemoveTask(name);
}
}
void JsEnvironment::InitSourceMap(const std::string bundleCodeDir, std::string isStageModel)
{
bool isStage = (isStageModel == "true");
bindSourceMaps_ = std::make_unique<AbilityRuntime::ModSourceMap>(bundleCodeDir, isStage);
}
void JsEnvironment::RegisterUncaughtExceptionHandler(JsEnv::UncaughtInfo uncaughtInfo)
{
if ((bindSourceMaps_ != nullptr) && (engine_ != nullptr)) {
engine_->RegisterUncaughtExceptionHandler(UncaughtExceptionCallback(uncaughtInfo.hapPath,
// uncaughtInfo.uncaughtTask, std::move(bindSourceMaps_)));
uncaughtInfo.uncaughtTask, *bindSourceMaps_));
}
}
} // namespace JsEnv
} // namespace OHOS

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "uncaught_exception_callback.h"
#include <string>
#include "js_env_logger.h"
#include "native_engine/native_engine.h"
namespace OHOS {
namespace JsEnv {
std::string UncaughtExceptionCallback::GetNativeStrFromJsTaggedObj(NativeObject* obj, const char* key)
{
if (obj == nullptr) {
JSENV_LOG_E("Failed to get value from key:%{public}s, Null NativeObject", key);
return "";
}
NativeValue* value = obj->GetProperty(key);
NativeString* valueStr = JsEnv::ConvertNativeValueTo<NativeString>(value);
if (valueStr == nullptr) {
JSENV_LOG_E("Failed to convert value from key:%{public}s", key);
return "";
}
size_t valueStrBufLength = valueStr->GetLength();
size_t valueStrLength = 0;
char* valueCStr = new (std::nothrow) char[valueStrBufLength + 1];
if (valueCStr == nullptr) {
JSENV_LOG_E("Failed to new valueCStr");
return "";
}
valueStr->GetCString(valueCStr, valueStrBufLength + 1, &valueStrLength);
std::string ret(valueCStr, valueStrLength);
delete []valueCStr;
JSENV_LOG_D("GetNativeStrFromJsTaggedObj Success %{public}s:%{public}s", key, ret.c_str());
return ret;
}
void UncaughtExceptionCallback::operator()(NativeValue* value)
{
NativeObject* obj = JsEnv::ConvertNativeValueTo<NativeObject>(value);
std::string errorMsg = GetNativeStrFromJsTaggedObj(obj, "message");
std::string errorName = GetNativeStrFromJsTaggedObj(obj, "name");
std::string errorStack = GetNativeStrFromJsTaggedObj(obj, "stack");
std::string summary = "Error message:" + errorMsg + "\n";
const JsEnv::ErrorObject errorObj = {
.name = errorName,
.message = errorMsg,
.stack = errorStack
};
if (obj != nullptr && obj->HasProperty("code")) {
std::string errorCode = GetNativeStrFromJsTaggedObj(obj, "code");
summary += "Error code:" + errorCode + "\n";
}
if (errorStack.empty()) {
JSENV_LOG_E("errorStack is empty");
return;
}
JSENV_LOG_I("JS Stack:\n%{public}s", errorStack.c_str());
auto errorPos = AbilityRuntime::ModSourceMap::GetErrorPos(errorStack);
std::string error;
if (obj != nullptr) {
NativeValue* value = obj->GetProperty("errorfunc");
NativeFunction* fuc = JsEnv::ConvertNativeValueTo<NativeFunction>(value);
if (fuc != nullptr) {
error = fuc->GetSourceCodeInfo(errorPos);
}
}
summary += error + "Stacktrace:\n" +AbilityRuntime::ModSourceMap::TranslateBySourceMap(errorStack, bindSourceMaps_, hapPath_);
if (uncaughtTask_) {
uncaughtTask_(summary, errorObj);
}
}
} // namespace JsEnv
} // namespace OHOS

View File

@ -31,9 +31,6 @@ struct JsEnvLogger final {
const char* fmt, ...);
};
void(*JsEnvLogger::logger)(JsEnvLogLevel level, const char* fileName, const char* functionName, int line,
const char* fmt, ...) = nullptr;
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
#define JSENV_LOG_D(fmt, ...) \

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_env_logger.h"
namespace OHOS {
namespace JsEnv {
void(*JsEnvLogger::logger)(JsEnvLogLevel level, const char* fileName, const char* functionName, int line,
const char* fmt, ...) = nullptr;
} // namespace JsEnv
} // namespace OHOS

View File

@ -20,10 +20,20 @@
#include "ecmascript/napi/include/jsnapi.h"
#include "js_environment_impl.h"
#include "native_engine/native_engine.h"
#include "source_map.h"
namespace OHOS {
namespace JsEnv {
class JsEnvironmentImpl;
struct ErrorObject {
std::string name;
std::string message;
std::string stack;
};
struct UncaughtInfo {
std::string hapPath;
std::function<void(std::string summary, const JsEnv::ErrorObject errorObj)> uncaughtTask;
};
class JsEnvironment final {
public:
JsEnvironment() {}
@ -52,15 +62,20 @@ public:
void InitWorkerModule();
void InitSourceMap(std::string bundleCodeDir, std::string isStageModel);
void InitSyscapModule();
void PostTask(const std::function<void()>& task, const std::string& name, int64_t delayTime);
void RemoveTask(const std::string& name);
void RegisterUncaughtExceptionHandler(JsEnv::UncaughtInfo uncaughtInfo);
private:
std::shared_ptr<JsEnvironmentImpl> impl_ = nullptr;
NativeEngine* engine_ = nullptr;
panda::ecmascript::EcmaVM* vm_ = nullptr;
std::unique_ptr<AbilityRuntime::ModSourceMap> bindSourceMaps_;
};
} // namespace JsEnv
} // namespace OHOS

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_UNCAUGHT_EXCEPTION_CALLBACK_H
#define OHOS_ABILITY_UNCAUGHT_EXCEPTION_CALLBACK_H
#include <string>
#include "js_environment.h"
#include "native_engine/native_engine.h"
namespace OHOS {
namespace JsEnv {
template<class T>
inline T* ConvertNativeValueTo(NativeValue* value)
{
return (value != nullptr) ? static_cast<T*>(value->GetInterface(T::INTERFACE_ID)) : nullptr;
}
class UncaughtExceptionCallback final {
public:
// UncaughtExceptionCallback(const std::string hapPath,
// std::function<void(std::string summary, const JsEnv::ErrorObject errorObj)> uncaughtTask,
// std::unique_ptr<AbilityRuntime::ModSourceMap> bindSourceMaps) {
// hapPath_ = hapPath;
// uncaughtTask_ = uncaughtTask;
// bindSourceMaps_ = std::make_unique<AbilityRuntime::ModSourceMap>(*bindSourceMaps);
// bindSourceMaps_ = std::move(bindSourceMaps);
// };
UncaughtExceptionCallback(const std::string hapPath,
std::function<void(std::string summary, const JsEnv::ErrorObject errorObj)> uncaughtTask,
AbilityRuntime::ModSourceMap& bindSourceMaps) :
hapPath_(hapPath), uncaughtTask_(uncaughtTask), bindSourceMaps_(bindSourceMaps)
{}
virtual ~UncaughtExceptionCallback() {};
void operator()(NativeValue* value);
std::string GetNativeStrFromJsTaggedObj(NativeObject* obj, const char* key);
private:
std::string hapPath_;
std::function<void(std::string summary, const JsEnv::ErrorObject errorObj)> uncaughtTask_;
// std::unique_ptr<AbilityRuntime::ModSourceMap> bindSourceMaps_;
AbilityRuntime::ModSourceMap& bindSourceMaps_;
};
} // namespace JsEnv
} // namespace OHOS
#endif // OHOS_ABILITY_UNCAUGHT_EXCEPTION_CALLBACK_H