* Copyright (c) 2024-2026 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 <cstdio>
#include "ecmascript/dfx/stackinfo/tests/js_stackinfo_test.h"
#include "assembler/assembly-emitter.h"
#include "assembler/assembly-parser.h"
#include "class_data_accessor-inl.h"
#include "libziparchive/zip_archive.h"
#include "ecmascript/dfx/stackinfo/js_stackinfo.h"
#include "ecmascript/napi/include/dfx_jsnapi.h"
#include "ecmascript/tests/test_helper.h"
using namespace panda::ecmascript;
namespace panda::test {
class JsStackInfoTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
TestHelper::CreateEcmaVMWithScope(instance_, thread_, scope_);
instance_->SetEnableForceGC(false);
}
void TearDown() override
{
TestHelper::DestroyEcmaVMWithScope(instance_, scope_);
JsStackInfo::nameMap.clear();
}
EcmaVM *instance_ {nullptr};
EcmaHandleScope *scope_ {nullptr};
JSThread *thread_ {nullptr};
};
template<typename T>
uintptr_t ToUintPtr(T frame)
{
return static_cast<uintptr_t>(frame);
}
bool ReadMemFunc([[maybe_unused]] void *ctx, uintptr_t addr, uintptr_t *value)
{
*value = *(reinterpret_cast<uintptr_t *>(addr));
return true;
}
struct SafeMemContext {
std::vector<std::pair<uintptr_t, uintptr_t>> validRanges;
uintptr_t readValue = 0;
void AddRange(uintptr_t start, uintptr_t end)
{
validRanges.push_back({start, end});
}
bool IsValid(uintptr_t addr) const
{
for (const auto& range : validRanges) {
if (addr >= range.first && addr < range.second) {
return true;
}
}
return false;
}
};
bool SafeReadMemFuncForJit(void *ctx, uintptr_t addr, uintptr_t *value)
{
SafeMemContext *safeCtx = static_cast<SafeMemContext*>(ctx);
if (safeCtx && safeCtx->IsValid(addr)) {
*value = *(reinterpret_cast<uintptr_t *>(addr));
return true;
}
*value = safeCtx ? safeCtx->readValue : 0;
return false;
}
* @tc.name: ArkFrameCheck
* @tc.desc: Check whether the result returned through "ArkFrameCheck" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestArkFrameCheck)
{
for (uintptr_t i = 0; i < 25; i++) {
bool ret = ArkFrameCheck(i);
if (i == ToUintPtr(FrameType::OPTIMIZED_ENTRY_FRAME) ||
i == ToUintPtr(FrameType::ASM_INTERPRETER_ENTRY_FRAME)) {
EXPECT_TRUE(ret == true);
} else {
EXPECT_TRUE(ret == false);
}
}
}
* @tc.name: IsJsFunctionFrame
* @tc.desc: Check whether the result returned through "IsJsFunctionFrame" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestIsJsFunctionFrame)
{
for (uintptr_t i = 0; i < 25; i++) {
bool ret = IsJsFunctionFrame(i);
if (i == ToUintPtr(FrameType::ASM_INTERPRETER_FRAME) ||
i == ToUintPtr(FrameType::INTERPRETER_CONSTRUCTOR_FRAME) ||
i == ToUintPtr(FrameType::INTERPRETER_FRAME) ||
i == ToUintPtr(FrameType::INTERPRETER_FAST_NEW_FRAME)) {
EXPECT_TRUE(ret == true);
} else {
EXPECT_TRUE(ret == false);
}
}
}
* @tc.name: IsFastJitFunctionFrame
* @tc.desc: Check whether the result returned through "IsFastJitFunctionFrame" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestIsFastJitFunctionFrame)
{
for (uintptr_t i = 0; i < 25; i++) {
bool ret = IsFastJitFunctionFrame(i);
if (i == ToUintPtr(FrameType::FASTJIT_FUNCTION_FRAME) ||
i == ToUintPtr(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME)) {
EXPECT_TRUE(ret == true);
} else {
EXPECT_TRUE(ret == false);
}
}
}
* @tc.name: IsNativeFunctionFrame
* @tc.desc: Check whether the result returned through "IsNativeFunctionFrame" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestIsNativeFunctionFrame)
{
for (uintptr_t i = 0; i < 25; i++) {
bool ret = IsNativeFunctionFrame(i);
if (i == ToUintPtr(FrameType::OPTIMIZED_FRAME) ||
i == ToUintPtr(FrameType::BASELINE_BUILTIN_FRAME) ||
i == ToUintPtr(FrameType::ASM_BRIDGE_FRAME) ||
i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME) ||
i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME) ||
i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME) ||
i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) ||
i == ToUintPtr(FrameType::LEAVE_FRAME) ||
i == ToUintPtr(FrameType::LEAVE_FRAME_WITH_ARGV) ||
i == ToUintPtr(FrameType::BUILTIN_CALL_LEAVE_FRAME) ||
i == ToUintPtr(FrameType::BUILTIN_FRAME) ||
i == ToUintPtr(FrameType::BUILTIN_ENTRY_FRAME) ||
i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV) ||
i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME) ||
i == ToUintPtr(FrameType::ASM_INTERPRETER_BRIDGE_FRAME)) {
EXPECT_TRUE(ret == true);
} else {
EXPECT_TRUE(ret == false);
}
}
}
* @tc.name: IsAotFunctionFrame
* @tc.desc: Check whether the result returned through "IsAotFunctionFrame" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestIsAotFunctionFrame)
{
for (uintptr_t i = 0; i < 25; i++) {
bool ret = IsAotFunctionFrame(i);
if (i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) ||
i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME)) {
EXPECT_TRUE(ret == true);
} else {
EXPECT_TRUE(ret == false);
}
}
}
* @tc.name: ReadMethodInfo
* @tc.desc: Check whether the result returned through "ReadMethodInfo" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestReadMethodInfo)
{
const char *filename = "__JSPandaFileManagerTest1.pa";
const char *data = R"(
.function void foo() {
return
}
)";
pandasm::Parser parser;
auto res = parser.Parse(data);
auto file = pandasm::AsmEmitter::Emit(res.Value());
auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
EXPECT_TRUE(jsPandaFile != nullptr);
CVector<MethodInfo> result;
const panda_file::File *pf = jsPandaFile->GetPandaFile();
Span<const uint32_t> classIndexes = jsPandaFile->GetClasses();
for (const uint32_t index : classIndexes) {
panda_file::File::EntityId classId(index);
if (jsPandaFile->IsExternal(classId)) {
continue;
}
panda_file::ClassDataAccessor cda(*pf, classId);
cda.EnumerateMethods([&result, jsPandaFile](panda_file::MethodDataAccessor &mda) {
auto info = JSStackTrace::ReadMethodInfo(mda);
if (!info) {
return;
}
result.push_back(info.value());
});
}
EXPECT_TRUE(result.size() > 0);
}
* @tc.name: ReadAllMethodInfos
* @tc.desc: Check whether the result returned through "ReadAllMethodInfos" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestReadAllMethodInfos)
{
const char *filename = "__JsStackInfoTest.pa";
const char *data = R"(
.function void foo() {
return
}
)";
pandasm::Parser parser;
auto res = parser.Parse(data);
auto file = pandasm::AsmEmitter::Emit(res.Value());
auto pf = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
EXPECT_TRUE(pf != nullptr);
auto methods = JSStackTrace::ReadAllMethodInfos(pf);
EXPECT_TRUE(methods.size() > 0);
pf = nullptr;
methods = JSStackTrace::ReadAllMethodInfos(pf);
EXPECT_TRUE(methods.size() == 0);
}
* @tc.name: TranslateByteCodePc
* @tc.desc: Check whether the result returned through "TranslateByteCodePc" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestTranslateByteCodePc)
{
CVector<MethodInfo> vec = {
{0, 0, 24},
{1, 24, 30},
{2, 54, 56},
{3, 110, 60}
};
uintptr_t realPc = 115;
auto ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
EXPECT_TRUE(ret != std::nullopt);
vec.clear();
ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
EXPECT_TRUE(ret == std::nullopt);
vec.push_back({2, 54, 56});
ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
EXPECT_TRUE(ret == std::nullopt);
}
* @tc.name: ParseJsFrameInfo
* @tc.desc: Check whether the result returned through "ParseJsFrameInfo" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestParseJsFrameInfo)
{
const char *filename = "__JsStackInfoTest.pa";
const char *data = R"(
.function void foo() {
return
}
)";
pandasm::Parser parser;
auto res = parser.Parse(data);
auto file = pandasm::AsmEmitter::Emit(res.Value());
auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
EXPECT_TRUE(jsPandaFile != nullptr);
auto debugExtractor = std::make_unique<DebugInfoExtractor>(jsPandaFile.get());
auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
uintptr_t offset = 0;
JsFunction jsFunction;
ParseJsFrameInfo(jsPandaFile.get(), debugExtractor.get(), EntityId(methods[0].methodId), offset, jsFunction);
EXPECT_TRUE(std::string(jsFunction.functionName) == "foo");
EXPECT_TRUE(JsStackInfo::nameMap.empty());
}
* @tc.name: ArkParseJsFrameInfo
* @tc.desc: Check whether the result returned through "ArkCreateJSSymbolExtractor" function is within expectations;
* Check whether the result returned through "ArkParseJsFrameInfo" function is within expectations;
* Check whether the result returned through "ArkDestroyJSSymbolExtractor" function is within expectations.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestArkParseJsFrameInfo)
{
const char *filename1 = "__JsStackInfoTest1.pa";
const char *filename2 = "__JsStackInfoTest2.pa";
const char *pfdata1 = R"(
.function void foo() {
return
}
)";
const char *pfdata2 = R"(
.language ECMAScript
.function any func_main_0(any a0, any a1, any a2) {
ldai 1
return
}
)";
pandasm::Parser parser1;
pandasm::Parser parser2;
auto res1 = parser1.Parse(pfdata1);
auto res2 = parser2.Parse(pfdata2);
auto file1 = pandasm::AsmEmitter::Emit(res1.Value());
auto file2 = pandasm::AsmEmitter::Emit(res2.Value());
auto jsPandaFile1 = std::make_shared<JSPandaFile>(file1.release(), CString(filename1), CreateMode::DFX);
auto jsPandaFile2 = std::make_shared<JSPandaFile>(file2.release(), CString(filename2), CreateMode::DFX);
EXPECT_TRUE(jsPandaFile1 != nullptr);
EXPECT_TRUE(jsPandaFile2 != nullptr);
auto debugExtractor1 = std::make_unique<DebugInfoExtractor>(jsPandaFile1.get());
auto debugExtractor2 = std::make_unique<DebugInfoExtractor>(jsPandaFile2.get());
auto methods1 = JSStackTrace::ReadAllMethodInfos(jsPandaFile1);
auto methods2 = JSStackTrace::ReadAllMethodInfos(jsPandaFile2);
uintptr_t byteCodePc1 = methods1[0].codeBegin;
uintptr_t byteCodePc2 = methods2[0].codeBegin;
uintptr_t mapBase1 = reinterpret_cast<uintptr_t>(jsPandaFile1->GetHeader());
uintptr_t mapBase2 = reinterpret_cast<uintptr_t>(jsPandaFile2->GetHeader());
uintptr_t loadOffset1 = 0;
uintptr_t loadOffset2 = 0;
const uint8_t* data1 = jsPandaFile1->GetPandaFile()->GetBase();
const uint8_t* data2 = jsPandaFile2->GetPandaFile()->GetBase();
uint64_t dataSize1 = jsPandaFile1->GetFileSize();
uint64_t dataSize2 = jsPandaFile2->GetFileSize();
uintptr_t extractorptr1 = 0;
uintptr_t extractorptr2 = 0;
JsFunction jsFunction1;
JsFunction jsFunction2;
auto ret = ark_create_js_symbol_extractor(&extractorptr1);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(extractorptr1 != 0);
ret = ark_create_js_symbol_extractor(&extractorptr2);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(extractorptr2 != 0);
ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
reinterpret_cast<uint8_t *>(const_cast<char*>(pfdata1)),
strlen(pfdata1) + 1, extractorptr1, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
const_cast<uint8_t*>(data1), dataSize1, extractorptr1, &jsFunction1);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(std::string(jsFunction1.functionName) == "foo");
ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
const_cast<uint8_t*>(data1), dataSize1 + 1, 0, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
nullptr, 0, extractorptr1, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc2, mapBase1, loadOffset1,
const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc2, mapBase1, loadOffset1,
const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
EXPECT_TRUE(ret == -1);
ret = ark_parse_js_frame_info(byteCodePc2, mapBase2, loadOffset2,
const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction2);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(std::string(jsFunction2.functionName) == "func_main_0");
ret = ark_destory_js_symbol_extractor(extractorptr1);
EXPECT_TRUE(ret == 1);
ret = ark_destory_js_symbol_extractor(extractorptr2);
EXPECT_TRUE(!JsStackInfo::nameMap.empty());
EXPECT_TRUE(ret == 1);
}
* @tc.name: ark_destroy_local
* @tc.desc: Check whether the result returned through "ark_destroy_local" function is within expectations;
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F_L0(JsStackInfoTest, TestArkDestroyLocal)
{
auto ret = ark_destroy_local();
EXPECT_TRUE(ret);
ret = ark_create_local();
ret = ark_create_local();
EXPECT_TRUE(ret);
auto trace = JSStackTrace::GetInstance();
EXPECT_TRUE(trace != nullptr);
ret = ark_destroy_local();
trace = JSStackTrace::GetInstance();
EXPECT_TRUE(trace != nullptr);
ret = ark_destroy_local();
trace = JSStackTrace::GetInstance();
EXPECT_TRUE(trace == nullptr);
EXPECT_TRUE(ret);
ret = ark_destroy_local();
EXPECT_TRUE(ret);
ret = ark_create_local();
trace = JSStackTrace::GetInstance();
EXPECT_TRUE(trace != nullptr);
ret = ark_destroy_local();
EXPECT_TRUE(ret);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk__001)
{
void *ctx = nullptr;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
uintptr_t frame[10][3];
uintptr_t fp[10];
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
for (int i = 0; i < 10; i++) {
frame[i][0] = 0;
frame[i][1] = 0;
}
fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8;
for (int i = 1; i < 10; i++) {
fp[i] = fp[i-1] + 24;
}
ArkStepParam arkStepParam{ &fp[0], &sp, &pc, &isJsFrame, &frameType, frameIndex };
frame[0][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME);
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[1][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_FAST_NEW_FRAME);
arkStepParam.fp = &fp[1];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[2][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME);
arkStepParam.fp = &fp[2];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[3][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_ENTRY_FRAME);
arkStepParam.fp = &fp[3];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[4][2] = static_cast<uintptr_t>(FrameType::BUILTIN_ENTRY_FRAME);
arkStepParam.fp = &fp[4];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[5][2] = static_cast<uintptr_t>(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME);
arkStepParam.fp = &fp[5];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[6][2] = static_cast<uintptr_t>(FrameType::BASELINE_BUILTIN_FRAME);
arkStepParam.fp = &fp[6];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[7][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME);
arkStepParam.fp = &fp[7];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[8][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME);
arkStepParam.fp = &fp[8];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[9][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME_WITH_ARGV);
arkStepParam.fp = &fp[9];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk__002)
{
void *ctx = nullptr;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
uintptr_t frame[30][3];
uintptr_t fp[30];
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
for (int i = 0; i < 30; i++) {
frame[i][0] = 0;
frame[i][1] = 0;
}
fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8;
for (int i = 1; i < 30; i++) {
fp[i] = fp[i-1] + 24;
}
ArkStepParam arkStepParam{ &fp[0], &sp, &pc, &isJsFrame, &frameType, frameIndex };
frame[0][2] = static_cast<uintptr_t>(FrameType::BUILTIN_CALL_LEAVE_FRAME);
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[1][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_FRAME);
arkStepParam.fp = &fp[1];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[2][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_BRIDGE_FRAME);
arkStepParam.fp = &fp[2];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[3][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME);
arkStepParam.fp = &fp[3];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[4][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME);
arkStepParam.fp = &fp[4];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[5][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_ENTRY_FRAME);
arkStepParam.fp = &fp[5];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[6][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME);
arkStepParam.fp = &fp[6];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[7][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME);
arkStepParam.fp = &fp[7];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[8][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
arkStepParam.fp = &fp[8];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
frame[9][2] = 100;
arkStepParam.fp = &fp[9];
ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
}
HWTEST_F_L0(JsStackInfoTest, TestLocalParseJsFrameInfo__001)
{
const char *filename = "__JsStackInfoTest1.pa";
const char *pfdata = R"(
.function void foo() {
return
}
)";
auto pfManager = JSPandaFileManager::GetInstance();
pandasm::Parser parser1;
auto res = parser1.Parse(pfdata);
auto file = pandasm::AsmEmitter::Emit(res.Value());
auto jsPandaFile = pfManager->NewJSPandaFile(file.release(), CString(filename));
pfManager->AddJSPandaFile(jsPandaFile);
EXPECT_TRUE(jsPandaFile != nullptr);
auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
uintptr_t byteCodePc = methods[0].codeBegin;
uintptr_t mapBase = reinterpret_cast<uintptr_t>(jsPandaFile->GetHeader());
uintptr_t loadOffset = 0;
JsFunction jsFunction;
auto ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
EXPECT_TRUE(ret == -1);
ark_create_local();
ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
EXPECT_TRUE(ret == 1);
ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(JsStackInfo::nameMap.empty());
ark_destroy_local();
pfManager->RemoveJSPandaFile(jsPandaFile.get());
}
HWTEST_F_L0(JsStackInfoTest, TestLocalParseJsFrameInfo__002)
{
const char *filename = "__JsStackInfoTest1.pa";
const char *pfdata = R"(
.function void foo() {
return
}
)";
auto pfManager = JSPandaFileManager::GetInstance();
pandasm::Parser parser1;
auto res = parser1.Parse(pfdata);
auto file = pandasm::AsmEmitter::Emit(res.Value());
auto jsPandaFile = pfManager->NewJSPandaFile(file.release(), CString(filename));
EXPECT_TRUE(jsPandaFile != nullptr);
auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
uintptr_t byteCodePc = methods[0].codeBegin;
uintptr_t mapBase = reinterpret_cast<uintptr_t>(jsPandaFile->GetHeader());
uintptr_t loadOffset = 0;
JsFunction jsFunction;
ark_create_local();
auto ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
ark_destroy_local();
EXPECT_TRUE(ret == -1);
}
#if defined(PANDA_TARGET_ARM64)
HWTEST_F_L0(JsStackInfoTest, TestFrameType_001)
{
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_ENTRY_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_ENTRY_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::FASTJIT_FUNCTION_FRAME) ==
ToUintPtr(FrameType::FASTJIT_FUNCTION_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::FASTJIT_FAST_CALL_FUNCTION_FRAME) ==
ToUintPtr(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_BRIDGE_FRAME) ==
ToUintPtr(FrameType::ASM_BRIDGE_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::LEAVE_FRAME) ==
ToUintPtr(FrameType::LEAVE_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::LEAVE_FRAME_WITH_ARGV) ==
ToUintPtr(FrameType::LEAVE_FRAME_WITH_ARGV));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_CALL_LEAVE_FRAME) ==
ToUintPtr(FrameType::BUILTIN_CALL_LEAVE_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_FRAME) ==
ToUintPtr(FrameType::INTERPRETER_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_FRAME) ==
ToUintPtr(FrameType::ASM_INTERPRETER_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_CONSTRUCTOR_FRAME) ==
ToUintPtr(FrameType::INTERPRETER_CONSTRUCTOR_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME) ==
ToUintPtr(FrameType::BUILTIN_FRAME));
}
HWTEST_F_L0(JsStackInfoTest, TestFrameType_002)
{
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME_WITH_ARGV) ==
ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_ENTRY_FRAME) ==
ToUintPtr(FrameType::BUILTIN_ENTRY_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_BUILTIN_FRAME) ==
ToUintPtr(FrameType::INTERPRETER_BUILTIN_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_FAST_NEW_FRAME) ==
ToUintPtr(FrameType::INTERPRETER_FAST_NEW_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_ENTRY_FRAME) ==
ToUintPtr(FrameType::INTERPRETER_ENTRY_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_ENTRY_FRAME) ==
ToUintPtr(FrameType::ASM_INTERPRETER_ENTRY_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_BRIDGE_FRAME) ==
ToUintPtr(FrameType::ASM_INTERPRETER_BRIDGE_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME) ==
ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME) ==
ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME));
EXPECT_TRUE(ToUintPtr(arkts_frame_type::BASELINE_BUILTIN_FRAME) ==
ToUintPtr(FrameType::BASELINE_BUILTIN_FRAME));
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_001)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, 0 };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_002)
{
size_t size = 4;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(0);
frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME);
frame[2] = static_cast<JSTaggedType>(62480);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[2]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[2]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_003)
{
size_t size = 4;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
frame[2] = static_cast<JSTaggedType>(62480);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[2]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[2]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_004)
{
size_t size = 4;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME);
frame[2] = static_cast<JSTaggedType>(62480);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[2]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[2]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_005)
{
size_t size1 = 4;
JSTaggedType frame1[size1];
frame1[0] = static_cast<JSTaggedType>(0);
frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME);
frame1[2] = static_cast<JSTaggedType>(62480);
frame1[3] = static_cast<JSTaggedType>(123456);
size_t size2 = 5;
JSTaggedType frame2[size2];
frame2[0] = static_cast<JSTaggedType>(1234);
frame2[1] = JSTaggedValue::Hole().GetRawData();
frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FUNCTION_FRAME);
frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[1]) + 8);
frame2[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame1[2]);
EXPECT_TRUE(pre_frame.pc == frame1[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame1[2]);
EXPECT_TRUE(*arkStepParam.pc == frame1[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_006)
{
size_t size1 = 4;
JSTaggedType frame1[size1];
frame1[0] = static_cast<JSTaggedType>(0);
frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME);
frame1[2] = static_cast<JSTaggedType>(62480);
frame1[3] = static_cast<JSTaggedType>(123456);
size_t size2 = 5;
JSTaggedType frame2[size2];
frame2[0] = static_cast<JSTaggedType>(1234);
frame2[1] = JSTaggedValue::Hole().GetRawData();
frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME);
frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[1]) + 8);
frame2[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame1[2]);
EXPECT_TRUE(pre_frame.pc == frame1[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame1[2]);
EXPECT_TRUE(*arkStepParam.pc == frame1[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_007)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::ASM_BRIDGE_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_008)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::LEAVE_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
frame[3] = static_cast<JSTaggedType>(0);
frame[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_009)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::LEAVE_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
frame[3] = static_cast<JSTaggedType>(0);
frame[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_010)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(0);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_011)
{
size_t size = 9;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = JSTaggedValue::Hole().GetRawData();
frame[2] = JSTaggedValue::Hole().GetRawData();
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = JSTaggedValue::Hole().GetRawData();
frame[5] = JSTaggedValue::Hole().GetRawData();
frame[6] = static_cast<JSTaggedType>(123456);
frame[7] = static_cast<JSTaggedType>(62480);
frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[7]);
EXPECT_TRUE(pre_frame.pc == frame[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[7]);
EXPECT_TRUE(*arkStepParam.pc == frame[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_012)
{
size_t size = 9;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = JSTaggedValue::Hole().GetRawData();
frame[2] = JSTaggedValue::Hole().GetRawData();
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = JSTaggedValue::Hole().GetRawData();
frame[5] = JSTaggedValue::Hole().GetRawData();
frame[6] = static_cast<JSTaggedType>(123456);
frame[7] = static_cast<JSTaggedType>(62480);
frame[8] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[7]);
EXPECT_TRUE(pre_frame.pc == frame[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[7]);
EXPECT_TRUE(*arkStepParam.pc == frame[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_013)
{
size_t size = 9;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = JSTaggedValue::Hole().GetRawData();
frame[2] = JSTaggedValue::Hole().GetRawData();
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = JSTaggedValue::Hole().GetRawData();
frame[5] = JSTaggedValue::Hole().GetRawData();
frame[6] = static_cast<JSTaggedType>(123456);
frame[7] = static_cast<JSTaggedType>(62480);
frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[7]);
EXPECT_TRUE(pre_frame.pc == frame[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[7]);
EXPECT_TRUE(*arkStepParam.pc == frame[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_014)
{
size_t size = 6;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = JSTaggedValue::Hole().GetRawData();
frame[5] = JSTaggedValue::Hole().GetRawData();
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_015)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME_WITH_ARGV);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_016)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_ENTRY_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_017)
{
size_t size1 = 9;
JSTaggedType frame1[size1];
frame1[0] = JSTaggedValue::Hole().GetRawData();
frame1[1] = JSTaggedValue::Hole().GetRawData();
frame1[2] = JSTaggedValue::Hole().GetRawData();
frame1[3] = JSTaggedValue::Hole().GetRawData();
frame1[4] = JSTaggedValue::Hole().GetRawData();
frame1[5] = JSTaggedValue::Hole().GetRawData();
frame1[6] = static_cast<JSTaggedType>(123456);
frame1[7] = static_cast<JSTaggedType>(62480);
frame1[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME);
size_t size2 = 4;
JSTaggedType frame2[size2];
frame2[0] = JSTaggedValue::Hole().GetRawData();
frame2[1] = static_cast<JSTaggedType>(0);
frame2[2] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[8]) + 8);
frame2[3] = static_cast<JSTaggedType>(FrameType::INTERPRETER_BUILTIN_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[3]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame1[7]);
EXPECT_TRUE(pre_frame.pc == frame1[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame1[7]);
EXPECT_TRUE(*arkStepParam.pc == frame1[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_018)
{
size_t size1 = 9;
JSTaggedType frame[size1];
frame[0] = JSTaggedValue::Hole().GetRawData();
frame[1] = JSTaggedValue::Hole().GetRawData();
frame[2] = JSTaggedValue::Hole().GetRawData();
frame[3] = JSTaggedValue::Hole().GetRawData();
frame[4] = JSTaggedValue::Hole().GetRawData();
frame[5] = JSTaggedValue::Hole().GetRawData();
frame[6] = static_cast<JSTaggedType>(123456);
frame[7] = static_cast<JSTaggedType>(62480);
frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FAST_NEW_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[7]);
EXPECT_TRUE(pre_frame.pc == frame[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[7]);
EXPECT_TRUE(*arkStepParam.pc == frame[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_019)
{
size_t size1 = 9;
JSTaggedType frame1[size1];
frame1[0] = JSTaggedValue::Hole().GetRawData();
frame1[1] = JSTaggedValue::Hole().GetRawData();
frame1[2] = JSTaggedValue::Hole().GetRawData();
frame1[3] = JSTaggedValue::Hole().GetRawData();
frame1[4] = JSTaggedValue::Hole().GetRawData();
frame1[5] = JSTaggedValue::Hole().GetRawData();
frame1[6] = static_cast<JSTaggedType>(123456);
frame1[7] = static_cast<JSTaggedType>(62480);
frame1[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME);
size_t size2 = 3;
JSTaggedType frame2[size2];
frame2[0] = static_cast<JSTaggedType>(0);
frame2[1] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[8]) + 8);
frame2[2] = static_cast<JSTaggedType>(FrameType::INTERPRETER_BUILTIN_FRAME);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame1[7]);
EXPECT_TRUE(pre_frame.pc == frame1[6]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame1[7]);
EXPECT_TRUE(*arkStepParam.pc == frame1[6]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_020)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(0);
frame[1] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame[8]) + 8);
frame[2] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_ENTRY_FRAME);
frame[3] = static_cast<JSTaggedType>(62480);
frame[4] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[3]);
EXPECT_TRUE(pre_frame.pc == frame[4]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[3]);
EXPECT_TRUE(*arkStepParam.pc == frame[4]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_021)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(0);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_BRIDGE_FRAME);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_022)
{
size_t size = 4;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Undefined().GetRawData();
frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME);
frame[2] = static_cast<JSTaggedType>(62480);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[2]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[2]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_023)
{
size_t size = 4;
JSTaggedType frame[size];
frame[0] = JSTaggedValue::Undefined().GetRawData();
frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME);
frame[2] = static_cast<JSTaggedType>(62480);
frame[3] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[2]);
EXPECT_TRUE(pre_frame.pc == frame[3]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[2]);
EXPECT_TRUE(*arkStepParam.pc == frame[3]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_024)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_025)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BASELINE_BUILTIN_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == frame[1]);
EXPECT_TRUE(pre_frame.pc == frame[2]);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(*arkStepParam.fp == frame[1]);
EXPECT_TRUE(*arkStepParam.pc == frame[2]);
EXPECT_TRUE(ret == 1);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_026)
{
size_t size = 1;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::BASELINE_BUILTIN_FRAME) + 1;
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
uintptr_t sp = 0;
uintptr_t pc = 0;
bool isJsFrame = true;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = -1;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame, &frameType, frameIndex };
int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
EXPECT_TRUE(ret == -1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArk_027)
{
unsigned int type = static_cast<unsigned int>(arkts_frame_type::FRAME_TYPE_MAX) + 1;
bool ret = is_entry_frame(type);
EXPECT_TRUE(ret == false);
ret = is_js_function_frame(type);
EXPECT_TRUE(ret == false);
ret = is_native_function_frame(type);
EXPECT_TRUE(ret == false);
}
HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_001)
{
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
unwind_stack_frame_s cur_frame = UNWIND_FRAME_EMPTY;
auto pre_frame = unwind_arkts(nullptr, &cur_frame);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
pre_frame = unwind_arkts(ctx, nullptr);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_002)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = 0;
unwind_stack_frame_s cur_frame = { fp, 0 };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_003)
{
size_t size = 3;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME);
frame[1] = static_cast<JSTaggedType>(62480);
frame[2] = static_cast<JSTaggedType>(123456);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = 1;
unwind_stack_frame_s cur_frame = { fp, 0 };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_004)
{
size_t size = 5;
JSTaggedType frame[size];
frame[0] = static_cast<JSTaggedType>(1234);
frame[1] = JSTaggedValue::Hole().GetRawData();
frame[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FUNCTION_FRAME);
frame[3] = static_cast<JSTaggedType>(62480);
frame[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8;
uintptr_t pc = 0;
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = 2;
unwind_stack_frame_s cur_frame = { fp, pc };
auto pre_frame = unwind_arkts(ctx, &cur_frame);
EXPECT_TRUE(pre_frame.fp == 0);
EXPECT_TRUE(pre_frame.pc == 0);
}
HWTEST_F_L0(JsStackInfoTest, TestNextArkFrame)
{
unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
ctx->count = 0;
uintptr_t fp = 0;
unsigned int type = 0;
unwind_stack_frame_s frame = UNWIND_FRAME_EMPTY;
bool retFrameAvail = false;
int ret = next_ark_frame(ctx, fp, type, &frame, &retFrameAvail);
EXPECT_TRUE(ret == -1);
free(ctx);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArkWithRecordJit_001)
{
size_t size1 = 4;
JSTaggedType frame1[size1];
frame1[0] = static_cast<JSTaggedType>(0);
frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME);
frame1[2] = static_cast<JSTaggedType>(62480);
frame1[3] = static_cast<JSTaggedType>(123456);
size_t size2 = 5;
JSTaggedType frame2[size2];
frame2[0] = static_cast<JSTaggedType>(1234);
frame2[1] = JSTaggedValue::Hole().GetRawData();
frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FUNCTION_FRAME);
frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[2]));
frame2[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8;
SafeMemContext safeCtx;
safeCtx.AddRange(reinterpret_cast<uintptr_t>(&frame1[0]), reinterpret_cast<uintptr_t>(&frame1[size1]));
safeCtx.AddRange(reinterpret_cast<uintptr_t>(&frame2[0]), reinterpret_cast<uintptr_t>(&frame2[size2]));
uintptr_t sp = 0;
uintptr_t pc = 0;
uintptr_t methodId = 0;
bool isJsFrame = true;
std::vector<uintptr_t> jitCache;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
ArkUnwindParam arkUnwindParam(&safeCtx, SafeReadMemFuncForJit, &fp, &sp, &pc,
&methodId, &isJsFrame, &frameType, frameIndex, jitCache);
int ret = step_ark_with_record_jit(&arkUnwindParam);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(*arkUnwindParam.fp == reinterpret_cast<uintptr_t>(&frame1[2]));
EXPECT_TRUE(*arkUnwindParam.pc == 1234);
EXPECT_TRUE(*arkUnwindParam.isJsFrame == true);
}
HWTEST_F_L0(JsStackInfoTest, TestStepArkWithRecordJit_002)
{
size_t size1 = 4;
JSTaggedType frame1[size1];
frame1[0] = static_cast<JSTaggedType>(0);
frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME);
frame1[2] = static_cast<JSTaggedType>(62480);
frame1[3] = static_cast<JSTaggedType>(123456);
size_t size2 = 5;
JSTaggedType frame2[size2];
frame2[0] = static_cast<JSTaggedType>(5678);
frame2[1] = JSTaggedValue::Hole().GetRawData();
frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME);
frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[2]));
frame2[4] = static_cast<JSTaggedType>(0);
uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8;
SafeMemContext safeCtx;
safeCtx.AddRange(reinterpret_cast<uintptr_t>(&frame1[0]), reinterpret_cast<uintptr_t>(&frame1[size1]));
safeCtx.AddRange(reinterpret_cast<uintptr_t>(&frame2[0]), reinterpret_cast<uintptr_t>(&frame2[size2]));
uintptr_t sp = 0;
uintptr_t pc = 0;
uintptr_t methodId = 0;
bool isJsFrame = true;
std::vector<uintptr_t> jitCache;
StepFrameType frameType = StepFrameType::JS_FRAME;
uint64_t frameIndex = 0;
ArkUnwindParam arkUnwindParam(&safeCtx, SafeReadMemFuncForJit, &fp, &sp, &pc,
&methodId, &isJsFrame, &frameType, frameIndex, jitCache);
int ret = step_ark_with_record_jit(&arkUnwindParam);
EXPECT_TRUE(ret == 1);
EXPECT_TRUE(*arkUnwindParam.fp == reinterpret_cast<uintptr_t>(&frame1[2]));
EXPECT_TRUE(*arkUnwindParam.pc == 5678);
EXPECT_TRUE(*arkUnwindParam.isJsFrame == true);
}
#endif
HWTEST_F_L0(JsStackInfoTest, MatchLineAndRevisedOffset) {
const std::string fileName = STACKINFO_TEST_ABC_FILES_DIR"index.abc";
std::string entryPoint = "index";
bool result = JSNApi::Execute(instance_, fileName, entryPoint);
ASSERT_TRUE(result);
auto jsPandaFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(CString(fileName));
EXPECT_NE(jsPandaFile, nullptr);
auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
DebugInfoExtractor *debugExtractor = JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile.get());
int32_t lineNumber = 0;
auto callbackLineFunc = [&lineNumber](int32_t line) -> bool {
lineNumber = line + 1;
return true;
};
auto method = methods[0];
uintptr_t offset = 54;
debugExtractor->MatchLineWithOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 0);
debugExtractor->MatchLineAndRevisedOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 20);
EXPECT_TRUE(offset == 55);
lineNumber = 0;
offset = 55;
debugExtractor->MatchLineWithOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 20);
lineNumber = 0;
debugExtractor->MatchLineAndRevisedOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 20);
offset = 20;
debugExtractor->MatchLineWithOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 17);
debugExtractor->MatchLineAndRevisedOffset(callbackLineFunc, EntityId(method.methodId), offset);
EXPECT_TRUE(lineNumber == 17);
}
HWTEST_F_L0(JsStackInfoTest, TestBuildJsStackInfo1)
{
auto jsFrame = JsStackInfo::BuildJsStackInfo(thread_);
EXPECT_TRUE(jsFrame.empty());
}
HWTEST_F_L0(JsStackInfoTest, TestBuildJsStackInfo2)
{
JSHandle<JSObject> jsErrorObj;
std::string stack1 = JsStackInfo::BuildJsStackTrace(thread_, false, jsErrorObj, true);
#if defined(ENABLE_EXCEPTION_BACKTRACE)
EXPECT_TRUE(!stack1.empty());
#else
EXPECT_TRUE(stack1.empty());
#endif
std::string stack2 = JsStackInfo::BuildJsStackTrace(thread_, false, jsErrorObj, false);
EXPECT_TRUE(stack2.empty());
}
HWTEST_F_L0(JsStackInfoTest, TestBuildJsStackInfo3)
{
thread_->SetCrossThreadExecution(true);
JSHandle<JSObject> jsErrorObj;
std::string stack1 = JsStackInfo::BuildJsStackTrace(thread_, false, jsErrorObj, true);
EXPECT_TRUE(stack1.empty());
thread_->SetCrossThreadExecution(false);
}
HWTEST_F_L0(JsStackInfoTest, TestArkWriteJitCode)
{
std::vector<uint8_t> codeVec1 = {0x01, 0x02, 0x03, 0x04};
std::vector<uint8_t> codeVec2 = {0x05, 0x06, 0x07, 0x08};
EntityId id1(100);
EntityId id2(200);
JsStackInfo::machineCodeMap[id1] = codeVec1;
JsStackInfo::machineCodeMap[id2] = codeVec2;
JsStackInfo::nameMap[id1] = "jitFunction1";
JsStackInfo::nameMap[id2] = "jitFunction2";
uintptr_t jitCodeArray[2] = {100, 200};
char tempFile[] = "/tmp/test_ark_write_jit_code_XXXXXX";
int fd = mkstemp(tempFile);
if (fd < 0) {
GTEST_LOG_(INFO) << "Cannot create temp file, skip this test";
return;
}
int result = ark_write_jit_code(nullptr, ReadMemFunc, fd, jitCodeArray, 2);
EXPECT_EQ(result, 1);
close(fd);
unlink(tempFile);
JsStackInfo::machineCodeMap.clear();
JsStackInfo::nameMap.clear();
}
}