1 /*
2 * Copyright (c) 2025 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 #include <vector>
18
19 #include "stack_printer.h"
20
21 using namespace testing::ext;
22
23 namespace OHOS {
24 namespace HiviewDFX {
25 #if defined(__aarch64__)
26 static std::vector<std::vector<uintptr_t>> pcsVec = {
27 {
28 0x0000007f0b0da13c,
29 0x0000007f19709a99,
30 0x0000007f1ac8e1b4,
31 0x0000007f1af60370,
32 0x0000007f14ddbf9c,
33 0x0000007f147adc54,
34 0x0000007f1479c8e0,
35 0x0000007f14845870,
36 0x0000007f12a2d55c,
37 0x0000007f12ae6590,
38 0x0000007f12af1df8,
39 0x0000007f12adfbe0,
40 0x0000007f12af1150,
41 0x0000007f12ae8e4c,
42 0x0000007f12af0284,
43 0x0000007f11e9e8f0,
44 0x0000007f11e9c374,
45 0x0000007f12074ab8,
46 0x0000007f1457c4e0,
47 0x0000007f1457bcc8,
48 0x0000007f145a4818,
49 0x0000007f14606d64,
50 0x0000007f18f65d34,
51 0x0000007f18f4f5f4,
52 0x0000007f18f778dc,
53 0x0000007f18efa87c,
54 0x0000007f18efacd0,
55 0x0000007f1f7df700,
56 0x0000007f1f7c5c9c
57 },
58 {
59 0x0000007f1ad84888,
60 0x0000007f0b0da140,
61 0x0000007f0ab16de4,
62 0x0000007f19709a99,
63 0x0000007f1ac8e1b4,
64 0x0000007f1af60370,
65 0x0000007f14ddbf9c,
66 0x0000007f147adc54,
67 0x0000007f1479c8e0,
68 0x0000007f14845870,
69 0x0000007f12a2d55c,
70 0x0000007f12ae6590,
71 0x0000007f12af1df8,
72 0x0000007f12adfbe0,
73 0x0000007f12af1150,
74 0x0000007f12ae8e4c,
75 0x0000007f12af0284,
76 0x0000007f11e9e8f0,
77 0x0000007f11e9c374,
78 0x0000007f12074ab8,
79 0x0000007f1457c4e0,
80 0x0000007f1457bcc8,
81 0x0000007f145a4818,
82 0x0000007f14606d64,
83 0x0000007f18f65d34,
84 0x0000007f18f4f5f4,
85 0x0000007f18f778dc,
86 0x0000007f18efa87c,
87 0x0000007f18efacd0,
88 0x0000007f1f7df700,
89 0x0000007f1f7c5c9c
90 },
91 {
92 0x0000007f0ab2c670,
93 0x0000007f19709a99,
94 0x0000007f1ac8e1b4,
95 0x0000007f1af60370,
96 0x0000007f14ddbf9c,
97 0x0000007f147adc54,
98 0x0000007f1479c8e0,
99 0x0000007f14845870,
100 0x0000007f12a2d55c,
101 0x0000007f12ae6590,
102 0x0000007f12af1df8,
103 0x0000007f12adfbe0,
104 0x0000007f12af1150,
105 0x0000007f12ae8e4c,
106 0x0000007f12af0284,
107 0x0000007f11e9e8f0,
108 0x0000007f11e9c374,
109 0x0000007f12074ab8,
110 0x0000007f1457c4e0,
111 0x0000007f1457bcc8,
112 0x0000007f145a4818,
113 0x0000007f14606d64,
114 0x0000007f18f65d34,
115 0x0000007f18f4f5f4,
116 0x0000007f18f778dc,
117 0x0000007f18efa87c,
118 0x0000007f18efacd0,
119 0x0000007f1f7df700,
120 0x0000007f1f7c5c9c
121 },
122 {
123 0x0000007f0ab2c60c,
124 0x0000007f19709a99,
125 0x0000007f1ac8e1b4,
126 0x0000007f1af60370,
127 0x0000007f14ddbf9c,
128 0x0000007f147adc54,
129 0x0000007f1479c8e0,
130 0x0000007f14845870,
131 0x0000007f12a2d55c,
132 0x0000007f12ae6590,
133 0x0000007f12af1df8,
134 0x0000007f12adfbe0,
135 0x0000007f12af1150,
136 0x0000007f12ae8e4c,
137 0x0000007f12af0284,
138 0x0000007f11e9e8f0,
139 0x0000007f11e9c374,
140 0x0000007f12074ab8,
141 0x0000007f1457c4e0,
142 0x0000007f1457bcc8,
143 0x0000007f145a4818,
144 0x0000007f14606d64,
145 0x0000007f18f65d34,
146 0x0000007f18f4f5f4,
147 0x0000007f18f778dc,
148 0x0000007f18efa87c,
149 0x0000007f18efacd0,
150 0x0000007f1f7df700,
151 0x0000007f1f7c5c9c
152 },
153 {
154 0x0000007fa409ac8c,
155 0x0000007f2291931c,
156 0x0000007f22920ddc,
157 0x0000007f2292453c,
158 0x0000007f2292f17c,
159 0x0000007f22932a44,
160 0x0000007f18b22f58,
161 0x0000007f17b057c4,
162 0x000000556e13254c,
163 0x000000556e13c5a0,
164 0x000000556e13a3dc,
165 0x0000007fa38d6d68,
166 0x0000007fa38d687c,
167 0x0000007fa38d3fb4,
168 0x0000007fa38d3b30,
169 0x000000556e1380e0,
170 0x000000556e135ac0,
171 0x0000007fa4070618,
172 0x000000556e132234
173 },
174 {
175 0x0000007fa409ac8c,
176 0x0000007f2291931c,
177 0x0000007f22920ddc,
178 0x0000007f2292453c,
179 0x0000007f2292f17c,
180 0x0000007f22932a44,
181 0x0000007f18b22f58,
182 0x0000007f17b057c4,
183 0x000000556e13254c,
184 0x000000556e13c5a0,
185 0x000000556e13a3dc,
186 0x0000007fa38d6d68,
187 0x0000007fa38d687c,
188 0x0000007fa38d3fb4,
189 0x0000007fa38d3b30,
190 0x000000556e1380e0,
191 0x000000556e135ac0,
192 0x0000007fa4070618,
193 0x000000556e132234
194 },
195 {
196 0x0000007fa409ac8c,
197 0x0000007f2291931c,
198 0x0000007f22920ddc,
199 0x0000007f2292453c,
200 0x0000007f2292f17c,
201 0x0000007f22932a44,
202 0x0000007f18b22f58,
203 0x0000007f17b057c4,
204 0x000000556e13254c,
205 0x000000556e13c5a0,
206 0x000000556e13a3dc,
207 0x0000007fa38d6d68,
208 0x0000007fa38d687c,
209 0x0000007fa38d3fb4,
210 0x0000007fa38d3b30,
211 0x000000556e1380e0,
212 0x000000556e135ac0,
213 0x0000007fa4070618,
214 0x000000556e132234
215 },
216 {
217 0x0000007fa409ac8c,
218 0x0000007f2291931c,
219 0x0000007f22920ddc,
220 0x0000007f2292453c,
221 0x0000007f2292f17c,
222 0x0000007f22932a44,
223 0x0000007f18b22f58,
224 0x0000007f17b057c4,
225 0x000000556e13254c,
226 0x000000556e13c5a0,
227 0x000000556e13a3dc,
228 0x0000007fa38d6d68,
229 0x0000007fa38d687c,
230 0x0000007fa38d3fb4,
231 0x0000007fa38d3b30,
232 0x000000556e1380e0,
233 0x000000556e135ac0,
234 0x0000007fa4070618,
235 0x000000556e132234
236 },
237 {
238 0x0000007fa409ac8c,
239 0x0000007f2291931c,
240 0x0000007f22920ddc,
241 0x0000007f2292453c,
242 0x0000007f2292f17c,
243 0x0000007f22932a44,
244 0x0000007f18b22f58,
245 0x0000007f17b057c4,
246 0x000000556e13254c,
247 0x000000556e13c5a0,
248 0x000000556e13a3dc,
249 0x0000007fa38d6d68,
250 0x0000007fa38d687c,
251 0x0000007fa38d3fb4,
252 0x0000007fa38d3b30,
253 0x000000556e1380e0,
254 0x000000556e135ac0,
255 0x0000007fa4070618,
256 0x000000556e132234
257 },
258 {
259 0x0000007fa409ac8c,
260 0x0000007f2291931c,
261 0x0000007f22920ddc,
262 0x0000007f2292453c,
263 0x0000007f2292f17c,
264 0x0000007f22932a44,
265 0x0000007f18b22f58,
266 0x0000007f17b057c4,
267 0x000000556e13254c,
268 0x000000556e13c5a0,
269 0x000000556e13a3dc,
270 0x0000007fa38d6d68,
271 0x0000007fa38d687c,
272 0x0000007fa38d3fb4,
273 0x0000007fa38d3b30,
274 0x000000556e1380e0,
275 0x000000556e135ac0,
276 0x0000007fa4070618,
277 0x000000556e132234
278 }
279 };
280 const std::string MAPS_PATH = "/data/test/resource/testdata/stack_printer_testmaps64";
281 #elif defined(__arm__)
282 static std::vector<std::vector<uintptr_t>> pcsVec = {
283 {
284 0xedc80a80,
285 0xed87fe33,
286 0xed87f8f9,
287 0xeda22db5,
288 0xeda0ff2b,
289 0xedaaf9cf,
290 0xedbef469,
291 0xe9934d59,
292 0xe953e4fd,
293 0xe9533a47,
294 0xe959dedb,
295 0xe7feae75,
296 0xe806f8f9,
297 0xe806f773,
298 0xe807822f,
299 0xe806b24d,
300 0xe8077809,
301 0xe8070aeb,
302 0xe80713d1,
303 0xe8076de5,
304 0xe8076c6b,
305 0xe8076c1d,
306 0xe77bbc87,
307 0xe77ba81f,
308 0xe77ba0af,
309 0xe78e385f,
310 0xe93abc63,
311 0xe93ab6d9,
312 0xe93c866d,
313 0xe93c7b23,
314 0xe940e30b,
315 0xed48553f,
316 0xed4793e9,
317 0xed490881,
318 0xed440609,
319 0xed440945,
320 0xed590c0b,
321 0xed57eca3,
322 0xed57dbc1,
323 0xee73601b
324 },
325 {
326 0xeda18e0e,
327 0xeda0ff2b,
328 0xedaaf9cf,
329 0xedbef469,
330 0xe9934d59,
331 0xe953e4fd,
332 0xe9533a47,
333 0xe959dedb,
334 0xe7feae75,
335 0xe806f8f9,
336 0xe806f773,
337 0xe807822f,
338 0xe806b24d,
339 0xe8077809,
340 0xe8070aeb,
341 0xe80713d1,
342 0xe8076de5,
343 0xe8076c6b,
344 0xe8076c1d,
345 0xe77bbc87,
346 0xe77ba81f,
347 0xe77ba0af,
348 0xe78e385f,
349 0xe93abc63,
350 0xe93ab6d9,
351 0xe93c866d,
352 0xe93c7b23,
353 0xe940e30b,
354 0xed48553f,
355 0xed4793e9,
356 0xed490881,
357 0xed440609,
358 0xed440945,
359 0xed590c0b,
360 0xed57eca3,
361 0xed57dbc1,
362 0xee73601b
363 },
364 {
365 0xf7a16458,
366 0xf5793273,
367 0xf5798c65,
368 0xf579b403,
369 0xf57a2ea9,
370 0xf57a59af,
371 0xf0b75909,
372 0xf4984e89,
373 0x00a410fd,
374 0x00a4897d,
375 0x00a46f05,
376 0xf710f8a3,
377 0xf710f511,
378 0xf710d713,
379 0xf710d3b5,
380 0x00a454a7,
381 0x00a437f7,
382 0xf79e2fe4,
383 0x00a40f18,
384 0x00a40ebc
385 },
386 {
387 0xf7a16458,
388 0xf5793273,
389 0xf5798c65,
390 0xf579b403,
391 0xf57a2ea9,
392 0xf57a59af,
393 0xf0b75909,
394 0xf4984e89,
395 0x00a410fd,
396 0x00a4897d,
397 0x00a46f05,
398 0xf710f8a3,
399 0xf710f511,
400 0xf710d713,
401 0xf710d3b5,
402 0x00a454a7,
403 0x00a437f7,
404 0xf79e2fe4,
405 0x00a40f18,
406 0x00a40ebc
407 },
408 {
409 0xf7a16458,
410 0xf5793273,
411 0xf5798c65,
412 0xf579b403,
413 0xf57a2ea9,
414 0xf57a59af,
415 0xf0b75909,
416 0xf4984e89,
417 0x00a410fd,
418 0x00a4897d,
419 0x00a46f05,
420 0xf710f8a3,
421 0xf710f511,
422 0xf710d713,
423 0xf710d3b5,
424 0x00a454a7,
425 0x00a437f7,
426 0xf79e2fe4,
427 0x00a40f18,
428 0x00a40ebc
429 },
430 {
431 0xf7a16458,
432 0xf5793273,
433 0xf5798c65,
434 0xf579b403,
435 0xf57a2ea9,
436 0xf57a59af,
437 0xf0b75909,
438 0xf4984e89,
439 0x00a410fd,
440 0x00a4897d,
441 0x00a46f05,
442 0xf710f8a3,
443 0xf710f511,
444 0xf710d713,
445 0xf710d3b5,
446 0x00a454a7,
447 0x00a437f7,
448 0xf79e2fe4,
449 0x00a40f18,
450 0x00a40ebc
451 },
452 {
453 0xf7a16458,
454 0xf5793273,
455 0xf5798c65,
456 0xf579b403,
457 0xf57a2ea9,
458 0xf57a59af,
459 0xf0b75909,
460 0xf4984e89,
461 0x00a410fd,
462 0x00a4897d,
463 0x00a46f05,
464 0xf710f8a3,
465 0xf710f511,
466 0xf710d713,
467 0xf710d3b5,
468 0x00a454a7,
469 0x00a437f7,
470 0xf79e2fe4,
471 0x00a40f18,
472 0x00a40ebc
473 },
474 {
475 0xf7a16458,
476 0xf5793273,
477 0xf5798c65,
478 0xf579b403,
479 0xf57a2ea9,
480 0xf57a59af,
481 0xf0b75909,
482 0xf4984e89,
483 0x00a410fd,
484 0x00a4897d,
485 0x00a46f05,
486 0xf710f8a3,
487 0xf710f511,
488 0xf710d713,
489 0xf710d3b5,
490 0x00a454a7,
491 0x00a437f7,
492 0xf79e2fe4,
493 0x00a40f18,
494 0x00a40ebc
495 },
496 {
497 0xf7a16458,
498 0xf5793273,
499 0xf5798c65,
500 0xf579b403,
501 0xf57a2ea9,
502 0xf57a59af,
503 0xf0b75909,
504 0xf4984e89,
505 0x00a410fd,
506 0x00a4897d,
507 0x00a46f05,
508 0xf710f8a3,
509 0xf710f511,
510 0xf710d713,
511 0xf710d3b5,
512 0x00a454a7,
513 0x00a437f7,
514 0xf79e2fe4,
515 0x00a40f18,
516 0x00a40ebc
517 },
518 {
519 0xf7a16458,
520 0xf5793273,
521 0xf5798c65,
522 0xf579b403,
523 0xf57a2ea9,
524 0xf57a59af,
525 0xf0b75909,
526 0xf4984e89,
527 0x00a410fd,
528 0x00a4897d,
529 0x00a46f05,
530 0xf710f8a3,
531 0xf710f511,
532 0xf710d713,
533 0xf710d3b5,
534 0x00a454a7,
535 0x00a437f7,
536 0xf79e2fe4,
537 0x00a40f18,
538 0x00a40ebc
539 }
540 };
541 const std::string MAPS_PATH = "/data/test/resource/testdata/stack_printer_testmaps32";
542 #endif
543
544 static std::vector<uint64_t> timestamps = {
545 1719392400123456789,
546 1719392400123606789,
547 1719392400123756789,
548 1719392400123906789,
549 1719392400124056789,
550 1719392400124206789,
551 1719392400124356789,
552 1719392400124506789,
553 1719392400124656789,
554 1719392400124706789,
555 };
556
557 class StackPrinterTest : public testing::Test {
558 public:
559 static void SetUpTestCase(void);
560 static void TearDownTestCase(void);
561 void SetUp();
562 void TearDown();
563 };
564
SetUpTestCase(void)565 void StackPrinterTest::SetUpTestCase(void)
566 {
567 GTEST_LOG_(INFO) << "SetUpTestCase.";
568 }
569
TearDownTestCase(void)570 void StackPrinterTest::TearDownTestCase(void)
571 {
572 GTEST_LOG_(INFO) << "TearDownTestCase.";
573 }
574
SetUp(void)575 void StackPrinterTest::SetUp(void)
576 {
577 GTEST_LOG_(INFO) << "SetUp.";
578 }
579
TearDown(void)580 void StackPrinterTest::TearDown(void)
581 {
582 GTEST_LOG_(INFO) << "TearDown.";
583 }
584
585 /**
586 * @tc.name: StackPrinterTest001
587 * @tc.desc: test StackPrinter functions
588 * @tc.type: FUNC
589 */
590 HWTEST_F(StackPrinterTest, StackPrinterTest_001, TestSize.Level2)
591 {
592 GTEST_LOG_(INFO) << "StackPrinterTest_001: start.";
593 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
594 bool flag = stackPrinter->InitUniqueTable(getpid(), 0);
595 ASSERT_FALSE(flag);
596 uint32_t uniqueStableSize = 128 * 1024;
597 flag = stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
598 ASSERT_TRUE(flag);
599 GTEST_LOG_(INFO) << "StackPrinterTest_001: end.";
600 }
601
602 /**
603 * @tc.name: StackPrinterTest002
604 * @tc.desc: test StackPrinter functions
605 * @tc.type: FUNC
606 */
607 HWTEST_F(StackPrinterTest, StackPrinterTest_002, TestSize.Level2)
608 {
609 GTEST_LOG_(INFO) << "StackPrinterTest_002: start.";
610 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
611 bool flag = stackPrinter->PutPcsInTable(pcsVec[0], gettid(), timestamps[0]);
612 ASSERT_FALSE(flag);
613
614 uint32_t uniqueStableSize = 128 * 1024;
615 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
616 for (size_t i = 0; i < pcsVec.size(); i++) {
617 flag = stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
618 ASSERT_TRUE(flag);
619 }
620 GTEST_LOG_(INFO) << "StackPrinterTest_002: end.";
621 }
622
623 /**
624 * @tc.name: StackPrinterTest003
625 * @tc.desc: test StackPrinter functions
626 * @tc.type: FUNC
627 */
628 HWTEST_F(StackPrinterTest, StackPrinterTest_003, TestSize.Level2)
629 {
630 GTEST_LOG_(INFO) << "StackPrinterTest_003: start.";
631 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
632 std::vector<TimeStampedPcs> timeStampedPcsVec;
633 for (size_t i = 0; i < pcsVec.size(); i++) {
634 TimeStampedPcs p = {
635 .snapshotTime = timestamps[i],
636 .pcVec = pcsVec[i]
637 };
638 timeStampedPcsVec.emplace_back(p);
639 }
640
641 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
642 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
643 stackPrinter->SetUnwindInfo(unwinder, maps);
644 std::string stack = stackPrinter->GetFullStack(timeStampedPcsVec);
645 ASSERT_NE(stack, "");
646 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
647 GTEST_LOG_(INFO) << "StackPrinterTest_003: end.\n";
648 }
649
650 /**
651 * @tc.name: StackPrinterTest004
652 * @tc.desc: test StackPrinter functions
653 * @tc.type: FUNC
654 */
655 HWTEST_F(StackPrinterTest, StackPrinterTest_004, TestSize.Level2)
656 {
657 GTEST_LOG_(INFO) << "StackPrinterTest_004: start.";
658 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
659 uint32_t uniqueStableSize = 128 * 1024;
660 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
661 for (size_t i = 0; i < pcsVec.size(); i++) {
662 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
663 }
664
665 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
666 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
667 stackPrinter->SetUnwindInfo(unwinder, maps);
668 std::string stack = stackPrinter->GetTreeStack(gettid());
669 ASSERT_NE(stack, "");
670 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
671 GTEST_LOG_(INFO) << "\n================================================\n";
672
673 stack = stackPrinter->GetTreeStack(gettid(), true);
674 ASSERT_NE(stack, "");
675 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
676 GTEST_LOG_(INFO) << "\n================================================\n";
677
678 stack = stackPrinter->GetTreeStack(gettid(), true, timestamps[2], timestamps[6]);
679 ASSERT_NE(stack, "");
680 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
681 GTEST_LOG_(INFO) << "StackPrinterTest_004: end.";
682 }
683
684 /**
685 * @tc.name: StackPrinterTest005
686 * @tc.desc: test StackPrinter functions
687 * @tc.type: FUNC
688 */
689 HWTEST_F(StackPrinterTest, StackPrinterTest_005, TestSize.Level2)
690 {
691 GTEST_LOG_(INFO) << "StackPrinterTest_005: start.";
692 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
693 uint32_t uniqueStableSize = 128 * 1024;
694 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
695 for (size_t i = 0; i < pcsVec.size(); i++) {
696 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
697 }
698
699 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
700 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
701 stackPrinter->SetUnwindInfo(unwinder, maps);
702 std::string stack = stackPrinter->GetHeaviestStack(gettid());
703 ASSERT_NE(stack, "");
704 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
705 GTEST_LOG_(INFO) << "\n================================================\n";
706
707 stack = stackPrinter->GetHeaviestStack(gettid(), timestamps[2], timestamps[6]);
708 ASSERT_NE(stack, "");
709 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
710 GTEST_LOG_(INFO) << "StackPrinterTest_005: end.";
711 }
712
713 /**
714 * @tc.name: StackPrinterTest006
715 * @tc.desc: test StackPrinter functions
716 * @tc.type: FUNC
717 */
718 HWTEST_F(StackPrinterTest, StackPrinterTest_006, TestSize.Level2)
719 {
720 GTEST_LOG_(INFO) << "StackPrinterTest_006: start.";
721 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
722 uint32_t uniqueStableSize = 128 * 1024;
723 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
724 for (size_t i = 0; i < pcsVec.size(); i++) {
725 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
726 }
727
728 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
729 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
730 stackPrinter->SetUnwindInfo(unwinder, maps);
731 std::map<int, std::vector<SampledFrame>> threadSampledFrames = stackPrinter->GetThreadSampledFrames();
732 ASSERT_FALSE(threadSampledFrames.empty());
733 std::vector<SampledFrame> frames = threadSampledFrames[getpid()];
734 ASSERT_FALSE(frames.empty());
735
736 const int indent = 2;
737 for (const auto& frame : frames) {
738 ASSERT_EQ(frame.indent, indent * frame.level);
739 }
740 GTEST_LOG_(INFO) << "StackPrinterTest_006: end.";
741 }
742
743 /**
744 * @tc.name: StackPrinterTest007
745 * @tc.desc: test StackPrinter functions
746 * @tc.type: FUNC
747 */
748 HWTEST_F(StackPrinterTest, StackPrinterTest_007, TestSize.Level2)
749 {
750 GTEST_LOG_(INFO) << "StackPrinterTest_007: start.";
751 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
752 uint32_t uniqueStableSize = 128 * 1024;
753 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
754 for (size_t i = 0; i < pcsVec.size(); i++) {
755 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
756 }
757
758 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
759 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
760 stackPrinter->SetUnwindInfo(unwinder, maps);
761 std::map<int, std::vector<SampledFrame>> threadSampledFrames = stackPrinter->GetThreadSampledFrames();
762 ASSERT_FALSE(threadSampledFrames.empty());
763
764 std::stringstream ss;
765 StackPrinter::SerializeSampledFrameMap(threadSampledFrames, ss);
766 GTEST_LOG_(INFO) << "serialized map: " << ss.str().c_str();
767
768 std::map<int, std::vector<SampledFrame>> deserializeMap = StackPrinter::DeserializeSampledFrameMap(ss);
769 ASSERT_EQ(threadSampledFrames.size(), deserializeMap.size());
770 auto it1 = threadSampledFrames.cbegin();
771 auto it2 = deserializeMap.cbegin();
772 while (it1 != threadSampledFrames.cend() && it2 != deserializeMap.cend()) {
773 ASSERT_EQ(it1->first, it2->first);
774 ASSERT_EQ(it1->second.size(), it2->second.size());
775 for (size_t i = 0; i < it1->second.size(); i++) {
776 ASSERT_EQ(it1->second[i].indent, it2->second[i].indent);
777 ASSERT_EQ(it1->second[i].count, it2->second[i].count);
778 ASSERT_EQ(it1->second[i].level, it2->second[i].level);
779 ASSERT_EQ(it1->second[i].pc, it2->second[i].pc);
780 ASSERT_EQ(it1->second[i].isLeaf, it2->second[i].isLeaf);
781 ASSERT_EQ(it1->second[i].timestamps, it2->second[i].timestamps);
782 }
783 it1++;
784 it2++;
785 }
786 GTEST_LOG_(INFO) << "StackPrinterTest_007: end.";
787 }
788
789 /**
790 * @tc.name: StackPrinterTest008
791 * @tc.desc: test StackPrinter functions
792 * @tc.type: FUNC
793 */
794 HWTEST_F(StackPrinterTest, StackPrinterTest_008, TestSize.Level2)
795 {
796 GTEST_LOG_(INFO) << "StackPrinterTest_008: start.";
797 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
798 uint32_t uniqueStableSize = 128 * 1024;
799 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
800 for (size_t i = 0; i < pcsVec.size(); i++) {
801 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
802 }
803
804 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
805 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
806 stackPrinter->SetUnwindInfo(unwinder, maps);
807 std::map<int, std::vector<SampledFrame>> threadSampledFrames = stackPrinter->GetThreadSampledFrames();
808 ASSERT_FALSE(threadSampledFrames.empty());
809
810 std::vector<SampledFrame> sampledFrameVec = threadSampledFrames[gettid()];
811 ASSERT_FALSE(sampledFrameVec.empty());
812
813 std::string stack = StackPrinter::PrintTreeStackBySampledStack(sampledFrameVec, true, unwinder, maps);
814 ASSERT_NE(stack, "");
815 GTEST_LOG_(INFO) << "stack:\n" << stack.c_str() << "\n";
816
817 GTEST_LOG_(INFO) << "StackPrinterTest_008: end.";
818 }
819
820 /**
821 * @tc.name: StackPrinterTest009
822 * @tc.desc: test StackPrinter functions
823 * @tc.type: FUNC
824 */
825 HWTEST_F(StackPrinterTest, StackPrinterTest_009, TestSize.Level2)
826 {
827 GTEST_LOG_(INFO) << "StackPrinterTest_009: start.";
828 std::unique_ptr<StackPrinter> stackPrinter = std::make_unique<StackPrinter>();
829 uint32_t uniqueStableSize = 128 * 1024;
830 stackPrinter->InitUniqueTable(getpid(), uniqueStableSize);
831 for (size_t i = 0; i < pcsVec.size(); i++) {
832 stackPrinter->PutPcsInTable(pcsVec[i], gettid(), timestamps[i]);
833 }
834
835 std::shared_ptr<Unwinder> unwinder = std::make_shared<Unwinder>(false);
836 std::shared_ptr<DfxMaps> maps = DfxMaps::Create(getpid(), MAPS_PATH);
837 stackPrinter->SetUnwindInfo(unwinder, maps);
838 std::map<int, std::vector<SampledFrame>> threadSampledFrames = stackPrinter->GetThreadSampledFrames();
839 ASSERT_FALSE(threadSampledFrames.empty());
840
841 std::vector<SampledFrame> sampledFrameVec = threadSampledFrames[gettid()];
842 ASSERT_FALSE(sampledFrameVec.empty());
843
844 for (const auto& originFrame : sampledFrameVec) {
845 std::stringstream ss;
846 ss << originFrame;
847 std::string frameStr = std::to_string(originFrame.indent) + " " + std::to_string(originFrame.count) + " " +
848 std::to_string(originFrame.level) + " " + std::to_string(originFrame.pc) + " " +
849 std::to_string(originFrame.isLeaf) + " " + std::to_string(originFrame.timestamps.size());
850 for (const auto& timestamp : originFrame.timestamps) {
851 frameStr = frameStr + " " + std::to_string(timestamp);
852 }
853 ASSERT_EQ(ss.str(), frameStr);
854
855 SampledFrame sampledFrame;
856 ss >> sampledFrame;
857
858 ASSERT_EQ(originFrame.indent, sampledFrame.indent);
859 ASSERT_EQ(originFrame.count, sampledFrame.count);
860 ASSERT_EQ(originFrame.level, sampledFrame.level);
861 ASSERT_EQ(originFrame.pc, sampledFrame.pc);
862 ASSERT_EQ(originFrame.isLeaf, sampledFrame.isLeaf);
863 ASSERT_EQ(originFrame.timestamps, sampledFrame.timestamps);
864 }
865
866 GTEST_LOG_(INFO) << "StackPrinterTest_009: end.";
867 }
868
869 /**
870 * @tc.name: StackPrinterTest010
871 * @tc.desc: test StackPrinter functions
872 * @tc.type: FUNC
873 */
874 HWTEST_F(StackPrinterTest, StackPrinterTest_010, TestSize.Level2)
875 {
876 GTEST_LOG_(INFO) << "StackPrinterTest_010: start.";
877 // SampledFrame string to be deserialized: mapSize + \n + tid + vecSize + frameinfo + \n
878 // frameinfo: indent + count + level + pc + isLeaf + timestamps.size() + timestamps(set empty)
879 std::string sampledFrameMapStr = "11\n" + std::to_string(gettid()) + " 1 1 5 3 9630076 0 0\n";
880 std::stringstream ss(sampledFrameMapStr);
881 auto result = StackPrinter::DeserializeSampledFrameMap(ss);
882 ASSERT_TRUE(ss.fail());
883 ASSERT_TRUE(result.empty());
884
885 ss.str("");
886 ss.clear();
887 ss.str("invalidMapSize");
888 result = StackPrinter::DeserializeSampledFrameMap(ss);
889 ASSERT_TRUE(ss.fail());
890 ASSERT_TRUE(result.empty());
891
892 ss.str("");
893 ss.clear();
894 sampledFrameMapStr = "1\n-1 1 1 5 3 9630076 0 0\n";
895 ss.str(sampledFrameMapStr);
896 result = StackPrinter::DeserializeSampledFrameMap(ss);
897 ASSERT_FALSE(ss.fail());
898 ASSERT_TRUE(result.empty());
899
900 ss.str("");
901 ss.clear();
902 ss.str("1\ninvalidTid");
903 result = StackPrinter::DeserializeSampledFrameMap(ss);
904 ASSERT_TRUE(ss.fail());
905 ASSERT_TRUE(result.empty());
906
907 ss.str("");
908 ss.clear();
909 ss.str("1\ninvalidTid 1");
910 result = StackPrinter::DeserializeSampledFrameMap(ss);
911 ASSERT_FALSE(ss.fail());
912 ASSERT_TRUE(result.empty());
913
914 ss.str("");
915 ss.clear();
916 sampledFrameMapStr = "1\n" + std::to_string(gettid()) + " 1 1 5 3 9630076 0 0\n";
917 ss.str(sampledFrameMapStr);
918 result = StackPrinter::DeserializeSampledFrameMap(ss);
919 ASSERT_FALSE(ss.fail());
920 ASSERT_EQ(result.size(), 1);
921 ASSERT_EQ(result[gettid()].size(), 1);
922
923 GTEST_LOG_(INFO) << "StackPrinterTest_010: end.";
924 }
925 } // namespace HiviewDFX
926 } // namespace OHOS