异常栈转换优化

issue:https://gitee.com/openharmony/ability_ability_runtime/issues/IBQ5BW

Signed-off-by: rentangyu <rentangyu@huawei.com>
This commit is contained in:
rentangyu
2025-03-03 10:55:24 +08:00
parent 6155b69c40
commit c68ff3ebed
3 changed files with 46 additions and 182 deletions
@@ -113,30 +113,10 @@ std::string SourceMap::TranslateBySourceMap(const std::string& stackStr)
ExtractStackInfo(stackStr, res);
// collect error info first
uint32_t i = 0;
std::string codeStart = "SourceCode (";
std::string sourceCode = "";
if (!res.empty()) {
std::string fristLine = res[0];
uint32_t codeStartLen = codeStart.length();
if (fristLine.substr(0, codeStartLen).compare(codeStart) == 0) {
sourceCode = fristLine.substr(codeStartLen, fristLine.length() - codeStartLen - 1);
i = 1; // 1 means Convert from the second line
}
}
// collect error info first
for (; i < res.size(); i++) {
for (uint32_t i = 0; i < res.size(); i++) {
std::string temp = res[i];
size_t start;
size_t end;
if (isModular_) {
start = temp.find(openBrace);
end = temp.find(":");
} else {
start = temp.find("/ets/");
end = temp.rfind("_.js");
}
size_t start = temp.find(openBrace);
size_t end = temp.find(":");
if (end <= start) {
continue;
}
@@ -151,23 +131,12 @@ std::string SourceMap::TranslateBySourceMap(const std::string& stackStr)
break;
}
std::string sourceInfo;
if (isModular_) {
auto iter = sourceMaps_.find(key);
if (iter != sourceMaps_.end()) {
sourceInfo = GetSourceInfo(line, column, *(iter->second), key);
} else {
ans = ans + temp + "\n";
continue;
}
auto iter = sourceMaps_.find(key);
if (iter != sourceMaps_.end()) {
sourceInfo = GetSourceInfo(line, column, *(iter->second), key);
} else {
std::string url = key + ".js.map";
std::string curSourceMap;
if (!ReadSourceMapData(hapPath_, url, curSourceMap)) {
TAG_LOGW(AAFwkTag::JSENV, "ReadSourceMapData fail");
continue;
}
ExtractSourceMapData(curSourceMap, nonModularMap_);
sourceInfo = GetSourceInfo(line, column, *nonModularMap_, key);
ans = ans + temp + "\n";
continue;
}
if (sourceInfo.empty()) {
continue;
@@ -182,76 +151,46 @@ std::string SourceMap::TranslateBySourceMap(const std::string& stackStr)
return ans;
}
void SourceMap::SetSourceMapData()
{
for (auto it = sources_.begin(); it != sources_.end(); ++it) {
std::string mappings = mappings_[it->first];
if (mappings.size() < FLAG_MAPPINGS_LEN + 1) {
TAG_LOGE(AAFwkTag::JSENV, "Translate failed, url: %{public}s", it->first.c_str());
continue;
}
std::shared_ptr<SourceMapData> modularMap = std::make_shared<SourceMapData>();
if (modularMap == nullptr) {
TAG_LOGE(AAFwkTag::JSENV, "New SourceMapData failed");
continue;
}
modularMap->entryPackageInfo_.push_back(entryPackageInfo_[it->first]);
modularMap->packageInfo_.push_back(packageInfo_[it->first]);
ExtractSourceMapData(mappings.substr(FLAG_MAPPINGS_LEN, mappings.size() - FLAG_MAPPINGS_LEN - 1), modularMap);
modularMap->sources_.push_back(it->second);
sourceMaps_[it->first] = modularMap;
}
}
void SourceMap::SplitSourceMap(const std::string& sourceMapData)
{
std::lock_guard<std::mutex> lock(sourceMapMutex_);
if (!isModular_) {
if (!nonModularMap_) {
nonModularMap_ = std::make_shared<SourceMapData>();
}
return ExtractSourceMapData(sourceMapData, nonModularMap_);
}
std::stringstream ss(sourceMapData);
std::string tmp;
std::string url;
std::getline(ss, tmp);
bool isUrl = true;
std::shared_ptr<SourceMapData> mapData;
while (std::getline(ss, tmp)) {
if (isUrl && tmp.size() > REAL_SOURCE_INDEX) {
if (isUrl && tmp.size() > REAL_SOURCE_INDEX) { // url
url = tmp.substr(REAL_URL_INDEX, tmp.size() - REAL_SOURCE_INDEX);
isUrl = false;
mapData = std::make_shared<SourceMapData>();
continue;
}
if (StringStartWith(tmp.c_str(), FLAG_SOURCES)) {
if (StringStartWith(tmp.c_str(), FLAG_SOURCES)) { // sources
std::getline(ss, tmp);
sources_.emplace(url, tmp);
mapData->sources_ = tmp;
continue;
}
if (StringStartWith(tmp.c_str(), FLAG_MAPPINGS)) {
mappings_.emplace(url, tmp);
if (StringStartWith(tmp.c_str(), FLAG_MAPPINGS)) { // mapping
ExtractSourceMapData(tmp.substr(FLAG_MAPPINGS_LEN, tmp.size() - FLAG_MAPPINGS_LEN - 1), mapData);
continue;
}
if (StringStartWith(tmp.c_str(), FLAG_ENTRY_PACKAGE_INFO)) {
entryPackageInfo_.emplace(url, tmp);
if (StringStartWith(tmp.c_str(), FLAG_ENTRY_PACKAGE_INFO)) { // entryPackageInfo
mapData->packageName_ = tmp;
continue;
}
if (StringStartWith(tmp.c_str(), FLAG_PACKAGE_INFO)) {
packageInfo_.emplace(url, tmp);
if (StringStartWith(tmp.c_str(), FLAG_PACKAGE_INFO)) { // packageInfo
mapData->packageName_ = tmp;
mapData->isPackageInfo_ = true;
continue;
}
if (StringStartWith(tmp.c_str(), FLAG_END)) {
sourceMaps_[url] = mapData;
isUrl = true;
}
}
SetSourceMapData();
mappings_.clear();
sources_.clear();
entryPackageInfo_.clear();
packageInfo_.clear();
}
void SourceMap::ExtractStackInfo(const std::string& stackStr, std::vector<std::string>& res)
@@ -293,19 +232,13 @@ void SourceMap::ExtractSourceMapData(const std::string& allmappings, std::shared
}
// after decode, assgin each value to the position
curMapData->nowPos_.afterColumn += ans[0];
curMapData->nowPos_.sourcesVal += ans[INDEX_ONE];
curMapData->nowPos_.beforeRow += ans[INDEX_TWO];
curMapData->nowPos_.beforeColumn += ans[INDEX_THREE];
if (ans.size() == ANS_MAP_SIZE) {
curMapData->nowPos_.namesVal += ans[INDEX_FOUR];
}
curMapData->afterPos_.push_back({
curMapData->nowPos_.beforeRow,
curMapData->nowPos_.beforeColumn,
curMapData->nowPos_.afterRow,
curMapData->nowPos_.afterColumn,
curMapData->nowPos_.sourcesVal,
curMapData->nowPos_.namesVal
});
}
curMapData->mappings_.clear();
@@ -314,7 +247,7 @@ void SourceMap::ExtractSourceMapData(const std::string& allmappings, std::shared
MappingInfo SourceMap::Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key)
{
if (row < 1 || col < 1 || targetMap.afterPos_.empty() || targetMap.sources_[0].empty()) {
if (row < 1 || col < 1 || targetMap.afterPos_.empty() || targetMap.sources_.empty()) {
return MappingInfo {row, col, key};
}
row--;
@@ -336,8 +269,8 @@ MappingInfo SourceMap::Find(int32_t row, int32_t col, const SourceMapData& targe
left = mid + 1;
}
}
std::string sources = targetMap.sources_[0].substr(REAL_SOURCE_INDEX,
targetMap.sources_[0].size() - REAL_SOURCE_INDEX - 1);
std::string sources = targetMap.sources_.substr(REAL_SOURCE_INDEX,
targetMap.sources_.size() - REAL_SOURCE_INDEX - 1);
auto pos = sources.find(WEBPACK);
if (pos != std::string::npos) {
sources.replace(pos, sizeof(WEBPACK) - 1, "");
@@ -397,27 +330,6 @@ void SourceMap::GetPosInfo(const std::string& temp, int32_t start, std::string&
}
}
std::string SourceMap::GetRelativePath(const std::string& sources)
{
std::string temp = sources;
std::size_t splitPos = std::string::npos;
const static int pathLevel = 3;
int i = 0;
while (i < pathLevel) {
splitPos = temp.find_last_of("/\\");
if (splitPos != std::string::npos) {
temp = temp.substr(0, splitPos - 1);
} else {
break;
}
i++;
}
if (i == pathLevel) {
return sources.substr(splitPos);
}
return sources;
}
std::vector<std::string> SourceMap::HandleMappings(const std::string& mapping)
{
std::vector<std::string> keyInfo;
@@ -489,21 +401,13 @@ std::string SourceMap::GetSourceInfo(const std::string& line, const std::string&
#else
mapInfo = Find(StringToInt(line) - offSet, StringToInt(column), targetMap, key);
#endif
std::string sources = isModular_ ? mapInfo.sources : GetRelativePath(mapInfo.sources);
std::string entryPackageInfo = targetMap.entryPackageInfo_[0];
std::string packageInfo = targetMap.packageInfo_[0];
if (!packageInfo.empty()) {
auto last = packageInfo.rfind('|');
std::string sources = mapInfo.sources;
std::string packageName = targetMap.packageName_;
if (!packageName.empty()) {
auto last = packageName.rfind('|');
if (last != std::string::npos) {
sourceInfo = packageInfo.substr(FLAG_PACKAGE_INFO_SIZE, last - FLAG_PACKAGE_INFO_SIZE);
return sourceInfo.append(" (" + sources + ":" + std::to_string(mapInfo.row) + ":" +
std::to_string(mapInfo.col) + ")");
}
}
if (!entryPackageInfo.empty()) {
auto last = entryPackageInfo.rfind('|');
if (last != std::string::npos) {
sourceInfo = entryPackageInfo.substr(FLAG_ENTRY_PACKAGE_INFO_SIZE, last - FLAG_ENTRY_PACKAGE_INFO_SIZE);
auto packageNameSize = targetMap.isPackageInfo_ ? FLAG_PACKAGE_INFO_SIZE : FLAG_ENTRY_PACKAGE_INFO_SIZE;
sourceInfo = packageName.substr(packageNameSize, last - packageNameSize);
return sourceInfo.append(" (" + sources + ":" + std::to_string(mapInfo.row) + ":" +
std::to_string(mapInfo.col) + ")");
}
@@ -549,14 +453,11 @@ bool SourceMap::ReadSourceMapData(const std::string& hapPath, const std::string&
bool SourceMap::TranslateUrlPositionBySourceMap(std::string& url, int& line, int& column, std::string& packageName)
{
if (isModular_) {
auto iter = sourceMaps_.find(url);
if (iter != sourceMaps_.end()) {
return GetLineAndColumnNumbers(line, column, *(iter->second), url, packageName);
}
TAG_LOGE(AAFwkTag::JSENV, "stageMode sourceMaps find fail");
return false;
auto iter = sourceMaps_.find(url);
if (iter != sourceMaps_.end()) {
return GetLineAndColumnNumbers(line, column, *(iter->second), url, packageName);
}
TAG_LOGE(AAFwkTag::JSENV, "stageMode sourceMaps find fail");
return false;
}
@@ -597,19 +498,12 @@ void SourceMap::GetHapPath(const std::string &bundleName, std::vector<std::strin
void SourceMap::GetPackageName(const SourceMapData& targetMap, std::string& packageName)
{
std::string entryPackageInfo = targetMap.entryPackageInfo_[0];
std::string packageInfo = targetMap.packageInfo_[0];
std::string packageInfo = targetMap.packageName_;
if (!packageInfo.empty()) {
auto last = packageInfo.rfind('|');
if (last != std::string::npos) {
packageName = packageInfo.substr(FLAG_PACKAGE_INFO_SIZE, last - FLAG_PACKAGE_INFO_SIZE);
return;
}
}
if (!entryPackageInfo.empty()) {
auto last = entryPackageInfo.rfind('|');
if (last != std::string::npos) {
packageName = entryPackageInfo.substr(FLAG_ENTRY_PACKAGE_INFO_SIZE, last - FLAG_ENTRY_PACKAGE_INFO_SIZE);
auto packageNameSize = targetMap.isPackageInfo_ ? FLAG_PACKAGE_INFO_SIZE : FLAG_ENTRY_PACKAGE_INFO_SIZE;
packageName = packageInfo.substr(packageNameSize, last - packageNameSize);
}
}
}
@@ -36,8 +36,6 @@ struct SourceMapInfo {
int32_t beforeColumn = 0;
int32_t afterRow = 0;
int32_t afterColumn = 0;
int32_t sourcesVal = 0;
int32_t namesVal = 0;
};
struct MappingInfo {
@@ -52,10 +50,9 @@ public:
~SourceMapData() = default;
SourceMapInfo nowPos_;
std::vector<std::string> entryPackageInfo_;
std::vector<std::string> packageInfo_;
std::vector<std::string> sources_;
std::vector<std::string> names_;
std::string packageName_;
bool isPackageInfo_ = false;
std::string sources_;
std::vector<std::string> mappings_;
std::vector<SourceMapInfo> afterPos_;
@@ -93,24 +90,15 @@ private:
bool VlqRevCode(const std::string& vStr, std::vector<int32_t>& ans);
MappingInfo Find(int32_t row, int32_t col, const SourceMapData& targetMap, const std::string& key);
void GetPosInfo(const std::string& temp, int32_t start, std::string& line, std::string& column);
std::string GetRelativePath(const std::string& sources);
std::string GetSourceInfo(const std::string& line, const std::string& column,
const SourceMapData& targetMap, const std::string& key);
void SetSourceMapData();
static void GetPackageName(const SourceMapData& targetMap, std::string& packageName);
private:
bool isModular_ = true;
std::string hapPath_;
std::unordered_map<std::string, std::shared_ptr<SourceMapData>> sourceMaps_;
std::shared_ptr<SourceMapData> nonModularMap_;
static ReadSourceMapCallback readSourceMapFunc_;
static std::mutex sourceMapMutex_;
static GetHapPathCallback getHapPathFunc_;
std::unordered_map<std::string, std::string> sources_;
std::unordered_map<std::string, std::string> mappings_;
std::unordered_map<std::string, std::string> entryPackageInfo_;
std::unordered_map<std::string, std::string> packageInfo_;
std::unordered_map<std::string, std::shared_ptr<SourceMapData>> sourceMaps_;
};
} // namespace JsEnv
} // namespace OHOS
@@ -177,7 +177,7 @@ HWTEST_F(SourceMapTest, JsEnv_SourceMap_0900, Function | MediumTest | Level1)
int32_t row = 249;
int32_t col = 3;
SourceMapData targetMap;
targetMap.sources_.emplace_back("sources");
targetMap.sources_ = ("sources");
for (int32_t i = 0; i < 10; i++) {
for (int32_t j = 0; j < 5; j++) {
SourceMapInfo mapInfo;
@@ -206,7 +206,7 @@ HWTEST_F(SourceMapTest, JsEnv_SourceMap_1000, Function | MediumTest | Level1)
int32_t row = 2;
int32_t col = 3;
SourceMapData targetMap;
targetMap.sources_.emplace_back("sources");
targetMap.sources_ = ("sources");
for (int32_t i = 0; i < 10; i++) {
for (int32_t j = 0; j < 5; j++) {
SourceMapInfo mapInfo;
@@ -243,23 +243,6 @@ HWTEST_F(SourceMapTest, JsEnv_SourceMap_1300, Function | MediumTest | Level1)
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1300 end";
}
/**
* @tc.number: JsEnv_SourceMap_1400
* @tc.name: GetRelativePath
* @tc.desc: Verifying GetRelativePath succeeded.
* @tc.require: #I6T4K1
*/
HWTEST_F(SourceMapTest, JsEnv_SourceMap_1400, Function | MediumTest | Level1)
{
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1400 start";
auto modSourceMap = std::make_shared<SourceMap>();
std::string sources = "TEST:/data/app/MainAbility.js";
auto res = modSourceMap->GetRelativePath(sources);
EXPECT_STREQ(res.c_str(), "/data/app/MainAbility.js");
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1400 end";
}
/**
* @tc.number: JsEnv_SourceMap_1500
* @tc.name: GetPosInfo
@@ -411,8 +394,7 @@ HWTEST_F(SourceMapTest, JsEnv_SourceMap_1900, Function | MediumTest | Level1)
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1900 start";
SourceMapData targetMap;
std::string packageName;
targetMap.entryPackageInfo_.emplace_back(" \"entry-package-info\": \"entry|1.0.0\n");
targetMap.packageInfo_.emplace_back("");
targetMap.packageName_ = " \"entry-package-info\": \"entry|1.0.0\n";
SourceMap::GetPackageName(targetMap, packageName);
EXPECT_STREQ("entry", packageName.c_str());
GTEST_LOG_(INFO) << "JsEnv_SourceMap_1900 end";
@@ -423,8 +405,8 @@ HWTEST_F(SourceMapTest, JsEnv_SourceMap_2000, Function | MediumTest | Level1)
GTEST_LOG_(INFO) << "JsEnv_SourceMap_2000 start";
SourceMapData targetMap;
std::string packageName;
targetMap.entryPackageInfo_.emplace_back(" \"entry-package-info\": \"entrypackageinfo|1.0.0\n");
targetMap.packageInfo_.emplace_back(" \"package-info\": \"packageinfo|1.0.0\n");
targetMap.packageName_ = " \"package-info\": \"packageinfo|1.0.0\n";
targetMap.isPackageInfo_ = true;
SourceMap::GetPackageName(targetMap, packageName);
EXPECT_STREQ("packageinfo", packageName.c_str());
GTEST_LOG_(INFO) << "JsEnv_SourceMap_2000 end";