148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
448f512ceSopenharmony_ci * you may not use this file except in compliance with the License.
548f512ceSopenharmony_ci * You may obtain a copy of the License at
648f512ceSopenharmony_ci *
748f512ceSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
848f512ceSopenharmony_ci *
948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and
1348f512ceSopenharmony_ci * limitations under the License.
1448f512ceSopenharmony_ci */
1548f512ceSopenharmony_ci#ifndef HIPERF_CALLSTACK_TEST_H
1648f512ceSopenharmony_ci#define HIPERF_CALLSTACK_TEST_H
1748f512ceSopenharmony_ci
1848f512ceSopenharmony_ci#include <gmock/gmock.h>
1948f512ceSopenharmony_ci#include <gtest/gtest.h>
2048f512ceSopenharmony_ci#include <iterator>
2148f512ceSopenharmony_ci#include <link.h>
2248f512ceSopenharmony_ci#include <random>
2348f512ceSopenharmony_ci#include <sys/mman.h>
2448f512ceSopenharmony_ci
2548f512ceSopenharmony_ci#include <hilog/log.h>
2648f512ceSopenharmony_ci
2748f512ceSopenharmony_ci#include "callstack.h"
2848f512ceSopenharmony_ci#include "debug_logger.h"
2948f512ceSopenharmony_ci#include "utilities.h"
3048f512ceSopenharmony_ci
3148f512ceSopenharmony_cinamespace OHOS {
3248f512ceSopenharmony_cinamespace Developtools {
3348f512ceSopenharmony_cinamespace HiPerf {
3448f512ceSopenharmony_ciconst std::string PATH_RESOURCE_TEST_DWARF_DATA = "resource/testdata/dwarf/";
3548f512ceSopenharmony_cistruct mmapDumpInfo {
3648f512ceSopenharmony_ci    std::string fileName;
3748f512ceSopenharmony_ci    uint64_t begin = 0;
3848f512ceSopenharmony_ci    uint64_t len = 0;
3948f512ceSopenharmony_ci    uint64_t pgoff = 0;
4048f512ceSopenharmony_ci};
4148f512ceSopenharmony_ci
4248f512ceSopenharmony_cistruct frame {
4348f512ceSopenharmony_ci    uint64_t ip = 0;
4448f512ceSopenharmony_ci    uint64_t sp = 0;
4548f512ceSopenharmony_ci};
4648f512ceSopenharmony_ci/*
4748f512ceSopenharmony_ci    create from
4848f512ceSopenharmony_ci    ./hiperf_example_cmd --thread 1 --time 60 --stack 10
4948f512ceSopenharmony_ci    ./hiperf_host dump --userdata > dump.txt
5048f512ceSopenharmony_ci*/
5148f512ceSopenharmony_ci#ifdef __arm__
5248f512ceSopenharmony_cistatic const std::string TEST_DWARF_ELF = "hiperf_example_cmd";
5348f512ceSopenharmony_ci/*
5448f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 107
5548f512ceSopenharmony_ci  pid 643, tid 643, addr 0x454000, len 0x3000
5648f512ceSopenharmony_ci  pgoff 0x0, maj 179, min 7, ino 4868, ino_generation 6874019636378171493
5748f512ceSopenharmony_ci  prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd
5848f512ceSopenharmony_ci
5948f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 107
6048f512ceSopenharmony_ci  pid 643, tid 643, addr 0x457000, len 0x5000
6148f512ceSopenharmony_ci  pgoff 0x2000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
6248f512ceSopenharmony_ci  prot 5, flags 2, filename /data/local/tmp/hiperf_example_cmd
6348f512ceSopenharmony_ci
6448f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 107
6548f512ceSopenharmony_ci  pid 643, tid 643, addr 0x45c000, len 0x1000
6648f512ceSopenharmony_ci  pgoff 0x6000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
6748f512ceSopenharmony_ci  prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd
6848f512ceSopenharmony_ci
6948f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 107
7048f512ceSopenharmony_ci  pid 643, tid 643, addr 0x45d000, len 0x1000
7148f512ceSopenharmony_ci  pgoff 0x6000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
7248f512ceSopenharmony_ci  prot 3, flags 2, filename /data/local/tmp/hiperf_example_cmd
7348f512ceSopenharmony_ci*/
7448f512ceSopenharmony_cistatic const std::vector<mmapDumpInfo> TEST_DWARF_MMAP = {
7548f512ceSopenharmony_ci    {"hiperf_example_cmd", 0x454000, 0x3000, 0x0},
7648f512ceSopenharmony_ci    {"hiperf_example_cmd", 0x457000, 0x5000, 0x2000},
7748f512ceSopenharmony_ci    {"hiperf_example_cmd", 0x45c000, 0x1000, 0x6000},
7848f512ceSopenharmony_ci    {"hiperf_example_cmd", 0x45d000, 0x1000, 0x6000},
7948f512ceSopenharmony_ci};
8048f512ceSopenharmony_cistatic const std::string TEST_DWARF_USER_REGS_0 = "user_regs.dump";
8148f512ceSopenharmony_cistatic const std::string TEST_DWARF_USER_DATA_0 = "user_data.dump";
8248f512ceSopenharmony_ci/*
8348f512ceSopenharmony_ciUnwindStep:unwind:0: ip 0x45765e sp 0xb6ca1c68
8448f512ceSopenharmony_ciUnwindStep:unwind:1: ip 0x45768a sp 0xb6ca1c78
8548f512ceSopenharmony_ciUnwindStep:unwind:2: ip 0x4576ce sp 0xb6ca1c88
8648f512ceSopenharmony_ciUnwindStep:unwind:3: ip 0x457712 sp 0xb6ca1c98
8748f512ceSopenharmony_ciUnwindStep:unwind:4: ip 0x457756 sp 0xb6ca1ca8
8848f512ceSopenharmony_ciUnwindStep:unwind:5: ip 0x45779a sp 0xb6ca1cb8
8948f512ceSopenharmony_ciUnwindStep:unwind:6: ip 0x4577de sp 0xb6ca1cc8
9048f512ceSopenharmony_ciUnwindStep:unwind:7: ip 0x457822 sp 0xb6ca1cd8
9148f512ceSopenharmony_ciUnwindStep:unwind:8: ip 0x457866 sp 0xb6ca1ce8
9248f512ceSopenharmony_ciUnwindStep:unwind:9: ip 0x4578aa sp 0xb6ca1cf8
9348f512ceSopenharmony_ciUnwindStep:unwind:10: ip 0x4578ee sp 0xb6ca1d08
9448f512ceSopenharmony_ciUnwindStep:unwind:11: ip 0x45793c sp 0xb6ca1d18
9548f512ceSopenharmony_ciUnwindStep:unwind:12: ip 0x457ffe sp 0xb6ca1d28
9648f512ceSopenharmony_ciUnwindStep:unwind:13: ip 0xb6f01f73 sp 0xb6ca1d38
9748f512ceSopenharmony_ci*/
9848f512ceSopenharmony_cistatic const std::vector<frame> TEST_DWARF_FRAMES = {
9948f512ceSopenharmony_ci    {0x4575bc, 0xb6ca1c18}, // base ip sp
10048f512ceSopenharmony_ci    {0x45765f, 0xb6ca1c68}, {0x45768b, 0xb6ca1c78},   {0x4576cf, 0xb6ca1c88},
10148f512ceSopenharmony_ci    {0x457713, 0xb6ca1c98}, {0x457757, 0xb6ca1ca8},   {0x45779b, 0xb6ca1cb8},
10248f512ceSopenharmony_ci    {0x4577df, 0xb6ca1cc8}, {0x457823, 0xb6ca1cd8},   {0x457867, 0xb6ca1ce8},
10348f512ceSopenharmony_ci    {0x4578ab, 0xb6ca1cf8}, {0x4578ef, 0xb6ca1d08},   {0x45793d, 0xb6ca1d18},
10448f512ceSopenharmony_ci    {0x457fff, 0xb6ca1d28},
10548f512ceSopenharmony_ci};
10648f512ceSopenharmony_ci#else
10748f512ceSopenharmony_cistatic const std::string TEST_DWARF_ELF = "hiperf_example_cmd_64";
10848f512ceSopenharmony_ci/*
10948f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 110
11048f512ceSopenharmony_ci  pid 24925, tid 24925, addr 0x5591ef4000, len 0x3000
11148f512ceSopenharmony_ci  pgoff 0x0, maj 179, min 11, ino 2495283, ino_generation 0
11248f512ceSopenharmony_ci  prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
11348f512ceSopenharmony_ci
11448f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 110
11548f512ceSopenharmony_ci  pid 24925, tid 24925, addr 0x5591ef7000, len 0x3000
11648f512ceSopenharmony_ci  pgoff 0x2000, maj 179, min 11, ino 2495283, ino_generation 0
11748f512ceSopenharmony_ci  prot 5, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
11848f512ceSopenharmony_ci
11948f512ceSopenharmony_cirecord mmap2: type 10, misc 2, size 110
12048f512ceSopenharmony_ci  pid 24925, tid 24925, addr 0x5591efa000, len 0x1000
12148f512ceSopenharmony_ci  pgoff 0x4000, maj 179, min 11, ino 2495283, ino_generation 0
12248f512ceSopenharmony_ci  prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
12348f512ceSopenharmony_ci*/
12448f512ceSopenharmony_cistatic const std::vector<mmapDumpInfo> TEST_DWARF_MMAP = {
12548f512ceSopenharmony_ci    {"hiperf_example_cmd_64", 0x5591ef4000, 0x3000, 0x0},
12648f512ceSopenharmony_ci    {"hiperf_example_cmd_64", 0x5591ef7000, 0x3000, 0x2000},
12748f512ceSopenharmony_ci    {"hiperf_example_cmd_64", 0x5591efa000, 0x1000, 0x4000},
12848f512ceSopenharmony_ci};
12948f512ceSopenharmony_cistatic const std::string TEST_DWARF_USER_REGS_0 = "user_regs_64.dump";
13048f512ceSopenharmony_cistatic const std::string TEST_DWARF_USER_DATA_0 = "user_data_64.dump";
13148f512ceSopenharmony_ci/*
13248f512ceSopenharmony_ciUnwindStep:unwind:0: ip 0x5591ef772c sp 0x7f9aec76f0
13348f512ceSopenharmony_ciUnwindStep:unwind:1: ip 0x5591ef78cc sp 0x7f9aec77b0
13448f512ceSopenharmony_ciUnwindStep:unwind:2: ip 0x5591ef7990 sp 0x7f9aec77e0
13548f512ceSopenharmony_ciUnwindStep:unwind:3: ip 0x5591ef7a50 sp 0x7f9aec7820
13648f512ceSopenharmony_ciUnwindStep:unwind:4: ip 0x5591ef7b10 sp 0x7f9aec7860
13748f512ceSopenharmony_ciUnwindStep:unwind:5: ip 0x5591ef7bd0 sp 0x7f9aec78a0
13848f512ceSopenharmony_ciUnwindStep:unwind:6: ip 0x5591ef7c90 sp 0x7f9aec78e0
13948f512ceSopenharmony_ciUnwindStep:unwind:7: ip 0x5591ef7d50 sp 0x7f9aec7920
14048f512ceSopenharmony_ciUnwindStep:unwind:8: ip 0x5591ef7e10 sp 0x7f9aec7960
14148f512ceSopenharmony_ciUnwindStep:unwind:9: ip 0x5591ef7ed0 sp 0x7f9aec79a0
14248f512ceSopenharmony_ciUnwindStep:unwind:10: ip 0x5591ef7f90 sp 0x7f9aec79e0
14348f512ceSopenharmony_ciUnwindStep:unwind:11: ip 0x5591ef8050 sp 0x7f9aec7a20
14448f512ceSopenharmony_ciUnwindStep:unwind:12: ip 0x5591ef80e8 sp 0x7f9aec7a60
14548f512ceSopenharmony_ciUnwindStep:unwind:13: ip 0x5591ef95dc sp 0x7f9aec7a80
14648f512ceSopenharmony_ciUnwindStep:unwind:14: ip 0x7f9b0fa59c sp 0x7f9aec7aa0
14748f512ceSopenharmony_ci*/
14848f512ceSopenharmony_cistatic const std::vector<frame> TEST_DWARF_FRAMES = {
14948f512ceSopenharmony_ci    {0x5591ef772c, 0x7f9aec76f0}, // base ip sp
15048f512ceSopenharmony_ci    {0x5591ef78cc, 0x7f9aec77b0}, {0x5591ef7990, 0x7f9aec77e0},   {0x5591ef7a50, 0x7f9aec7820},
15148f512ceSopenharmony_ci    {0x5591ef7b10, 0x7f9aec7860}, {0x5591ef7bd0, 0x7f9aec78a0},   {0x5591ef7c90, 0x7f9aec78e0},
15248f512ceSopenharmony_ci    {0x5591ef7d50, 0x7f9aec7920}, {0x5591ef7e10, 0x7f9aec7960},   {0x5591ef7ed0, 0x7f9aec79a0},
15348f512ceSopenharmony_ci    {0x5591ef7f90, 0x7f9aec79e0}, {0x5591ef8050, 0x7f9aec7a20},   {0x5591ef80e8, 0x7f9aec7a60},
15448f512ceSopenharmony_ci    {0x5591ef95dc, 0x7f9aec7a80},
15548f512ceSopenharmony_ci};
15648f512ceSopenharmony_ci#endif
15748f512ceSopenharmony_ci
15848f512ceSopenharmony_ci// data convert function
15948f512ceSopenharmony_citemplate<class T>
16048f512ceSopenharmony_civoid LoadFromFile(const std::string &fileName, std::vector<T> &data)
16148f512ceSopenharmony_ci{
16248f512ceSopenharmony_ci    FILE* fp_ = fopen(fileName.c_str(), "r");
16348f512ceSopenharmony_ci    if (fp_ == nullptr) {
16448f512ceSopenharmony_ci        return;
16548f512ceSopenharmony_ci    }
16648f512ceSopenharmony_ci    std::unique_ptr<FILE, decltype(&fclose)> fp(fp_, fclose);
16748f512ceSopenharmony_ci    if (fp) {
16848f512ceSopenharmony_ci        struct stat sb = {};
16948f512ceSopenharmony_ci        ASSERT_NE(fstat(fileno(fp.get()), &sb), -1);
17048f512ceSopenharmony_ci        ASSERT_NE(sb.st_size, 0);
17148f512ceSopenharmony_ci        ASSERT_EQ(sb.st_size % sizeof(T), 0u);
17248f512ceSopenharmony_ci        data.resize(sb.st_size / sizeof(T));
17348f512ceSopenharmony_ci        ASSERT_EQ(fread(data.data(), sizeof(T), data.size(), fp.get()), data.size());
17448f512ceSopenharmony_ci    }
17548f512ceSopenharmony_ci}
17648f512ceSopenharmony_ci
17748f512ceSopenharmony_cistatic void MakeMaps(VirtualThread &thread)
17848f512ceSopenharmony_ci{
17948f512ceSopenharmony_ci    for (const mmapDumpInfo &mmap : TEST_DWARF_MMAP) {
18048f512ceSopenharmony_ci        thread.CreateMapItem(mmap.fileName, mmap.begin, mmap.len, mmap.pgoff);
18148f512ceSopenharmony_ci    }
18248f512ceSopenharmony_ci}
18348f512ceSopenharmony_ci} // namespace HiPerf
18448f512ceSopenharmony_ci} // namespace Developtools
18548f512ceSopenharmony_ci} // namespace OHOS
18648f512ceSopenharmony_ci#endif // HIPERF_CALLSTACK_TEST_H
187