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 "dfx_base_test.h"
17
18 #include <ctime>
19 #include <securec.h>
20 #include <string>
21 #include <vector>
22
23 #include "dfx_config.h"
24 #define private public
25 #include "dfx_dump_request.h"
26 #undef private
27 #include "dfx_dump_res.h"
28 #include "dfx_fault_stack.h"
29 #include "dfx_elf.h"
30 #include "dfx_signal.h"
31 #include "dfx_util.h"
32
33 using namespace OHOS::HiviewDFX;
34 using namespace testing::ext;
35 using namespace std;
36
SetUpTestCase(void)37 void DfxBaseTest::SetUpTestCase(void)
38 {
39 }
40
TearDownTestCase(void)41 void DfxBaseTest::TearDownTestCase(void)
42 {
43 }
44
SetUp(void)45 void DfxBaseTest::SetUp(void)
46 {
47 }
48
TearDown(void)49 void DfxBaseTest::TearDown(void)
50 {
51 }
52
53 static const char DUMPCATCHER_ELF_FILE[] = "/system/bin/dumpcatcher";
54
55 /**
56 * @tc.name: DfxConfigTest001
57 * @tc.desc: test DfxConfig class functions
58 * @tc.type: FUNC
59 */
60 HWTEST_F(DfxBaseTest, DfxConfigTest001, TestSize.Level2)
61 {
62 GTEST_LOG_(INFO) << "DfxConfigTest001: start.";
63 DfxConfig::GetInstance().ReadConfig();
64 ASSERT_EQ(DfxConfig::GetInstance().GetLogPersist(), false);
65 DfxConfig::GetInstance().SetLogPersist(true);
66 ASSERT_EQ(DfxConfig::GetInstance().GetLogPersist(), true);
67
68 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayRegister(), true);
69 DfxConfig::GetInstance().SetDisplayRegister(false);
70 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayRegister(), false);
71
72 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayBacktrace(), true);
73 DfxConfig::GetInstance().SetDisplayBacktrace(false);
74 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayBacktrace(), false);
75
76 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayMaps(), true);
77 DfxConfig::GetInstance().SetDisplayMaps(false);
78 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayMaps(), false);
79
80 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayFaultStack(), true);
81 DfxConfig::GetInstance().SetDisplayFaultStack(false);
82 ASSERT_EQ(DfxConfig::GetInstance().GetDisplayFaultStack(), false);
83
84 ASSERT_EQ(DfxConfig::GetInstance().GetDumpOtherThreads(), false);
85 DfxConfig::GetInstance().SetDumpOtherThreads(true);
86 ASSERT_EQ(DfxConfig::GetInstance().GetDumpOtherThreads(), true);
87
88 ASSERT_EQ(DfxConfig::GetInstance().GetFaultStackHighAddressStep(), 512);
89 ASSERT_EQ(DfxConfig::GetInstance().GetFaultStackLowAddressStep(), 16);
90 GTEST_LOG_(INFO) << "DfxConfigTest001: end.";
91 }
92
93 /**
94 * @tc.name: DfxElfTest001
95 * @tc.desc: test DfxElf class functions
96 * @tc.type: FUNC
97 */
98 HWTEST_F(DfxBaseTest, DfxElfTest001, TestSize.Level2)
99 {
100 GTEST_LOG_(INFO) << "DfxElfTest001: start.";
101 auto dfxElf = DfxElf::Create(DUMPCATCHER_ELF_FILE);
102 dfxElf->SetName("dumpcatcher");
103 string name = dfxElf->GetName();
104 dfxElf->SetPath(DUMPCATCHER_ELF_FILE);
105 string path = dfxElf->GetPath();
106 int32_t fd = dfxElf->GetFd();
107 uint64_t size = dfxElf->GetSize();
108 dfxElf->SetLoadBias(0);
109 size_t loadBias = dfxElf->GetLoadBias();
110 dfxElf->SetHeader(ElfW(Ehdr)());
111 ElfW(Ehdr) header = dfxElf->GetHeader();
112 struct ElfLoadInfo info;
113 info.offset = 0;
114 info.vaddr = 1;
115 vector<ElfLoadInfo> infos;
116 infos.emplace_back(info);
117 dfxElf->SetInfos(infos);
118 auto infos_bak = dfxElf->GetInfos();
119 GTEST_LOG_(INFO) << "DfxElfTest001: end.";
120 }
121
122 /**
123 * @tc.name: DfxElfTest002
124 * @tc.desc: test DfxElf FindRealLoadOffset functions
125 * @tc.type: FUNC
126 */
127 HWTEST_F(DfxBaseTest, DfxElfTest002, TestSize.Level2)
128 {
129 GTEST_LOG_(INFO) << "DfxElfTest002: start.";
130 auto dfxElf = DfxElf::Create(DUMPCATCHER_ELF_FILE);
131 uint64_t offset0 = dfxElf->FindRealLoadOffset(0);
132 uint64_t offset1 = dfxElf->FindRealLoadOffset(1);
133 GTEST_LOG_(INFO) << "DfxElfTest002: end.";
134 }
135
136 /**
137 * @tc.name: DfxDumpResquestTest001
138 * @tc.desc: test DfxDumpResquest functions
139 * @tc.type: FUNC
140 */
141 HWTEST_F(DfxBaseTest, DfxDumpResquestTest001, TestSize.Level2)
142 {
143 GTEST_LOG_(INFO) << "DfxDumpResquestTest001: start.";
144 auto request = make_shared<ProcessDumpRequest>();
145 request->SetRecycleTid(-1);
146 ASSERT_EQ(request->GetRecycleTid(), -1);
147 struct TraceInfo traceinfo;
148 request->traceInfo = traceinfo;
149 auto info = request->GetTraceInfo();
150 char threadname[] = "testThread";
151 char processname[] = "testProcess";
152 char fatalmsg[] = "test fatal message";
153 errno_t err = EOK;
154 if (strcpy_s(request->threadName_, NAME_LEN, threadname) != EOK) {
155 GTEST_LOG_(ERROR) << "strcpy_s failed.";
156 }
157 if (strcpy_s(request->processName_, NAME_LEN, processname) != EOK) {
158 GTEST_LOG_(ERROR) << "strcpy_s failed.";
159 }
160 if (strcpy_s(request->lastFatalMessage_, NAME_LEN, fatalmsg) != EOK) {
161 GTEST_LOG_(ERROR) << "strcpy_s failed.";
162 }
163 GTEST_LOG_(INFO) << "threadName_ = " << request->GetThreadNameString();
164 GTEST_LOG_(INFO) << "processName_ = " << request->GetProcessNameString();
165 GTEST_LOG_(INFO) << "lastFatalMessage_ = " << request->GetLastFatalMessage();
166 GTEST_LOG_(INFO) << "DfxDumpResquestTest001: end.";
167 }
168
169 /**
170 * @tc.name: DfxDumpResTest001
171 * @tc.desc: test DfxDumpRes functions
172 * @tc.type: FUNC
173 */
174 HWTEST_F(DfxBaseTest, DfxDumpResTest001, TestSize.Level2)
175 {
176 GTEST_LOG_(INFO) << "DfxDumpResTest001: start.";
177 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ESUCCESS);
178 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
179 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EREADREQUEST);
180 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
181 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EGETPPID);
182 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
183 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EATTACH);
184 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
185 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EGETFD);
186 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
187 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ENOMEM);
188 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
189 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADREG);
190 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
191 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EREADONLYREG);
192 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
193 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ESTOPUNWIND);
194 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
195 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EINVALIDIP);
196 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
197 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADFRAME);
198 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
199 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EINVAL);
200 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
201 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADVERSION);
202 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
203 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ENOINFO);
204 ASSERT_EQ(DfxDumpRes::GetInstance().GetRes(), ProcessDumpRes::DUMP_ENOINFO);
205 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
206 DfxDumpRes::GetInstance().SetRes(-1); // -1 : invalid status
207 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
208 GTEST_LOG_(INFO) << "DfxDumpResTest001: end.";
209 }
210
211 /**
212 * @tc.name: DfxSignalTest001
213 * @tc.desc: test DfxSignal functions
214 * @tc.type: FUNC
215 */
216 HWTEST_F(DfxBaseTest, DfxSignalTest001, TestSize.Level2)
217 {
218 GTEST_LOG_(INFO) << "DfxSignalTest001: start.";
219 siginfo_t si = {
220 .si_signo = SIGSEGV,
221 .si_errno = 0,
222 .si_code = -1,
223 .si_value.sival_int = gettid()
224 };
225 GTEST_LOG_(INFO) << PrintSignal(si);
226 si.si_signo = SIGABRT;
227 GTEST_LOG_(INFO) << PrintSignal(si);
228 si.si_signo = SIGBUS;
229 GTEST_LOG_(INFO) << PrintSignal(si);
230 si.si_signo = SIGILL;
231 GTEST_LOG_(INFO) << PrintSignal(si);
232 si.si_signo = SIGTRAP;
233 GTEST_LOG_(INFO) << PrintSignal(si);
234 si.si_signo = SIGFPE;
235 GTEST_LOG_(INFO) << PrintSignal(si);
236 si.si_signo = SIGSTKFLT;
237 GTEST_LOG_(INFO) << PrintSignal(si);
238 si.si_signo = SIGSYS;
239 GTEST_LOG_(INFO) << PrintSignal(si);
240 GTEST_LOG_(INFO) << "DfxSignalTest001: end.";
241 }
242
243 /**
244 * @tc.name: DfxUtilTest001
245 * @tc.desc: test DfxUtil functions
246 * @tc.type: FUNC
247 */
248 HWTEST_F(DfxBaseTest, DfxUtilTest001, TestSize.Level2)
249 {
250 GTEST_LOG_(INFO) << "DfxUtilTest001: start.";
251 time_t now = time(nullptr);
252 GTEST_LOG_(INFO) << GetCurrentTimeStr(static_cast<uint64_t>(now));
253 now += 100000; // 100000 : test time offset
254 GTEST_LOG_(INFO) << GetCurrentTimeStr(static_cast<uint64_t>(now));
255 GTEST_LOG_(INFO) << "DfxUtilTest001: end.";
256 }
257
258 /**
259 * @tc.name: DfxUtilTest002
260 * @tc.desc: test DfxUtil functions
261 * @tc.type: FUNC
262 */
263 HWTEST_F(DfxBaseTest, DfxUtilTest002, TestSize.Level2)
264 {
265 GTEST_LOG_(INFO) << "DfxUtilTest002: start.";
266 pid_t pid = getppid();
267 ASSERT_EQ(pid, GetRealTargetPid());
268 GTEST_LOG_(INFO) << "DfxUtilTest002: end.";
269 }
270