1 /*
2 * Copyright (c) 2024 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 <cstdlib>
20 #include <memory>
21 #include <mutex>
22 #include <thread>
23
24 #include <dlfcn.h>
25 #include <fcntl.h>
26 #include <securec.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
29
30 #include "async_stack.h"
31 #include "dfx_test_util.h"
32 #include "elapsed_time.h"
33 #include "fp_unwinder.h"
34 #include "uv.h"
35
36 using namespace testing;
37 using namespace testing::ext;
38
39 namespace OHOS {
40 namespace HiviewDFX {
41 #undef LOG_DOMAIN
42 #undef LOG_TAG
43 #define LOG_TAG "AsyncStackTest"
44 #define LOG_DOMAIN 0xD002D11
45
46 class AsyncStackTest : public testing::Test {
47 public:
48 static void SetUpTestCase();
49 static void TearDownTestCase();
50 void SetUp();
51 void TearDown();
52 };
53
SetUpTestCase()54 void AsyncStackTest::SetUpTestCase()
55 {}
56
TearDownTestCase()57 void AsyncStackTest::TearDownTestCase()
58 {}
59
SetUp()60 void AsyncStackTest::SetUp()
61 {}
62
TearDown()63 void AsyncStackTest::TearDown()
64 {}
65
66 constexpr size_t BUFFER_SIZE = 64 * 1024;
67 char *g_stackTrace = new (std::nothrow) char[BUFFER_SIZE];
68 int g_result = -1;
69 static bool g_done = false;
70
WorkCallback(uv_work_t * req)71 NOINLINE static void WorkCallback(uv_work_t* req)
72 {
73 g_result = DfxGetSubmitterStackLocal(g_stackTrace, BUFFER_SIZE);
74 }
75
AfterWorkCallback(uv_work_t * req,int status)76 NOINLINE static void AfterWorkCallback(uv_work_t* req, int status)
77 {
78 if (!g_done) {
79 uv_queue_work(req->loop, req, WorkCallback, AfterWorkCallback);
80 }
81 }
82
TimerCallback(uv_timer_t * handle)83 static void TimerCallback(uv_timer_t* handle)
84 {
85 g_done = true;
86 }
87 /**
88 * @tc.name: AsyncStackTest001
89 * @tc.desc: test GetAsyncStackLocal
90 * @tc.type: FUNC
91 */
92 HWTEST_F(AsyncStackTest, AsyncStackTest001, TestSize.Level2)
93 {
94 GTEST_LOG_(INFO) << "AsyncStackTest001: start.";
95 setenv("HAP_DEBUGGABLE", "true", 1);
96 ASSERT_EQ(DfxGetSubmitterStackLocal(g_stackTrace, BUFFER_SIZE), -1);
97 uv_timer_t timerHandle;
98 uv_work_t work;
99 uv_loop_t* loop = uv_default_loop();
100 int timeout = 1000;
101 uv_timer_init(loop, &timerHandle);
102 uv_timer_start(&timerHandle, TimerCallback, timeout, 0);
103 uv_queue_work(loop, &work, WorkCallback, AfterWorkCallback);
104 uv_run(loop, UV_RUN_DEFAULT);
105 #if defined(__aarch64__)
106 ASSERT_EQ(g_result, 0);
107 std::string stackTrace = std::string(g_stackTrace);
108 ASSERT_GT(stackTrace.size(), 0) << stackTrace;
109 #else
110 ASSERT_EQ(g_result, -1);
111 #endif
112 ASSERT_EQ(DfxGetSubmitterStackLocal(g_stackTrace, 0), -1);
113 GTEST_LOG_(INFO) << "AsyncStackTest001: end.";
114 }
115
116 /**
117 * @tc.name: AsyncStackTest002
118 * @tc.desc: test GetStackId()
119 * @tc.type: FUNC
120 */
121 HWTEST_F(AsyncStackTest, AsyncStackTest002, TestSize.Level2)
122 {
123 GTEST_LOG_(INFO) << "AsyncStackTest002: start.";
124 SetStackId(1);
125 auto res = GetStackId();
126 GTEST_LOG_(INFO) << "res: " << res;
127 #if defined(__arm__)
128 ASSERT_EQ(0, res);
129 #elif defined(__aarch64__)
130 ASSERT_NE(0, res);
131 #endif
132
133 GTEST_LOG_(INFO) << "AsyncStackTest002: end.";
134 }
135
136 /**
137 * @tc.name: AsyncStackTest003
138 * @tc.desc: test CollectAsyncStack()
139 * @tc.type: FUNC
140 */
141 HWTEST_F(AsyncStackTest, AsyncStackTest003, TestSize.Level0)
142 {
143 GTEST_LOG_(INFO) << "AsyncStackTest003: start.";
144 auto ret = CollectAsyncStack();
145 #if defined(__aarch64__)
146 ASSERT_NE(0, ret);
147 #else
148 ASSERT_EQ(0, ret);
149 #endif
150 GTEST_LOG_(INFO) << "AsyncStackTest003: end.";
151 }
152 } // namespace HiviewDFX
153 } // namepsace OHOS
154