• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <hilog/log.h>
22 #include <malloc.h>
23 #include <libunwind_i-ohos.h>
24 #include <libunwind.h>
25 #include <securec.h>
26 
27 #include "dfx_config.h"
28 #include "elapsed_time.h"
29 #include "dwarf_unwinder.h"
30 #include "fp_unwinder.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS {
36 namespace HiviewDFX {
37 #undef LOG_DOMAIN
38 #undef LOG_TAG
39 #define LOG_TAG "DfxUnwinderTest"
40 #define LOG_DOMAIN 0xD002D11
41 
42 class UnwinderTest : public testing::Test {
43 public:
SetUpTestCase()44     static void SetUpTestCase() {}
TearDownTestCase()45     static void TearDownTestCase() {}
SetUp()46     void SetUp() {}
TearDown()47     void TearDown() {}
48 };
49 
50 /**
51  * @tc.name: DfxConfigTest001
52  * @tc.desc: test DfxConfig class functions
53  * @tc.type: FUNC
54  */
55 HWTEST_F(UnwinderTest, DfxConfigTest001, TestSize.Level2)
56 {
57     GTEST_LOG_(INFO) << "DfxConfigTest001: start.";
58     ASSERT_EQ(DfxConfig::GetConfig().logPersist, false);
59     ASSERT_EQ(DfxConfig::GetConfig().displayRegister, true);
60     ASSERT_EQ(DfxConfig::GetConfig().displayBacktrace, true);
61     ASSERT_EQ(DfxConfig::GetConfig().displayMaps, true);
62     ASSERT_EQ(DfxConfig::GetConfig().displayFaultStack, true);
63     ASSERT_EQ(DfxConfig::GetConfig().dumpOtherThreads, true);
64     ASSERT_EQ(DfxConfig::GetConfig().highAddressStep, 512);
65     ASSERT_EQ(DfxConfig::GetConfig().lowAddressStep, 16);
66     ASSERT_EQ(DfxConfig::GetConfig().maxFrameNums, 256);
67     GTEST_LOG_(INFO) << "DfxConfigTest001: end.";
68 }
69 
70 /**
71  * @tc.name: UnwinderTest000
72  * @tc.desc: test dwarf unwinder UnwindWithContext
73  * @tc.type: FUNC
74  */
75 HWTEST_F(UnwinderTest, UnwinderTest000, TestSize.Level2)
76 {
77     GTEST_LOG_(INFO) << "UnwinderTest000: start.";
78     ElapsedTime counter;
79     unw_context_t context;
80     (void)memset_s(&context, sizeof(unw_context_t), 0, sizeof(unw_context_t));
81     unw_getcontext(&context);
82     pid_t child = fork();
83     if (child == 0) {
84         unw_addr_space_t as;
85         unw_init_local_address_space(&as);
86         if (as == nullptr) {
87             FAIL() << "Failed to init address space.";
88             return;
89         }
90 
91         auto symbol = std::make_shared<DfxSymbols>();
92         ElapsedTime counter2;
93         DwarfUnwinder unwinder;
94         ASSERT_EQ(true, unwinder.UnwindWithContext(as, context, symbol, 0));
95         GTEST_LOG_(INFO) << "ChildProcessElapse:" << counter2.Elapsed();
96         const auto& frames = unwinder.GetFrames();
97         ASSERT_GT(frames.size(), 0);
98         unw_destroy_local_address_space(as);
99         _exit(0);
100     }
101     GTEST_LOG_(INFO) << "CurrentThreadElapse:" << counter.Elapsed();
102 
103     int status;
104     int ret = wait(&status);
105     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
106     GTEST_LOG_(INFO) << "UnwinderTest000: end.";
107 }
108 
109 /**
110  * @tc.name: UnwinderTest001
111  * @tc.desc: test fp unwinder UnwindWithContext
112  * @tc.type: FUNC
113  */
114 HWTEST_F(UnwinderTest, UnwinderTest001, TestSize.Level2)
115 {
116     GTEST_LOG_(INFO) << "UnwinderTest001: start.";
117 #ifdef __aarch64__
118     ElapsedTime counter;
119     unw_context_t context;
120     (void)memset_s(&context, sizeof(unw_context_t), 0, sizeof(unw_context_t));
121     unw_getcontext(&context);
122     pid_t child = fork();
123     if (child == 0) {
124         ElapsedTime counter2;
125         FpUnwinder unwinder;
126         ASSERT_EQ(true, unwinder.UnwindWithContext(context, 0));
127         GTEST_LOG_(INFO) << "ChildProcessElapse:" << counter2.Elapsed();
128         const auto& frames = unwinder.GetFrames();
129         ASSERT_GT(frames.size(), 0);
130         _exit(0);
131     }
132     GTEST_LOG_(INFO) << "CurrentThreadElapse:" << counter.Elapsed();
133 
134     int status;
135     int ret = wait(&status);
136     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
137 #endif
138     GTEST_LOG_(INFO) << "UnwinderTest001: end.";
139 }
140 
141 /**
142  * @tc.name: UnwinderTest002
143  * @tc.desc: test fp unwinder Unwind
144  * @tc.type: FUNC
145  */
146 HWTEST_F(UnwinderTest, UnwinderTest002, TestSize.Level2)
147 {
148     GTEST_LOG_(INFO) << "UnwinderTest002: start.";
149 #ifdef __aarch64__
150     ElapsedTime counter;
151     pid_t child = fork();
152     if (child == 0) {
153         ElapsedTime counter2;
154         FpUnwinder unwinder;
155         ASSERT_EQ(true, unwinder.Unwind(0));
156         GTEST_LOG_(INFO) << "ChildProcessElapse:" << counter2.Elapsed();
157         const auto& frames = unwinder.GetFrames();
158         ASSERT_GT(frames.size(), 0);
159         _exit(0);
160     }
161     GTEST_LOG_(INFO) << "CurrentThreadElapse:" << counter.Elapsed();
162 
163     int status;
164     int ret = wait(&status);
165     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
166 #endif
167     GTEST_LOG_(INFO) << "UnwinderTest002: end.";
168 }
169 
170 /**
171  * @tc.name: UnwinderTest003
172  * @tc.desc: test dwarf unwinder Unwind
173  * @tc.type: FUNC
174  */
175 HWTEST_F(UnwinderTest, UnwinderTest003, TestSize.Level2)
176 {
177     GTEST_LOG_(INFO) << "UnwinderTest003: start.";
178     ElapsedTime counter;
179     pid_t child = fork();
180     if (child == 0) {
181         ElapsedTime counter2;
182         DwarfUnwinder unwinder;
183         ASSERT_EQ(true, unwinder.Unwind(0));
184         GTEST_LOG_(INFO) << "ChildProcessElapse:" << counter2.Elapsed();
185         const auto& frames = unwinder.GetFrames();
186         ASSERT_GT(frames.size(), 0);
187         _exit(0);
188     }
189     GTEST_LOG_(INFO) << "CurrentThreadElapse:" << counter.Elapsed();
190 
191     int status;
192     int ret = wait(&status);
193     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
194     GTEST_LOG_(INFO) << "UnwinderTest003: end.";
195 }
196 } // namespace HiviewDFX
197 } // namepsace OHOS
198