1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <gtest/gtest.h>
17
18#include <cstdio>
19#include <thread>
20#include <unistd.h>
21#include <malloc.h>
22#include <securec.h>
23#include "dfx_instr_statistic.h"
24#include "dfx_ptrace.h"
25#include "dfx_regs_get.h"
26#include "procinfo.h"
27#include "unwinder.h"
28
29using namespace testing;
30using namespace testing::ext;
31
32namespace OHOS {
33namespace HiviewDFX {
34#undef LOG_DOMAIN
35#undef LOG_TAG
36#define LOG_TAG "DfxInstrStatisticTest"
37#define LOG_DOMAIN 0xD002D11
38
39class InstrStatisticTest : public testing::Test {
40public:
41    static void SetUpTestCase() {}
42    static void TearDownTestCase() {}
43    void SetUp() {}
44    void TearDown() {}
45};
46
47/**
48 * @tc.name: InstrStatisticTest001
49 * @tc.desc: test InstrStatistic interface
50 * @tc.type: FUNC
51 */
52HWTEST_F(InstrStatisticTest, InstrStatisticTest001, TestSize.Level2)
53{
54    GTEST_LOG_(INFO) << "InstrStatisticTest001: start.";
55    static pid_t pid = getpid();
56    static std::string elfName;
57    ReadProcessName(pid, elfName);
58    pid_t child = fork();
59    if (child == 0) {
60        GTEST_LOG_(INFO) << "elfName: " << elfName;
61        DfxInstrStatistic::GetInstance().SetCurrentStatLib(elfName);
62        GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
63        auto unwinder = std::make_shared<Unwinder>(pid);
64        bool unwRet = DfxPtrace::Attach(pid);
65        EXPECT_EQ(true, unwRet) << "InstrStatisticTest001: Attach:" << unwRet;
66        auto regs = DfxRegs::CreateRemoteRegs(pid);
67        unwinder->SetRegs(regs);
68        auto maps = DfxMaps::Create(pid);
69        UnwindContext context;
70        context.pid = pid;
71        context.regs = regs;
72        context.maps = maps;
73        unwRet = unwinder->Unwind(&context);
74        EXPECT_EQ(true, unwRet) << "InstrStatisticTest001: Unwind:" << unwRet;
75        auto frames = unwinder->GetFrames();
76        ASSERT_GT(frames.size(), 1);
77        GTEST_LOG_(INFO) << "frames:\n" << Unwinder::GetFramesStr(frames);
78        DfxPtrace::Detach(pid);
79        std::vector<std::pair<uint32_t, uint32_t>> result;
80        DfxInstrStatistic::GetInstance().DumpInstrStatResult(result);
81        ASSERT_GT(result.size(), 0);
82        for (size_t i = 0; i < result.size(); ++i) {
83            GTEST_LOG_(INFO) << result[i].first << result[i].second;
84        }
85        _exit(0);
86    }
87
88    int status;
89    int ret = wait(&status);
90    ASSERT_EQ(status, 0);
91    GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
92    GTEST_LOG_(INFO) << "InstrStatisticTest001: end.";
93}
94} // namespace HiviewDFX
95} // namepsace OHOS