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 ASSERT_EQ(dfxElf->GetName(), "dumpcatcher");
104 dfxElf->SetPath(DUMPCATCHER_ELF_FILE);
105 ASSERT_EQ(dfxElf->GetPath(), DUMPCATCHER_ELF_FILE);
106 GTEST_LOG_(INFO) << dfxElf->GetFd();
107 GTEST_LOG_(INFO) << dfxElf->GetSize();
108 dfxElf->SetLoadBias(0);
109 ASSERT_EQ(dfxElf->GetLoadBias(), 0);
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 ASSERT_EQ(infos_bak.at(0).offset, 0);
120 ASSERT_EQ(infos_bak.at(0).vaddr, 1);
121 GTEST_LOG_(INFO) << "DfxElfTest001: end.";
122 }
123
124 /**
125 * @tc.name: DfxElfTest002
126 * @tc.desc: test DfxElf FindRealLoadOffset functions
127 * @tc.type: FUNC
128 */
129 HWTEST_F(DfxBaseTest, DfxElfTest002, TestSize.Level2)
130 {
131 GTEST_LOG_(INFO) << "DfxElfTest002: start.";
132 auto dfxElf = DfxElf::Create(DUMPCATCHER_ELF_FILE);
133 GTEST_LOG_(INFO) << dfxElf->FindRealLoadOffset(0);
134 GTEST_LOG_(INFO) << dfxElf->FindRealLoadOffset(1);
135 GTEST_LOG_(INFO) << "DfxElfTest002: end.";
136 }
137
138 /**
139 * @tc.name: DfxDumpResquestTest001
140 * @tc.desc: test DfxDumpResquest functions
141 * @tc.type: FUNC
142 */
143 HWTEST_F(DfxBaseTest, DfxDumpResquestTest001, TestSize.Level2)
144 {
145 GTEST_LOG_(INFO) << "DfxDumpResquestTest001: start.";
146 auto request = make_shared<ProcessDumpRequest>();
147 request->SetRecycleTid(-1);
148 ASSERT_EQ(request->GetRecycleTid(), -1);
149 struct TraceInfo traceinfo;
150 request->traceInfo = traceinfo;
151 auto info = request->GetTraceInfo();
152 char threadname[] = "testThread";
153 char processname[] = "testProcess";
154 char fatalmsg[] = "test fatal message";
155 if (strcpy_s(request->threadName_, NAME_LEN, threadname) != EOK) {
156 GTEST_LOG_(ERROR) << "strcpy_s failed.";
157 }
158 if (strcpy_s(request->processName_, NAME_LEN, processname) != EOK) {
159 GTEST_LOG_(ERROR) << "strcpy_s failed.";
160 }
161 if (strcpy_s(request->lastFatalMessage_, NAME_LEN, fatalmsg) != EOK) {
162 GTEST_LOG_(ERROR) << "strcpy_s failed.";
163 }
164 GTEST_LOG_(INFO) << "threadName_ = " << request->GetThreadNameString();
165 GTEST_LOG_(INFO) << "processName_ = " << request->GetProcessNameString();
166 GTEST_LOG_(INFO) << "lastFatalMessage_ = " << request->GetLastFatalMessage();
167 GTEST_LOG_(INFO) << "DfxDumpResquestTest001: end.";
168 }
169
170 /**
171 * @tc.name: DfxDumpResTest001
172 * @tc.desc: test DfxDumpRes functions
173 * @tc.type: FUNC
174 */
175 HWTEST_F(DfxBaseTest, DfxDumpResTest001, TestSize.Level2)
176 {
177 GTEST_LOG_(INFO) << "DfxDumpResTest001: start.";
178 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ESUCCESS);
179 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
180 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EREADREQUEST);
181 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
182 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EGETPPID);
183 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
184 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EATTACH);
185 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
186 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EGETFD);
187 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
188 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ENOMEM);
189 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
190 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADREG);
191 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
192 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EREADONLYREG);
193 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
194 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ESTOPUNWIND);
195 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
196 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EINVALIDIP);
197 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
198 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADFRAME);
199 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
200 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EINVAL);
201 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
202 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_EBADVERSION);
203 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
204 DfxDumpRes::GetInstance().SetRes(ProcessDumpRes::DUMP_ENOINFO);
205 ASSERT_EQ(DfxDumpRes::GetInstance().GetRes(), ProcessDumpRes::DUMP_ENOINFO);
206 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
207 DfxDumpRes::GetInstance().SetRes(-1); // -1 : invalid status
208 GTEST_LOG_(INFO) << DfxDumpRes::GetInstance().ToString();
209 GTEST_LOG_(INFO) << "DfxDumpResTest001: end.";
210 }
211
212 /**
213 * @tc.name: DfxSignalTest001
214 * @tc.desc: test DfxSignal functions
215 * @tc.type: FUNC
216 */
217 HWTEST_F(DfxBaseTest, DfxSignalTest001, TestSize.Level2)
218 {
219 GTEST_LOG_(INFO) << "DfxSignalTest001: start.";
220 siginfo_t si = {
221 .si_signo = SIGSEGV,
222 .si_errno = 0,
223 .si_code = -1,
224 .si_value.sival_int = gettid()
225 };
226 GTEST_LOG_(INFO) << PrintSignal(si);
227 si.si_signo = SIGABRT;
228 GTEST_LOG_(INFO) << PrintSignal(si);
229 si.si_signo = SIGBUS;
230 GTEST_LOG_(INFO) << PrintSignal(si);
231 si.si_signo = SIGILL;
232 GTEST_LOG_(INFO) << PrintSignal(si);
233 si.si_signo = SIGTRAP;
234 GTEST_LOG_(INFO) << PrintSignal(si);
235 si.si_signo = SIGFPE;
236 GTEST_LOG_(INFO) << PrintSignal(si);
237 si.si_signo = SIGSTKFLT;
238 GTEST_LOG_(INFO) << PrintSignal(si);
239 si.si_signo = SIGSYS;
240 GTEST_LOG_(INFO) << PrintSignal(si);
241 GTEST_LOG_(INFO) << "DfxSignalTest001: end.";
242 }
243
244 /**
245 * @tc.name: DfxUtilTest001
246 * @tc.desc: test DfxUtil functions
247 * @tc.type: FUNC
248 */
249 HWTEST_F(DfxBaseTest, DfxUtilTest001, TestSize.Level2)
250 {
251 GTEST_LOG_(INFO) << "DfxUtilTest001: start.";
252 time_t now = time(nullptr);
253 GTEST_LOG_(INFO) << GetCurrentTimeStr(static_cast<uint64_t>(now));
254 now += 100000; // 100000 : test time offset
255 GTEST_LOG_(INFO) << GetCurrentTimeStr(static_cast<uint64_t>(now));
256 GTEST_LOG_(INFO) << "DfxUtilTest001: end.";
257 }
258
259 /**
260 * @tc.name: DfxUtilTest002
261 * @tc.desc: test DfxUtil functions
262 * @tc.type: FUNC
263 */
264 HWTEST_F(DfxBaseTest, DfxUtilTest002, TestSize.Level2)
265 {
266 GTEST_LOG_(INFO) << "DfxUtilTest002: start.";
267 pid_t pid = getppid();
268 ASSERT_EQ(pid, GetRealTargetPid());
269 GTEST_LOG_(INFO) << "DfxUtilTest002: end.";
270 }
271