• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef HIPERF_CALLSTACK_TEST_H
16 #define HIPERF_CALLSTACK_TEST_H
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <iterator>
21 #include <link.h>
22 #include <random>
23 #include <sys/mman.h>
24 
25 #include <hilog/log.h>
26 
27 #include "callstack.h"
28 #include "debug_logger.h"
29 #include "utilities.h"
30 
31 namespace OHOS {
32 namespace Developtools {
33 namespace HiPerf {
34 static const std::string PATH_RESOURCE_TEST_DWARF_DATA = "resource/testdata/dwarf/";
35 struct mmapDumpInfo {
36     std::string fileName;
37     uint64_t begin = 0;
38     uint64_t len = 0;
39     uint64_t pgoff = 0;
40 };
41 
42 struct frame {
43     uint64_t ip = 0;
44     uint64_t sp = 0;
45 };
46 /*
47     create from
48     ./hiperf_example_cmd --thread 1 --time 60 --stack 10
49     ./hiperf_host dump --userdata > dump.txt
50 */
51 #ifdef __arm__
52 static const std::string TEST_DWARF_ELF = "hiperf_example_cmd";
53 /*
54 record mmap2: type 10, misc 2, size 107
55   pid 643, tid 643, addr 0x454000, len 0x3000
56   pgoff 0x0, maj 179, min 7, ino 4868, ino_generation 6874019636378171493
57   prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd
58 
59 record mmap2: type 10, misc 2, size 107
60   pid 643, tid 643, addr 0x457000, len 0x5000
61   pgoff 0x2000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
62   prot 5, flags 2, filename /data/local/tmp/hiperf_example_cmd
63 
64 record mmap2: type 10, misc 2, size 107
65   pid 643, tid 643, addr 0x45c000, len 0x1000
66   pgoff 0x6000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
67   prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd
68 
69 record mmap2: type 10, misc 2, size 107
70   pid 643, tid 643, addr 0x45d000, len 0x1000
71   pgoff 0x6000, maj 179, min 7, ino 4868, ino_generation 7237954708011182952
72   prot 3, flags 2, filename /data/local/tmp/hiperf_example_cmd
73 */
74 static const std::vector<mmapDumpInfo> TEST_DWARF_MMAP = {
75     {"hiperf_example_cmd", 0x454000, 0x3000, 0x0},
76     {"hiperf_example_cmd", 0x457000, 0x5000, 0x2000},
77     {"hiperf_example_cmd", 0x45c000, 0x1000, 0x6000},
78     {"hiperf_example_cmd", 0x45d000, 0x1000, 0x6000},
79 };
80 static const std::string TEST_DWARF_USER_REGS_0 = "user_regs.dump";
81 static const std::string TEST_DWARF_USER_DATA_0 = "user_data.dump";
82 /*
83 UnwindStep:unwind:0: ip 0x45765e sp 0xb6ca1c68
84 UnwindStep:unwind:1: ip 0x45768a sp 0xb6ca1c78
85 UnwindStep:unwind:2: ip 0x4576ce sp 0xb6ca1c88
86 UnwindStep:unwind:3: ip 0x457712 sp 0xb6ca1c98
87 UnwindStep:unwind:4: ip 0x457756 sp 0xb6ca1ca8
88 UnwindStep:unwind:5: ip 0x45779a sp 0xb6ca1cb8
89 UnwindStep:unwind:6: ip 0x4577de sp 0xb6ca1cc8
90 UnwindStep:unwind:7: ip 0x457822 sp 0xb6ca1cd8
91 UnwindStep:unwind:8: ip 0x457866 sp 0xb6ca1ce8
92 UnwindStep:unwind:9: ip 0x4578aa sp 0xb6ca1cf8
93 UnwindStep:unwind:10: ip 0x4578ee sp 0xb6ca1d08
94 UnwindStep:unwind:11: ip 0x45793c sp 0xb6ca1d18
95 UnwindStep:unwind:12: ip 0x457ffe sp 0xb6ca1d28
96 UnwindStep:unwind:13: ip 0xb6f01f73 sp 0xb6ca1d38
97 */
98 static const std::vector<frame> TEST_DWARF_FRAMES = {
99     {0x4575BC, 0xB6CA1C18}, // base ip sp
100     {0x45765e, 0xb6ca1c68}, {0x45768a, 0xb6ca1c78},   {0x4576ce, 0xb6ca1c88},
101     {0x457712, 0xb6ca1c98}, {0x457756, 0xb6ca1ca8},   {0x45779a, 0xb6ca1cb8},
102     {0x4577de, 0xb6ca1cc8}, {0x457822, 0xb6ca1cd8},   {0x457866, 0xb6ca1ce8},
103     {0x4578aa, 0xb6ca1cf8}, {0x4578ee, 0xb6ca1d08},   {0x45793c, 0xb6ca1d18},
104     {0x457ffe, 0xb6ca1d28}, {0xb6f01f73, 0xb6ca1d38},
105 };
106 #else
107 static const std::string TEST_DWARF_ELF = "hiperf_example_cmd_64";
108 /*
109 record mmap2: type 10, misc 2, size 110
110   pid 24925, tid 24925, addr 0x5591ef4000, len 0x3000
111   pgoff 0x0, maj 179, min 11, ino 2495283, ino_generation 0
112   prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
113 
114 record mmap2: type 10, misc 2, size 110
115   pid 24925, tid 24925, addr 0x5591ef7000, len 0x3000
116   pgoff 0x2000, maj 179, min 11, ino 2495283, ino_generation 0
117   prot 5, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
118 
119 record mmap2: type 10, misc 2, size 110
120   pid 24925, tid 24925, addr 0x5591efa000, len 0x1000
121   pgoff 0x4000, maj 179, min 11, ino 2495283, ino_generation 0
122   prot 1, flags 2, filename /data/local/tmp/hiperf_example_cmd_64
123 */
124 static const std::vector<mmapDumpInfo> TEST_DWARF_MMAP = {
125     {"hiperf_example_cmd_64", 0x5591ef4000, 0x3000, 0x0},
126     {"hiperf_example_cmd_64", 0x5591ef7000, 0x3000, 0x2000},
127     {"hiperf_example_cmd_64", 0x5591efa000, 0x1000, 0x4000},
128 };
129 static const std::string TEST_DWARF_USER_REGS_0 = "user_regs_64.dump";
130 static const std::string TEST_DWARF_USER_DATA_0 = "user_data_64.dump";
131 /*
132 UnwindStep:unwind:0: ip 0x5591ef772c sp 0x7f9aec76f0
133 UnwindStep:unwind:1: ip 0x5591ef78cb sp 0x7f9aec77b0
134 UnwindStep:unwind:2: ip 0x5591ef798f sp 0x7f9aec77e0
135 UnwindStep:unwind:3: ip 0x5591ef7a4f sp 0x7f9aec7820
136 UnwindStep:unwind:4: ip 0x5591ef7b0f sp 0x7f9aec7860
137 UnwindStep:unwind:5: ip 0x5591ef7bcf sp 0x7f9aec78a0
138 UnwindStep:unwind:6: ip 0x5591ef7c8f sp 0x7f9aec78e0
139 UnwindStep:unwind:7: ip 0x5591ef7d4f sp 0x7f9aec7920
140 UnwindStep:unwind:8: ip 0x5591ef7e0f sp 0x7f9aec7960
141 UnwindStep:unwind:9: ip 0x5591ef7ecf sp 0x7f9aec79a0
142 UnwindStep:unwind:10: ip 0x5591ef7f8f sp 0x7f9aec79e0
143 UnwindStep:unwind:11: ip 0x5591ef804f sp 0x7f9aec7a20
144 UnwindStep:unwind:12: ip 0x5591ef80e7 sp 0x7f9aec7a60
145 UnwindStep:unwind:13: ip 0x5591ef95db sp 0x7f9aec7a80
146 UnwindStep:unwind:14: ip 0x7f9b0fa59b sp 0x7f9aec7aa0
147 */
148 static const std::vector<frame> TEST_DWARF_FRAMES = {
149     {0x5591ef772c, 0x7f9aec76f0}, // base ip sp
150     {0x5591ef78cb, 0x7f9aec77b0}, {0x5591ef798f, 0x7f9aec77e0},   {0x5591ef7a4f, 0x7f9aec7820},
151     {0x5591ef7b0f, 0x7f9aec7860}, {0x5591ef7bcf, 0x7f9aec78a0},   {0x5591ef7c8f, 0x7f9aec78e0},
152     {0x5591ef7d4f, 0x7f9aec7920}, {0x5591ef7e0f, 0x7f9aec7960},   {0x5591ef7ecf, 0x7f9aec79a0},
153     {0x5591ef7f8f, 0x7f9aec79e0}, {0x5591ef804f, 0x7f9aec7a20},   {0x5591ef80e7, 0x7f9aec7a60},
154     {0x5591ef95db, 0x7f9aec7a80}, {0x7f9b0fa59b, 0x7f9aec7aa0},
155 };
156 #endif
157 
158 // data convert funcion
159 template<class T>
LoadFromFile(const std::string & fileName,std::vector<T> & data)160 void LoadFromFile(const std::string &fileName, std::vector<T> &data)
161 {
162     FILE* fp_ = fopen(fileName.c_str(), "r");
163     if (fp_ == nullptr) {
164         return;
165     }
166     std::unique_ptr<FILE, decltype(&fclose)> fp(fp_, fclose);
167     if (fp) {
168         struct stat sb = {};
169         ASSERT_NE(fstat(fileno(fp.get()), &sb), -1);
170         ASSERT_NE(sb.st_size, 0);
171         ASSERT_EQ(sb.st_size % sizeof(T), 0u);
172         data.resize(sb.st_size / sizeof(T));
173         ASSERT_EQ(fread(data.data(), sizeof(T), data.size(), fp.get()), data.size());
174     }
175 }
176 
MakeMaps(VirtualThread & thread)177 static void MakeMaps(VirtualThread &thread)
178 {
179     for (const mmapDumpInfo &mmap : TEST_DWARF_MMAP) {
180         thread.CreateMapItem(mmap.fileName, mmap.begin, mmap.len, mmap.pgoff);
181     }
182 }
183 } // namespace HiPerf
184 } // namespace Developtools
185 } // namespace OHOS
186 #endif // HIPERF_CALLSTACK_TEST_H
187